python-dmidecode-3.10.13/0000755002425500234200000000000011401711514014472 5ustar nimaautonomypython-dmidecode-3.10.13/.autoheader0000644002425500234200000000342011401675045016623 0ustar nimaautonomy © 2007-2010 Nima Talebi © 2009-2010 David Sommerseth © 2002-2008 Jean Delvare © 2000-2002 Alan Cox This file is part of @PKG@. @PKG@ 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. @PKG@ 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 @PKG@. 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::@SERIAL@ $ python-dmidecode-3.10.13/Makefile0000644002425500234200000000772211401675045016152 0ustar nimaautonomy#. ******* coding:utf-8 AUTOHEADER START v1.2 ******* #. vim: fileencoding=utf-8 syntax=Makefile sw=4 ts=4 et #. #. © 2007-2010 Nima Talebi #. © 2009-2010 David Sommerseth #. © 2002-2008 Jean Delvare #. © 2000-2002 Alan Cox #. #. This file is part of python-dmidecode. #. #. python-dmidecode 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-dmidecode 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-dmidecode. 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::20100225 $ #. ******* AUTOHEADER END v1.2 ******* VERSION := $(shell cd src;python -c "from setup_common import *; print get_version();") PACKAGE := python-dmidecode PY_VER := $(shell python -c 'import sys; print "%d.%d"%sys.version_info[0:2]') PY := python$(PY_VER) SO := build/lib.linux-$(shell uname -m)-$(PY_VER)/dmidecodemod.so SHELL := /bin/bash ############################################################################### .PHONY: build dmidump install uninstall clean tarball rpm unit version all : build dmidump build: $(PY)-dmidecodemod.so $(PY)-dmidecodemod.so: $(SO) cp $< $@ $(SO): $(PY) src/setup.py build dmidump : src/util.o src/efi.o src/dmilog.o $(CC) -o $@ src/dmidump.c $^ -g -Wall -D_DMIDUMP_MAIN_ install: $(PY) src/setup.py install uninstall: $(PY) src/setup.py uninstall clean: -$(PY) src/setup.py clean --all -rm -f *.so lib/*.o core dmidump src/*.o -rm -rf build -rm -rf rpm -rm -rf src/setup_common.py[oc] -rm -rf $(PACKAGE)-$(VERSION) $(PACKAGE)-$(VERSION).tar.gz $(MAKE) -C unit-tests clean tarball: rm -rf $(PACKAGE)-$(VERSION) mkdir $(PACKAGE)-$(VERSION) cp -r contrib doc examples Makefile man README src dmidecode.py unit-tests/ $(PACKAGE)-$(VERSION) tar -czvf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) rpm-prep: mkdir -p rpm/{BUILD,RPMS,SRPMS,SPECS,SOURCES} cp contrib/$(PACKAGE).spec rpm/SPECS cp $(PACKAGE)-$(VERSION).tar.gz rpm/SOURCES rpm: tarball rpm-prep rpmbuild -ba --define "_topdir $(shell pwd)/rpm" rpm/SPECS/$(PACKAGE).spec rpm-md5: tarball rpm-prep rpmbuild-md5 -ba --define "_topdir $(shell pwd)/rpm" rpm/SPECS/$(PACKAGE).spec unit: $(MAKE) -C unit-tests version: @echo "python-dmidecode: $(VERSION)" @echo "python version: $(PY_VER) ($(PY))" conflicts: @comm -12 \ <(dpkg-deb -c ../../DPKGS/python-dmidecode_$(VERSION)-1_amd64.deb | awk '$$NF!~/\/$$/{print$$NF}'|sort) \ <(dpkg-deb -c ../../DPKGS/python-dmidecode-dbg_$(VERSION)-1_amd64.deb | awk '$$NF!~/\/$$/{print$$NF}'|sort) python-dmidecode-3.10.13/README0000644002425500234200000000007711401675045015366 0ustar nimaautonomyPlease visit http://projects.autonomy.net.au/python-dmidecode/ python-dmidecode-3.10.13/contrib/0000755002425500234200000000000011401675045016142 5ustar nimaautonomypython-dmidecode-3.10.13/contrib/python-dmidecode.spec0000644002425500234200000000636611401676122022262 0ustar nimaautonomy%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} %{!?python_ver: %global python_ver %(%{__python} -c "import sys ; print sys.version[:3]")} Summary: Python module to access DMI data Name: python-dmidecode Version: 3.10.13 Release: 1%{?dist} License: GPLv2 Group: System Environment/Libraries URL: http://projects.autonomy.net.au/python-dmidecode/ Source0: http://src.autonomy.net.au/python-dmidecode/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root Requires: libxml2-python BuildRequires: libxml2-python BuildRequires: libxml2-devel BuildRequires: python-devel %description python-dmidecode is a python extension module that uses the code-base of the 'dmidecode' utility, and presents the data as python data structures or as XML data using libxml2. %prep %setup -q %build make build cd unit-tests make cd .. %install rm -rf $RPM_BUILD_ROOT python src/setup.py install --root $RPM_BUILD_ROOT --prefix=%{_prefix} %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc README doc/README.upstream doc/LICENSE doc/AUTHORS doc/AUTHORS.upstream %{python_sitearch}/dmidecodemod.so %{python_sitearch}/dmidecode.py %{python_sitearch}/dmidecode.py[co] %if "%{python_ver}" >= "2.5" %{python_sitearch}/*.egg-info %endif %{_datadir}/python-dmidecode/ %changelog * Thu Jun 03 2010 Nima Talebi - 3.10.13-1 - Update to new release * Fri Mar 12 2010 Nima Talebi - 3.10.12-1 - Update to new release * Tue Feb 16 2010 Nima Talebi - 3.10.11-1 - Update to new release * Tue Jan 12 2010 Nima Talebi - 3.10.10-1 - Update to new release * Thu Jan 07 2010 Nima Talebi - 3.10.9-1 - Update to new release * Thu Dec 15 2009 Nima Talebi - 3.10.8-1 - New Upstream release. - Big-endian and little-endian approved. - Packaged unit-test to tarball. - Rewritten unit-test to be able to run as non-root user, where it will not try to read /dev/mem. - Added two dmidump data files to the unit-test. * Thu Nov 26 2009 David Sommerseth - 3.10.7-3 - Fixed even more .spec file issues and removed explicit mentioning of /usr/share/python-dmidecode/pymap.xml * Wed Nov 25 2009 David Sommerseth - 3.10.7-2 - Fixed some .spec file issues (proper Requires, use _datadir macro) * Wed Sep 23 2009 Nima Talebi - 3.10.7-1 - Updated source0 to new 3.10.7 tar ball * Wed Jul 13 2009 David Sommerseth - 3.10.6-6 - Only build the python-dmidecode module, not everything * Wed Jul 13 2009 David Sommerseth - 3.10.6-5 - Added missing BuildRequres for libxml2-python * Wed Jul 13 2009 David Sommerseth - 3.10.6-4 - Added missing BuildRequres for python-devel * Wed Jul 13 2009 David Sommerseth - 3.10.6-3 - Added missing BuildRequres for libxml2-devel * Wed Jul 13 2009 David Sommerseth - 3.10.6-2 - Updated release, to avoid build conflict * Wed Jun 10 2009 David Sommerseth - 3.10.6-1 - Updated to work with the new XML based python-dmidecode * Sat Mar 7 2009 Clark Williams - 2.10.3-1 - Initial build. python-dmidecode-3.10.13/dmidecode.py0000644002425500234200000000660511401675045017000 0ustar nimaautonomy# # dmidecode.py # Module front-end for the python-dmidecode module. # # 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 libxml2 from dmidecodemod import * 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 = xmlapi(query_type='s', result_type=self.restype, section=sectname) ) elif self.restype == DMIXML_DOC: ret = libxml2.xmlDoc( _obj = 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 = xmlapi(query_type='t', result_type=self.restype, typeid=tpid)) elif self.restype == DMIXML_DOC: ret = libxml2.xmlDoc( _obj = xmlapi(query_type='t', result_type=self.restype, typeid=tpid)) else: raise TypeError, "Invalid result type value" return ret python-dmidecode-3.10.13/doc/0000755002425500234200000000000011401675045015247 5ustar nimaautonomypython-dmidecode-3.10.13/doc/AUTHORS0000644002425500234200000000130511401675045016316 0ustar nimaautonomyDEVELOPER AND MAINTAINER OF PYTHON MODULE (http://projects.autonomy.net.au/python-dmidecode) Nima Talebi David Sommerseth DEVELOPER AND MAINTAINER OF DMIDECODE (Please see http://www.nongnu.org/dmidecode) Jean Delvare ORIGINAL AUTHOR Alan Cox MANY THANKS TO (IN REVERSE CHRONOLOGICAL ORDER) Richard Fontana Daniel Veillard David Sommerseth Clark Williams Christoph Haas Jean Delvare Vaughan Whitteron Joel Heenan Stephen Darragh Justin Cook python-dmidecode-3.10.13/doc/AUTHORS.upstream0000644002425500234200000000237311401675045020163 0ustar nimaautonomyDEVELOPER AND MAINTAINER Jean Delvare ORIGINAL AUTHOR Alan Cox CODE CONTRIBUTORS (IN CHRONOLOGICAL ORDER) Matt Domsch Arjan van de Ven Mark D. Studebaker Larry Lile Dave Johnson Petter Reinholdtsen Roberto Nibali John Cagle Jens Elkner MANY THANKS TO (IN CHRONOLOGICAL ORDER) Werner Heuser Alexandre Duret-Lutz Xavier Roche Pamela Huntley Gael Stephan Sebastian Henschel Richard Sharpe David Wilson Glen Foster Chad Smith Joshua Goldenhar Luc Van de Velde Mario Lang Hugues Lepesant Sergey Leonovich Mike Cooper Marc Rieffel Jeff Moyer Josef Moellers Zing Zing Shishak Rafael Avila de Espindola Roger Koot Martin Pool Doug Brenner Alex Williamson Durval Menezes Raphael Raimbault Raul Nunez de Arenas Coronado Francois Revol Dominik Klein Erwan Velu Don Howard Frans Pop Tomek Mateja Myke Olson Torsten Seemann Garry Belka Klaus Muth Antoine Fuselier Matthew Garrett Landry Breuil Luke Suchocki Attila Nagy Alex Iribarren Sebastien Douche William Lallemand Olivier Guerrier Pascal Terjan Stuart Hayes Sofian Brabez Vincent Pelletier Andreas Gruenbacher python-dmidecode-3.10.13/doc/LICENSE0000644002425500234200000004310311401675045016255 0ustar nimaautonomy GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. python-dmidecode-3.10.13/doc/README.types0000644002425500234200000000312311401675045017271 0ustar nimaautonomy Type Information ---------------------------------------- 0 BIOS 1 System 2 Base Board 3 Chassis 4 Processor 5 Memory Controller 6 Memory Module 7 Cache 8 Port Connector 9 System Slots 10 On Board Devices 11 OEM Strings 12 System Configuration Options 13 BIOS Language 14 Group Associations 15 System Event Log 16 Physical Memory Array 17 Memory Device 18 32-bit Memory Error 19 Memory Array Mapped Address 20 Memory Device Mapped Address 21 Built-in Pointing Device 22 Portable Battery 23 System Reset 24 Hardware Security 25 System Power Controls 26 Voltage Probe 27 Cooling Device 28 Temperature Probe 29 Electrical Current Probe 30 Out-of-band Remote Access 31 Boot Integrity Services 32 System Boot 33 64-bit Memory Error 34 Management Device 35 Management Device Component 36 Management Device Threshold Data 37 Memory Channel 38 IPMI Device 39 Power Supply Keyword Types ------------------------------ bios 0, 13 system 1, 12, 15, 23, 32 baseboard 2, 10 chassis 3 processor 4 memory 5, 6, 16, 17 cache 7 connector 8 slot 9 python-dmidecode-3.10.13/doc/README.upstream0000644002425500234200000001114111401675045017764 0ustar nimaautonomy** INTRODUCTION ** Dmidecode reports information about your system's hardware as described in your system BIOS according to the SMBIOS/DMI standard. This information typically includes system manufacturer, model name, serial number, BIOS version, asset tag as well as a lot of other details of varying level of interest and reliability depending on the manufacturer. This will often include usage status for the CPU sockets, expansion slots (e.g. AGP, PCI, ISA) and memory module slots, and the list of I/O ports (e.g. serial, parallel, USB). DMI data can be used to enable or disable specific portions of kernel code depending on the specific hardware. Thus, one use of dmidecode is for kernel developers to detect system "signatures" and add them to the kernel source code when needed. Beware that DMI data have proven to be too unreliable to be blindly trusted. Dmidecode does not scan your hardware, it only reports what the BIOS told it to. ** INSTALLATION ** The home web page for dmidecode is hosted on Savannah: http://www.nongnu.org/dmidecode/ You will find the latest version (including CVS) there, as well as fresh news and other interesting material, such as a list of related projects and articles. This program was first written for Linux, and has since been reported to work on FreeBSD, NetBSD, OpenBSD, BeOS, Cygwin and Solaris as well. There's no configure script, so simply run "make" to build dmidecode, and "make install" to install it. You also can use "make uninstall" to remove all the files you installed. By default, files are installed in /usr/local but you can change this behavior by editing the Makefile file and setting prefix to wherever you want. You may change the C compiler and the compilation flags as well. Optionally, you can run "make strip" prior to "make install" if you want smaller binaries. However, be aware that this will prevent any further attempt to debug the programs. Two parameters can be set in the Makefile file to make dmidecode work on non-i386 systems. They should be used if your system uses the big endian byte ordering (Motorola) or doesn't support unaligned memory accesses, respectively. For example, compiling for a SPARC processor would require both (but I am not aware of SPARC-based systems implementing SMBIOS). Compiling for an IA64 processor requires the memory alignment workaround, and it is enabled automatically. ** DOCUMENTATION ** Each tool has a manual page, found in the "man" subdirectory. Manual pages are installed by "make install". See these manual pages for command line interface details and tool specific information. For an history of the changes made to dmidecode, see the CHANGELOG file. If you need help, your best chances are to visit the web page (see the INSTALLATION section above) or to get in touch with the developers directly. Have a look at the AUTHORS file and contact one of the maintainers. If you want to help with the development of dmidecode, please consider joining the dmidecode-devel discussion list: http://lists.nongnu.org/mailman/listinfo/dmidecode-devel ** COMMON PROBLEMS ** IA-64 Non-Linux systems are not yet supported. MMAP Note that mmap() is now used by default wherever possible, since this seems to solve a number of problems. This default behavior can be changed in config.h. Just to make sure this is clear, mmap() is not used for performance reasons but to increase the number of systems on which dmidecode can be successfully run. CYGWIN Dmidecode was reported to work under Cygwin. It seems that /dev/mem doesn't work properly before version 1.5.10 though, so you will need to use at least this version. ** MISCELLANEOUS TOOLS ** Three other tools come along with dmidecode: biosdecode, ownership and vpddecode. These tools are only useful on systems with a BIOS, so they are not built on IA-64 by default. BIOSDECODE This one prints all BIOS related information it can find in /dev/mem. It used to be part of dmidecode itself, but as dmidecode was growing, we felt that the non-DMI part had to be moved to a separate tool. OWNERSHIP This tool was written on a request by Luc Van de Velde for use with Novell tools in his company. It retrieves the "ownership tag" that can be set on most Compaq computers. Since it uses the same mechanisms dmidecode and biosdecode use, and could be of some use for other people as well, we decided to make it part of the project. VPDDECODE This tool prints the contents of the "vital product data" structure as found in most IBM and Lenovo computers. It used to have a lookup table for the machine name, but it was unreliable and hard to maintain so it was ultimately dropped. It has a command line interface. python-dmidecode-3.10.13/doc/changelog0000644002425500234200000011045211401675045017124 0ustar nimaautonomy------------------------------------------------------------------------ r177 | nima | 2009-03-09 00:49:21 +1100 (Mon, 09 Mar 2009) | 2 lines Releasing v2.10.4. ------------------------------------------------------------------------ r176 | nima | 2009-03-08 22:32:42 +1100 (Sun, 08 Mar 2009) | 2 lines Adding spec file supplied by Clark Williams . ------------------------------------------------------------------------ r175 | nima | 2009-03-08 22:31:31 +1100 (Sun, 08 Mar 2009) | 3 lines Applied patch submitted by Clark Williams . ------------------------------------------------------------------------ r174 | nima | 2009-02-23 00:34:24 +1100 (Mon, 23 Feb 2009) | 2 lines Fixed bug reported by Ralf Treinen. ------------------------------------------------------------------------ r173 | nima | 2009-02-14 01:39:23 +1100 (Sat, 14 Feb 2009) | 2 lines Removing spec file from upstream. ------------------------------------------------------------------------ r172 | nima | 2009-02-14 01:36:16 +1100 (Sat, 14 Feb 2009) | 2 lines Upped sub-version. ------------------------------------------------------------------------ r171 | nima | 2009-02-14 01:32:06 +1100 (Sat, 14 Feb 2009) | 2 lines Small changes - final touches for 2.10.1. ------------------------------------------------------------------------ r170 | nima | 2009-02-14 01:30:37 +1100 (Sat, 14 Feb 2009) | 3 lines Versioning now chagned to reflect the version of the upstream (dmidecode) version with which python-dmidecode is in sync with. ------------------------------------------------------------------------ r169 | nima | 2009-01-13 23:48:28 +1100 (Tue, 13 Jan 2009) | 2 lines Fixed watch file. ------------------------------------------------------------------------ r168 | nima | 2009-01-13 00:06:34 +1100 (Tue, 13 Jan 2009) | 2 lines Debian changes completely separated from upstream. ------------------------------------------------------------------------ r167 | nima | 2009-01-13 00:04:52 +1100 (Tue, 13 Jan 2009) | 2 lines Removed Debian-specific targets from the makefile. ------------------------------------------------------------------------ r166 | nima | 2008-12-23 10:02:00 +1100 (Tue, 23 Dec 2008) | 2 lines Source file name change. ------------------------------------------------------------------------ r165 | nima | 2008-12-23 10:01:22 +1100 (Tue, 23 Dec 2008) | 2 lines A more complete dmidecode example. ------------------------------------------------------------------------ r164 | nima | 2008-12-23 09:40:51 +1100 (Tue, 23 Dec 2008) | 2 lines Applied the nice changes suggested by Piotr Ożarowsk. ------------------------------------------------------------------------ r163 | nima | 2008-12-23 00:37:43 +1100 (Tue, 23 Dec 2008) | 6 lines Cleaned up the fix for type(127). Added the second type of stuffed bios (upstream). Integrated dmidecode the binary into the test case for a more objective result. ------------------------------------------------------------------------ r162 | nima | 2008-12-22 20:06:43 +1100 (Mon, 22 Dec 2008) | 2 lines Fixed the type(127) problem (at least on this machine) - again. ------------------------------------------------------------------------ r161 | nima | 2008-12-21 23:52:51 +1100 (Sun, 21 Dec 2008) | 4 lines Removed unnecessay manpage. Spell my own name correctly. ------------------------------------------------------------------------ r160 | nima | 2008-12-21 22:31:36 +1100 (Sun, 21 Dec 2008) | 2 lines Added an upload into src.autonomy.net.au after source build. ------------------------------------------------------------------------ r159 | nima | 2008-12-21 22:27:52 +1100 (Sun, 21 Dec 2008) | 2 lines Fixed sample. ------------------------------------------------------------------------ r158 | nima | 2008-12-21 21:22:06 +1100 (Sun, 21 Dec 2008) | 6 lines Cleanup copyright. Cleanup debian/rules. Adding test.py to examples. ------------------------------------------------------------------------ r157 | nima | 2008-12-21 21:04:03 +1100 (Sun, 21 Dec 2008) | 2 lines Remove README.Debian - no point. ------------------------------------------------------------------------ r156 | nima | 2008-12-21 18:57:49 +1100 (Sun, 21 Dec 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r155 | nima | 2008-12-21 18:53:54 +1100 (Sun, 21 Dec 2008) | 3 lines Handle cases where user does not have appropriate permission to access the memory file or device. ------------------------------------------------------------------------ r154 | nima | 2008-12-21 16:44:04 +1100 (Sun, 21 Dec 2008) | 2 lines Names. ------------------------------------------------------------------------ r153 | nima | 2008-12-21 16:43:06 +1100 (Sun, 21 Dec 2008) | 2 lines Better naming. ------------------------------------------------------------------------ r152 | nima | 2008-12-21 15:41:39 +1100 (Sun, 21 Dec 2008) | 4 lines Upped debhelper build-required version from 5 to 7. Final cleanups. ------------------------------------------------------------------------ r151 | nima | 2008-12-21 13:55:19 +1100 (Sun, 21 Dec 2008) | 2 lines Cleaned up and Lintian-approved. ------------------------------------------------------------------------ r150 | nima | 2008-12-21 13:48:05 +1100 (Sun, 21 Dec 2008) | 2 lines Email address fixed. ------------------------------------------------------------------------ r149 | nima | 2008-12-21 13:39:16 +1100 (Sun, 21 Dec 2008) | 2 lines Sigh. ------------------------------------------------------------------------ r148 | nima | 2008-12-21 13:38:35 +1100 (Sun, 21 Dec 2008) | 2 lines Changing to svn-buildpackage. ------------------------------------------------------------------------ r147 | nima | 2008-12-21 13:22:20 +1100 (Sun, 21 Dec 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r146 | nima | 2008-12-21 13:07:56 +1100 (Sun, 21 Dec 2008) | 2 lines Source generation. ------------------------------------------------------------------------ r145 | nima | 2008-12-21 12:41:57 +1100 (Sun, 21 Dec 2008) | 6 lines Fixed watchfile now that I've created a src (orig.tar.gz) repository. Added more copyright/lisencing information. More debianizing. ------------------------------------------------------------------------ r144 | nima | 2008-12-21 04:00:56 +1100 (Sun, 21 Dec 2008) | 2 lines Required for dh_installdocs. ------------------------------------------------------------------------ r143 | nima | 2008-12-21 03:54:32 +1100 (Sun, 21 Dec 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r142 | nima | 2008-12-21 03:52:15 +1100 (Sun, 21 Dec 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r141 | nima | 2008-12-21 03:49:40 +1100 (Sun, 21 Dec 2008) | 2 lines Removed out-of-place README. ------------------------------------------------------------------------ r140 | nima | 2008-12-21 03:47:18 +1100 (Sun, 21 Dec 2008) | 2 lines Hide private data from subversion. ------------------------------------------------------------------------ r139 | nima | 2008-12-21 03:46:37 +1100 (Sun, 21 Dec 2008) | 2 lines Remove private memory dumps. ------------------------------------------------------------------------ r138 | nima | 2008-12-21 03:45:39 +1100 (Sun, 21 Dec 2008) | 4 lines Added missing info to copyright file. Source creation target. ------------------------------------------------------------------------ r137 | nima | 2008-12-21 03:26:43 +1100 (Sun, 21 Dec 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r136 | nima | 2008-12-21 02:49:18 +1100 (Sun, 21 Dec 2008) | 4 lines Handle cases where user asks for invalid types. Updated test cases to test for this too. ------------------------------------------------------------------------ r135 | nima | 2008-12-21 02:32:30 +1100 (Sun, 21 Dec 2008) | 6 lines Version information now set once during init(). Bettered test cases. Case 127 magically fixed. ------------------------------------------------------------------------ r134 | nima | 2008-12-20 12:46:42 +1100 (Sat, 20 Dec 2008) | 2 lines Debian specific target. ------------------------------------------------------------------------ r133 | nima | 2008-12-20 12:44:55 +1100 (Sat, 20 Dec 2008) | 8 lines Removed "detected" from appearing in every single function call. TODO: An ivar should be implemented to return this string, so further cleanup is still required; as it stands, there is no access to this information anymore! Updated test case. Further general cleanup. ------------------------------------------------------------------------ r132 | nima | 2008-12-20 10:55:53 +1100 (Sat, 20 Dec 2008) | 4 lines Further testing shows that the segfault does not occur when the device is /dev/mem, but does so for all images (where requested type is 127), suggesting that the problem could be with the image or surrounding processes. ------------------------------------------------------------------------ r131 | nima | 2008-12-20 10:46:46 +1100 (Sat, 20 Dec 2008) | 2 lines Oops - fixed. ------------------------------------------------------------------------ r130 | nima | 2008-12-20 10:45:55 +1100 (Sat, 20 Dec 2008) | 3 lines Test case is close to complete, type 127 results in a segfault - (test case is serving its purpose). ------------------------------------------------------------------------ r129 | nima | 2008-12-20 10:29:50 +1100 (Sat, 20 Dec 2008) | 3 lines Adding an image from parallel's desktop running Debian lenny, and another for a physical server also running Debian. Both are intel 32 bit. ------------------------------------------------------------------------ r128 | nima | 2008-12-20 10:27:10 +1100 (Sat, 20 Dec 2008) | 4 lines More work on test case. Updated setup.py to reflect new version. ------------------------------------------------------------------------ r127 | nima | 2008-12-20 00:49:19 +1100 (Sat, 20 Dec 2008) | 2 lines More testing and fixes. ------------------------------------------------------------------------ r126 | nima | 2008-12-20 00:42:10 +1100 (Sat, 20 Dec 2008) | 2 lines Improved test case. ------------------------------------------------------------------------ r125 | nima | 2008-12-20 00:32:35 +1100 (Sat, 20 Dec 2008) | 2 lines Removed a printf() comment. ------------------------------------------------------------------------ r124 | nima | 2008-12-20 00:21:24 +1100 (Sat, 20 Dec 2008) | 6 lines Check that the path given with set_dev() is writeable. Don't crash when writing to a read-only file, return False instead. Missing an INCREF in get_dev() fixed. ------------------------------------------------------------------------ r123 | nima | 2008-12-19 22:56:39 +1100 (Fri, 19 Dec 2008) | 2 lines Test for write permission prior to write attempts. ------------------------------------------------------------------------ r122 | nima | 2008-12-19 20:02:52 +1100 (Fri, 19 Dec 2008) | 2 lines Fixed watch file. ------------------------------------------------------------------------ r121 | nima | 2008-12-19 16:05:38 +1100 (Fri, 19 Dec 2008) | 4 lines Received ITP auto-ack: #509169. More debianizing cleanup. ------------------------------------------------------------------------ r120 | nima | 2008-12-19 15:13:24 +1100 (Fri, 19 Dec 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r119 | nima | 2008-12-19 15:07:06 +1100 (Fri, 19 Dec 2008) | 3 lines Further work in enforcing the Debian policy in package based on advice from `POX' and the documentation. ------------------------------------------------------------------------ r118 | nima | 2008-12-19 13:23:32 +1100 (Fri, 19 Dec 2008) | 2 lines Removed junk and doing more debianizing - WIP. ------------------------------------------------------------------------ r117 | nima | 2008-12-19 00:49:57 +1100 (Fri, 19 Dec 2008) | 2 lines Updated. ------------------------------------------------------------------------ r116 | nima | 2008-12-19 00:48:52 +1100 (Fri, 19 Dec 2008) | 6 lines The dmidecode.type() call not takes ints, not strings. Adding an example directory. Adding test case. ------------------------------------------------------------------------ r115 | nima | 2008-12-19 00:45:37 +1100 (Fri, 19 Dec 2008) | 4 lines The dmidecode.type() call not takes ints, not strings. Adding an example directory. ------------------------------------------------------------------------ r114 | nima | 2008-12-18 12:12:50 +1100 (Thu, 18 Dec 2008) | 5 lines More upstream changes implemented, see CHANGELOG by Jean Delvare from the period 2008-02-16 to 2008-11-23. These changes have been made, but not yet fully tested. ------------------------------------------------------------------------ r113 | nima | 2008-12-18 00:26:57 +1100 (Thu, 18 Dec 2008) | 5 lines Claim to support revision 32 of Intel AP-485 (CPUID). No relevant change since revision 31. Update reference to AMD CPUID document. ------------------------------------------------------------------------ r112 | nima | 2008-12-18 00:11:35 +1100 (Thu, 18 Dec 2008) | 2 lines Handle chassis information records of size 19 (DMI type 3). ------------------------------------------------------------------------ r111 | nima | 2008-12-18 00:00:12 +1100 (Thu, 18 Dec 2008) | 2 lines And the debian subfolder itself... ------------------------------------------------------------------------ r110 | nima | 2008-12-17 23:59:32 +1100 (Wed, 17 Dec 2008) | 2 lines Debianizing dmidecode. ------------------------------------------------------------------------ r109 | nima | 2008-12-17 18:30:04 +1100 (Wed, 17 Dec 2008) | 2 lines Adding spec file written by Joel Heenan. ------------------------------------------------------------------------ r108 | nima | 2008-12-17 18:20:56 +1100 (Wed, 17 Dec 2008) | 2 lines Cleaning up source area, ready for debianizing, and rpm after that. ------------------------------------------------------------------------ r107 | nima | 2008-11-01 01:45:34 +1100 (Sat, 01 Nov 2008) | 2 lines Changed default target of Makefile back to `setup.py' method of installation. ------------------------------------------------------------------------ r106 | nima | 2008-11-01 01:41:02 +1100 (Sat, 01 Nov 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r105 | nima | 2008-11-01 01:33:03 +1100 (Sat, 01 Nov 2008) | 3 lines This commit closes #2 reported by Justin Cook, the ticket will remain open until Justin confirms this however. ------------------------------------------------------------------------ r104 | nima | 2008-11-01 01:07:22 +1100 (Sat, 01 Nov 2008) | 6 lines Implemented reading a dump to - this concludes syncing to the upstream release. Next, exceptions should be thrown in certain places, more error checking in the python side of things, and also in relation to setting and unsetting of the alternate memory file. ------------------------------------------------------------------------ r103 | nima | 2008-11-01 00:42:35 +1100 (Sat, 01 Nov 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r102 | nima | 2008-11-01 00:38:24 +1100 (Sat, 01 Nov 2008) | 3 lines Fixed dump. The `offset' problem was not really an offset problem - it was a silly typo. ------------------------------------------------------------------------ r101 | nima | 2008-11-01 00:24:04 +1100 (Sat, 01 Nov 2008) | 2 lines Missed two lines. ------------------------------------------------------------------------ r100 | nima | 2008-11-01 00:19:50 +1100 (Sat, 01 Nov 2008) | 3 lines Dump-to-file is almost working, there seems to be a 4-byte misalignment in the produced file though for now - needs to be fixed. ------------------------------------------------------------------------ r99 | nima | 2008-10-31 22:43:15 +1100 (Fri, 31 Oct 2008) | 2 lines Removed junk comments. ------------------------------------------------------------------------ r98 | nima | 2008-10-31 22:21:24 +1100 (Fri, 31 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r97 | nima | 2008-10-31 22:15:19 +1100 (Fri, 31 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r96 | nima | 2008-10-31 21:24:41 +1100 (Fri, 31 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r95 | nima | 2008-10-31 20:05:23 +1100 (Fri, 31 Oct 2008) | 6 lines Integration of required `dmiopt.h' bits. Removed QUIETness code. Other cleanups. Added get/set methods for changinf the default /dev/mem device. ------------------------------------------------------------------------ r94 | nima | 2008-10-31 20:02:21 +1100 (Fri, 31 Oct 2008) | 2 lines Removed traces of `_' and integrating required bits from dmiopt.h. ------------------------------------------------------------------------ r93 | nima | 2008-10-31 20:01:41 +1100 (Fri, 31 Oct 2008) | 2 lines Removed traces of `_'. ------------------------------------------------------------------------ r92 | nima | 2008-10-31 20:00:26 +1100 (Fri, 31 Oct 2008) | 2 lines Integrating the required bits from dmiopt into dmihelper. ------------------------------------------------------------------------ r91 | nima | 2008-10-31 19:39:12 +1100 (Fri, 31 Oct 2008) | 4 lines Removed `_' buffer. Removed use of `FLAGS_QUIET' as it makes no sense for a module. Removed the `submain()' function. ------------------------------------------------------------------------ r90 | nima | 2008-10-31 19:30:00 +1100 (Fri, 31 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r89 | nima | 2008-10-31 19:29:06 +1100 (Fri, 31 Oct 2008) | 2 lines Removed dependency on dmiopt. ------------------------------------------------------------------------ r88 | nima | 2008-10-31 19:28:33 +1100 (Fri, 31 Oct 2008) | 2 lines Removed verbose printout. ------------------------------------------------------------------------ r87 | nima | 2008-10-30 21:14:24 +1100 (Thu, 30 Oct 2008) | 2 lines Removed final traces of the `_' buffer. ------------------------------------------------------------------------ r86 | nima | 2008-10-30 13:11:56 +1100 (Thu, 30 Oct 2008) | 2 lines Implementing (incomplete) upstream changes. ------------------------------------------------------------------------ r85 | nima | 2008-10-29 18:15:35 +1100 (Wed, 29 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r84 | nima | 2008-10-29 18:13:49 +1100 (Wed, 29 Oct 2008) | 5 lines Adding man pages from upstream. Sooner or later, these will be removed, as will all other work that's simply replicating the demidecode binary. All this package should provide is the python module, and some py-module-specific man pages. ------------------------------------------------------------------------ r83 | nima | 2008-10-29 18:10:24 +1100 (Wed, 29 Oct 2008) | 4 lines Recoded the new work from upstream into these (main) files. The options to dump the memory image onto file, and read back from it has not yet been worked in, but the underlying work has been completed. ------------------------------------------------------------------------ r82 | nima | 2008-10-29 18:09:10 +1100 (Wed, 29 Oct 2008) | 3 lines Tested new dmidecode python module with this example file. A real test case will be implemented sometime in future. ------------------------------------------------------------------------ r81 | nima | 2008-10-29 18:07:56 +1100 (Wed, 29 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r80 | nima | 2008-10-29 18:07:13 +1100 (Wed, 29 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r79 | nima | 2008-10-29 18:06:47 +1100 (Wed, 29 Oct 2008) | 2 lines Using dmihelper now. ------------------------------------------------------------------------ r78 | nima | 2008-10-29 18:05:58 +1100 (Wed, 29 Oct 2008) | 2 lines Upstream. ------------------------------------------------------------------------ r77 | nima | 2008-10-29 18:04:19 +1100 (Wed, 29 Oct 2008) | 2 lines Upstream. ------------------------------------------------------------------------ r76 | nima | 2008-10-29 18:04:03 +1100 (Wed, 29 Oct 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r75 | nima | 2008-10-29 17:36:23 +1100 (Wed, 29 Oct 2008) | 2 lines Renamed to a more appropriate name. ------------------------------------------------------------------------ r74 | nima | 2008-10-29 17:35:21 +1100 (Wed, 29 Oct 2008) | 3 lines Committing new dmidecode helper functions, and next, renaming it to a meaningful name. ------------------------------------------------------------------------ r73 | nima | 2008-10-29 17:27:31 +1100 (Wed, 29 Oct 2008) | 3 lines Synced to the latest from upstream, with a light modification required for the module. ------------------------------------------------------------------------ r72 | nima | 2008-10-18 20:34:09 +1100 (Sat, 18 Oct 2008) | 5 lines Python does not have unsigned integers, hence %u and %lu in printf style strings are taken to be literal strings, not space-holders. All occurences of '%u' (78) have been amended to '%i', there was no '%lu'. ------------------------------------------------------------------------ r71 | nima | 2008-10-18 20:28:46 +1100 (Sat, 18 Oct 2008) | 4 lines Fixed bug reported by by Justin Cook, where dmidecode.type() would segfault. It turned out to be some code that was forgotten about during the conversion, or at least very incomplete and wrong. ------------------------------------------------------------------------ r70 | nima | 2008-10-17 02:52:48 +1100 (Fri, 17 Oct 2008) | 2 lines Remove efence. ------------------------------------------------------------------------ r69 | nima | 2008-09-05 13:08:02 +1000 (Fri, 05 Sep 2008) | 2 lines Fixed a bug that crashed dmidecode.slot(). ------------------------------------------------------------------------ r68 | nima | 2008-09-04 16:09:55 +1000 (Thu, 04 Sep 2008) | 5 lines Cleaning up of the dmidecode module, mostly conversion of things that can be Python `None's or `Int's but were `String'. Replaced a meaningless int dictionary key to `data'. ------------------------------------------------------------------------ r67 | nima | 2008-09-04 12:26:09 +1000 (Thu, 04 Sep 2008) | 3 lines Work on CPU details - seemed to been a bug with appending to a string rather than rewriting it. ------------------------------------------------------------------------ r66 | nima | 2008-08-09 00:15:47 +1000 (Sat, 09 Aug 2008) | 4 lines Replaced `%X' with `%x'. Logic cleanup - Put the `Handle' info back into the dictionary. ------------------------------------------------------------------------ r65 | nima | 2008-08-08 17:57:44 +1000 (Fri, 08 Aug 2008) | 2 lines Anoher bug fix, this time in baseboard. ------------------------------------------------------------------------ r64 | nima | 2008-08-08 17:27:36 +1000 (Fri, 08 Aug 2008) | 3 lines Fixed many major bugs (all of which were expected based on the way we mass converted all the `case' blocks. ------------------------------------------------------------------------ r63 | nima | 2008-08-07 22:32:39 +1000 (Thu, 07 Aug 2008) | 2 lines Cleaned up a little. ------------------------------------------------------------------------ r62 | nima | 2008-08-07 11:34:15 +1000 (Thu, 07 Aug 2008) | 2 lines Fixed some conversion bits missed during last night. ------------------------------------------------------------------------ r61 | nima | 2008-08-06 23:32:37 +1000 (Wed, 06 Aug 2008) | 2 lines Updated authors file with developers of the dmidecode python module. ------------------------------------------------------------------------ r60 | nima | 2008-08-06 23:27:26 +1000 (Wed, 06 Aug 2008) | 2 lines Changed to GNU GPL v3 License. ------------------------------------------------------------------------ r59 | nima | 2008-08-06 22:59:03 +1000 (Wed, 06 Aug 2008) | 2 lines Removed `sudo'. ------------------------------------------------------------------------ r58 | nima | 2008-08-06 22:52:46 +1000 (Wed, 06 Aug 2008) | 4 lines Completed `case 126', thought to have been completed in previous commit. Some housekeeping elsewhere. ------------------------------------------------------------------------ r57 | nima | 2008-08-06 18:51:05 +1000 (Wed, 06 Aug 2008) | 4 lines Completed all conversions! Only problem now is of course finding all the memory leaks and introduced logic errors which (confirmed) do exists - use valgrind and see. ------------------------------------------------------------------------ r56 | vwhitteron | 2008-08-06 18:29:18 +1000 (Wed, 06 Aug 2008) | 1 line Completed `Case 34' through `Case 39' ------------------------------------------------------------------------ r55 | nima | 2008-08-06 18:12:43 +1000 (Wed, 06 Aug 2008) | 2 lines Almost there! ------------------------------------------------------------------------ r54 | vwhitteron | 2008-08-06 17:49:23 +1000 (Wed, 06 Aug 2008) | 1 line Completed `Case 29' and `Case 32' ------------------------------------------------------------------------ r53 | nima | 2008-08-06 17:42:34 +1000 (Wed, 06 Aug 2008) | 2 lines Converted `case 30'. ------------------------------------------------------------------------ r52 | vwhitteron | 2008-08-06 17:40:42 +1000 (Wed, 06 Aug 2008) | 1 line Completed `Case 26', `Case 27' and `Case 28' ------------------------------------------------------------------------ r51 | nima | 2008-08-06 17:30:41 +1000 (Wed, 06 Aug 2008) | 3 lines Added `PyObject *data;' to all remaining functions which will generate a warning as to indicate these need to be converted. ------------------------------------------------------------------------ r50 | nima | 2008-08-06 17:27:30 +1000 (Wed, 06 Aug 2008) | 2 lines Completed functions for `csae 28'. ------------------------------------------------------------------------ r49 | nima | 2008-08-06 17:23:35 +1000 (Wed, 06 Aug 2008) | 2 lines Completed functions for `case 27', and fixed error in last commit for `case 26'. ------------------------------------------------------------------------ r48 | nima | 2008-08-06 17:19:27 +1000 (Wed, 06 Aug 2008) | 2 lines Completed functions for `case 26'. ------------------------------------------------------------------------ r47 | vwhitteron | 2008-08-06 17:09:11 +1000 (Wed, 06 Aug 2008) | 1 line Completed `Case 23', `Case 24', `Case24' and `Case 25' ------------------------------------------------------------------------ r46 | nima | 2008-08-06 17:07:20 +1000 (Wed, 06 Aug 2008) | 2 lines Completed functions for `case 25'. ------------------------------------------------------------------------ r45 | nima | 2008-08-06 17:00:41 +1000 (Wed, 06 Aug 2008) | 2 lines Converted function for `case 24'. ------------------------------------------------------------------------ r44 | nima | 2008-08-06 16:59:35 +1000 (Wed, 06 Aug 2008) | 2 lines More fixes on recent commits (by me), and more conversions on functions. ------------------------------------------------------------------------ r43 | vwhitteron | 2008-08-06 16:57:13 +1000 (Wed, 06 Aug 2008) | 1 line Completed `Case 22' ------------------------------------------------------------------------ r42 | nima | 2008-08-06 16:53:24 +1000 (Wed, 06 Aug 2008) | 2 lines Oops. Fixed stupidity on last commit. ------------------------------------------------------------------------ r41 | nima | 2008-08-06 16:52:01 +1000 (Wed, 06 Aug 2008) | 2 lines Completed functions called by `case 21' and `case 22'. ------------------------------------------------------------------------ r40 | nima | 2008-08-06 16:42:54 +1000 (Wed, 06 Aug 2008) | 3 lines Completed `case 21' functions. Cleanup. ------------------------------------------------------------------------ r39 | vwhitteron | 2008-08-06 16:39:53 +1000 (Wed, 06 Aug 2008) | 2 lines Completed `case 19' and `case 20'. ------------------------------------------------------------------------ r38 | nima | 2008-08-06 16:17:21 +1000 (Wed, 06 Aug 2008) | 2 lines Started on `case 19'. ------------------------------------------------------------------------ r37 | nima | 2008-08-06 15:43:05 +1000 (Wed, 06 Aug 2008) | 2 lines Completed `case 18' and `case 19'. ------------------------------------------------------------------------ r36 | nima | 2008-08-06 15:06:03 +1000 (Wed, 06 Aug 2008) | 2 lines Added `case 16' and `case 17'. ------------------------------------------------------------------------ r35 | nima | 2008-08-06 14:26:45 +1000 (Wed, 06 Aug 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r34 | nima | 2008-08-06 14:05:06 +1000 (Wed, 06 Aug 2008) | 2 lines Converted `case 5', `case 6', and `case 7'. ------------------------------------------------------------------------ r33 | nima | 2008-08-01 17:59:51 +1000 (Fri, 01 Aug 2008) | 2 lines Default case set to return python's `None'. ------------------------------------------------------------------------ r32 | nima | 2008-08-01 17:58:24 +1000 (Fri, 01 Aug 2008) | 2 lines Completed `case 15'. ------------------------------------------------------------------------ r31 | nima | 2008-07-29 14:33:59 +1000 (Tue, 29 Jul 2008) | 2 lines Completed `case 9' and case `8'. ------------------------------------------------------------------------ r30 | nima | 2008-07-29 11:31:21 +1000 (Tue, 29 Jul 2008) | 2 lines Completed `case 11'. ------------------------------------------------------------------------ r29 | nima | 2008-07-29 11:28:04 +1000 (Tue, 29 Jul 2008) | 2 lines Completed `case 12' and `case 14'. ------------------------------------------------------------------------ r28 | nima | 2008-07-29 10:29:05 +1000 (Tue, 29 Jul 2008) | 6 lines Bug fix (removed unnecessary breakr). Changed %i back to %u for now, even though it does not work with Python. Better to do the change globally - later. ------------------------------------------------------------------------ r27 | nima | 2008-07-28 20:14:38 +1000 (Mon, 28 Jul 2008) | 2 lines Try and determine python version dynamically. ------------------------------------------------------------------------ r26 | nima | 2008-07-27 22:15:51 +1000 (Sun, 27 Jul 2008) | 2 lines Completed `case 4', which was thought to have been completed falsely before. ------------------------------------------------------------------------ r25 | nima | 2008-07-26 19:15:53 +1000 (Sat, 26 Jul 2008) | 6 lines Completed cases 1, 4, and 13. Also altered the main PyDict object such that each case has a value of a list to which items are appended. Without this, each object of the same type would overwrite the previous, for example, 8 processors would result in one single cpu with data pertaining to the last cpu (7). ------------------------------------------------------------------------ r24 | nima | 2008-07-26 09:35:30 +1000 (Sat, 26 Jul 2008) | 2 lines Completed `case 0'. ------------------------------------------------------------------------ r23 | root | 2008-07-25 23:17:24 +1000 (Fri, 25 Jul 2008) | 2 lines Added `case 3'. ------------------------------------------------------------------------ r22 | root | 2008-07-25 22:51:02 +1000 (Fri, 25 Jul 2008) | 2 lines No new moves, cleanup on last commit and better test file template. ------------------------------------------------------------------------ r21 | root | 2008-07-25 22:27:26 +1000 (Fri, 25 Jul 2008) | 8 lines Next phase is to start converting all pure C functions returning `char *' and such to new Pythonized functions returning `PyObject *', to save from having to `PyString_FromString()' and similar, and more importantly, some functions return a long string that could better be represented by a PyDict, PyList etc. This is the first commit of many more to come, converting a `case XX:' at a time, making sure that each commit can actually compile and run. ------------------------------------------------------------------------ r20 | root | 2008-07-25 11:13:13 +1000 (Fri, 25 Jul 2008) | 2 lines Cleanup (DECREF). ------------------------------------------------------------------------ r19 | root | 2008-07-25 11:12:46 +1000 (Fri, 25 Jul 2008) | 2 lines Add in electric fence for now. ------------------------------------------------------------------------ r18 | root | 2008-07-25 11:11:39 +1000 (Fri, 25 Jul 2008) | 5 lines This was the culprit causing the `Abort' crash, valgrind showed that this file is where the error lied. Stephen Darragh discovered this, and the fix has been to use vsnprintf() and not vsprintf(), which should have been the case to begin with really. ------------------------------------------------------------------------ r17 | root | 2008-07-25 10:46:00 +1000 (Fri, 25 Jul 2008) | 2 lines Cleaner to not vsprintf() at all if `format' is NULL. ------------------------------------------------------------------------ r16 | root | 2008-07-25 10:45:11 +1000 (Fri, 25 Jul 2008) | 2 lines The `biosdecode' is a program, nothing to do with the module, removed. ------------------------------------------------------------------------ r15 | nima | 2008-07-25 00:36:16 +1000 (Fri, 25 Jul 2008) | 2 lines Added my small role in AUTHORS so nobody bugs others for my code. ------------------------------------------------------------------------ r14 | nima | 2008-07-25 00:17:16 +1000 (Fri, 25 Jul 2008) | 2 lines Cleanup. ------------------------------------------------------------------------ r13 | nima | 2008-07-24 22:02:12 +1000 (Thu, 24 Jul 2008) | 2 lines Some cleaning, crash in interactive mode on dmidecode.bios() still not fixed. ------------------------------------------------------------------------ r12 | nima | 2008-07-24 20:48:01 +1000 (Thu, 24 Jul 2008) | 3 lines Now that code has been converted, work has started on "bios", and at the point of proof-of-concept. ------------------------------------------------------------------------ r11 | nima | 2008-07-05 01:24:22 +1000 (Sat, 05 Jul 2008) | 3 lines Removing printf() statements, instead adding to Python dictionary object, untested. ------------------------------------------------------------------------ r10 | nima | 2008-07-04 01:59:08 +1000 (Fri, 04 Jul 2008) | 6 lines Major changes have been implemented, alas, untested, in hope to move towards a new version of dmi decode where rather than having data just printed to screen in functions, data is passed around, and some data structure is constructed, which is then used to construct the Python list/dicitonary objects. ------------------------------------------------------------------------ r9 | nima | 2008-07-02 17:02:05 +1000 (Wed, 02 Jul 2008) | 4 lines WIP - Adding h->type value to catsprintf (as int major), later will add minor too, and finally will replace the buffer with a linked list of structs, which will be added to the python dictionary/list. ------------------------------------------------------------------------ r8 | nima | 2008-07-02 14:53:48 +1000 (Wed, 02 Jul 2008) | 3 lines Now the `Handle' hex codes are the key values in the python dictionaries returned. ------------------------------------------------------------------------ r7 | nima | 2008-07-02 09:14:17 +1000 (Wed, 02 Jul 2008) | 2 lines Brought main() back into the python module and fixed malloc/free problems. ------------------------------------------------------------------------ r6 | nima | 2008-07-01 17:05:57 +1000 (Tue, 01 Jul 2008) | 2 lines Removed junk comments. ------------------------------------------------------------------------ r5 | nima | 2008-07-01 16:11:21 +1000 (Tue, 01 Jul 2008) | 2 lines Update for file renames. ------------------------------------------------------------------------ r4 | nima | 2008-07-01 16:04:02 +1000 (Tue, 01 Jul 2008) | 2 lines Better named. ------------------------------------------------------------------------ r3 | nima | 2008-07-01 16:01:21 +1000 (Tue, 01 Jul 2008) | 5 lines Project progressing along excellently. The python module is now functional and has as many methods as the --type option takes. Next is to expand and harness the code around the `--string' option. ------------------------------------------------------------------------ r2 | nima | 2008-07-01 00:14:46 +1000 (Tue, 01 Jul 2008) | 4 lines Split out the module header into its own file. Cleaned up Makefile a little. ------------------------------------------------------------------------ r1 | nima | 2008-06-30 22:08:58 +1000 (Mon, 30 Jun 2008) | 2 lines First commit to SVN. ------------------------------------------------------------------------ python-dmidecode-3.10.13/examples/0000755002425500234200000000000011401675045016320 5ustar nimaautonomypython-dmidecode-3.10.13/examples/dmidump.py0000755002425500234200000001454311401675045020343 0ustar nimaautonomy#!/usr/bin/env python # # Examples which makes use of the different python-dmidecode features # This script should be run as root, or else expect permission warnings # # Copyright 2008-2009 Nima Talebi # Copyright 2010 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 dmidecode import sys, os from pprint import pprint def print_warnings(): "Simple function, dumping out warnings with a prefix if warnings are found and clearing warning buffer" warn = dmidecode.get_warnings() if warn: print "### WARNING: %s" % warn dmidecode.clear_warnings() # Check if running as root .... provide a warning if not root_user = (os.getuid() == 0 and True or False) if not root_user: print "####" print "#### NOT RUNNING AS ROOT" print "####" print "#### The first run must always be done as root for this example to work." print "#### When not run as root, quite some permission errors might appear" print "####" print "#### If this script is first run as root, it should be possible to run this script" print "#### as an unprivileged user afterwards, with less warnings." print "####" print print #. Test for presence of important functions using /dev/mem... Using the legacy API #. This does not print any decoded info. If the call fails, either a warning will #. be issued or an exception will be raised. This test is now only used to check #. for presence of the legacy API, which "under the hood" uses #. dmidecode.QuerySection(name), where name can be 'bios', 'system', etc. if root_user: print "*** bios ***\n"; dmidecode.bios() print_warnings() print "*** system ***\n"; dmidecode.system() print_warnings() print "*** baseboard ***\n"; dmidecode.baseboard() print_warnings() print "*** chassis ***\n"; dmidecode.chassis() print_warnings() print "*** processor ***\n"; dmidecode.processor() print_warnings() print "*** memory ***\n"; dmidecode.memory() print_warnings() print "*** cache ***\n"; dmidecode.cache() print_warnings() print "*** connector ***\n"; dmidecode.connector() print_warnings() print "*** slot ***\n"; dmidecode.slot() print_warnings() #. Now test get/set of memory device file... print "*** get_dev()" print dmidecode.get_dev() print_warnings() print "*** set_dev('dmidata.dump')" print dmidecode.set_dev("dmidata.dump"); print_warnings() print "*** get_dev()" print dmidecode.get_dev() print_warnings() #. Test taking a dump... if root_user: print "*** Dumping DMI data to dump file" print dmidecode.dump() print_warnings() #. Test reading the dump... Using the preferred API print "*** bios ***\n"; pprint(dmidecode.QuerySection('bios')) print_warnings() print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) print_warnings() print "*** baseboard ***\n"; pprint(dmidecode.QuerySection('baseboard')) print_warnings() print "*** chassis ***\n"; pprint(dmidecode.QuerySection('chassis')) print_warnings() print "*** processor ***\n"; pprint(dmidecode.QuerySection('processor')) print_warnings() print "*** memory ***\n"; pprint(dmidecode.QuerySection('memory')) print_warnings() print "*** cache ***\n"; pprint(dmidecode.QuerySection('cache')) print_warnings() print "*** connector ***\n"; pprint(dmidecode.QuerySection('connector')) print_warnings() print "*** slot ***\n"; pprint(dmidecode.QuerySection('slot')) print_warnings() print "*** Extracting memory information" for v in dmidecode.memory().values(): if type(v) == dict and v['dmi_type'] == 17: pprint(v['data']['Size']), print "*** Querying for DMI type 3 and 7" pprint(dmidecode.type(3)) # <-- Legacy API pprint(dmidecode.QueryTypeId(7)) # <-- preferred API print_warnings() print "*** Querying for the BIOS section" pprint(dmidecode.QuerySection('bios')) print_warnings() # # Test XML stuff # print print print print "---------------------------------------" print "*** *** *** Testing XML API *** *** ***" print "---------------------------------------" print print dmixml = dmidecode.dmidecodeXML() # Fetch all DMI data into a libxml2.xmlDoc object print "*** Getting all DMI data into a XML document variable" dmixml.SetResultType(dmidecode.DMIXML_DOC) # Valid values: dmidecode.DMIXML_DOC, dmidecode.DMIXML_NODE xmldoc = dmixml.QuerySection('all') # Dump the XML to dmidump.xml - formated in UTF-8 decoding print "*** Dumping XML document to dmidump.xml" xmldoc.saveFormatFileEnc('dmidump.xml','UTF-8',1) # Do some XPath queries on the XML document print "*** Doing some XPath queries against the XML document" dmixp = xmldoc.xpathNewContext() # What to look for - XPath expressions keys = ['/dmidecode/SystemInfo/Manufacturer', '/dmidecode/SystemInfo/ProductName', '/dmidecode/SystemInfo/SerialNumber', '/dmidecode/SystemInfo/SystemUUID'] # Extract data and print it for k in keys: data = dmixp.xpathEval(k) for d in data: print "%s: %s" % (k, d.get_content()) del dmixp del xmldoc # Query for only a particular DMI TypeID - 0x04 - Processor print "*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout" dmixml.QueryTypeId(0x04).saveFormatFileEnc('-','UTF-8',1) print_warnings() python-dmidecode-3.10.13/man/0000755002425500234200000000000011401675045015255 5ustar nimaautonomypython-dmidecode-3.10.13/man/biosdecode.80000644002425500234200000000347011401675045017452 0ustar nimaautonomy.TH BIOSDECODE 8 "February 2007" "dmidecode" .SH NAME biosdecode \- \s-1BIOS\s0 information decoder .SH SYNOPSIS .B biosdecode .RB [ OPTIONS ] .SH DESCRIPTION .B biosdecode parses the \s-1BIOS\s0 memory and prints information about all structures (or entry points) it knows of. Currently known entry point types are: .IP \(bu "\w'\(bu'u+1n" \s-1SMBIOS\s0 (System Management \s-1BIOS\s0) .br Use .B dmidecode for a more detailed output. .IP \(bu \s-1DMI\s0 (Desktop Management Interface, a legacy version of \s-1SMBIOS\s0) .br Use .B dmidecode for a more detailed output. .IP \(bu \s-1SYSID\s0 .IP \(bu \s-1PNP\s0 (Plug and Play) .IP \(bu \s-1ACPI\s0 (Advanced Configuration and Power Interface) .IP \(bu \s-1BIOS32\s0 (\s-1BIOS32\s0 Service Directory) .IP \(bu \s-1PIR\s0 (\s-1PCI\s0 \s-1IRQ\s0 Routing) .IP \(bu \s-132OS\s0 (\s-1BIOS32\s0 Extension, Compaq-specific) .br See .B ownership for a Compaq ownership tag retrieval tool. .IP \(bu \s-1SNY\s0 (Sony-specific, not decoded) .IP \(bu \s-1VPD\s0 (Vital Product Data, IBM-specific) .br Use .B vpddecode for a more detailed output. .IP \(bu \s-1FJKEYINF\s0 (Application Panel, Fujitsu-specific) .PP .B biosdecode started its life as a part of .B dmidecode but as more entry point types were added, if was moved to a different program. .SH OPTIONS .TP .BR "-d" ", " "--dev-mem FILE" Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR) .TP .BR "-h" ", " "--help" Display usage information and exit .TP .BR "-V" ", " "--version" Display the version and exit .SH FILES .I /dev/mem .SH BUGS Most of the time, .B biosdecode prints too much information (you don't really care about addresses) or not enough (because it doesn't follow pointers and has no lookup tables). .SH AUTHORS Alan Cox, Jean Delvare .SH "SEE ALSO" .BR dmidecode (8), .BR mem (4), .BR ownership (8), .BR vpddecode (8) python-dmidecode-3.10.13/man/dmidecode.80000644002425500234200000001666611401675045017302 0ustar nimaautonomy.TH DMIDECODE 8 "October 2008" "dmidecode" .SH NAME dmidecode \- \s-1DMI\s0 table decoder .SH SYNOPSIS .B dmidecode .RB [ OPTIONS ] .SH DESCRIPTION .B dmidecode is a tool for dumping a computer's \s-1DMI\s0 (some say \s-1SMBIOS\s0) table contents in a human-readable format. This table contains a description of the system's hardware components, as well as other useful pieces of information such as serial numbers and \s-1BIOS\s0 revision. Thanks to this table, you can retrieve this information without having to probe for the actual hardware. While this is a good point in terms of report speed and safeness, this also makes the presented information possibly unreliable. The \s-1DMI\s0 table doesn't only describe what the system is currently made of, it also can report the possible evolutions (such as the fastest supported \s-1CPU\s0 or the maximal amount of memory supported). \s-1SMBIOS\s0 stands for System Management \s-1BIOS\s0, while \s-1DMI\s0 stands for Desktop Management Interface. Both standards are tightly related and developed by the \s-1DMTF\s0 (Desktop Management Task Force). As you run it, .B dmidecode will try to locate the \s-1DMI\s0 table. If it succeeds, it will then parse this table and display a list of records like this one: Handle 0x0002, DMI type 2, 8 bytes. Base Board Information Manufacturer: Intel Product Name: C440GX+ Version: 727281-001 Serial Number: INCY92700942 Each record has: .IP \(bu "\w'\(bu'u+1n" A handle. This is a unique identifier, which allows records to reference each other. For example, processor records usually reference cache memory records using their handles. .IP \(bu A type. The \s-1SMBIOS\s0 specification defines different types of elements a computer can be made of. In this example, the type is 2, which means that the record contains "Base Board Information". .IP \(bu A size. Each record has a 4-byte header (2 for the handle, 1 for the type, 1 for the size), the rest is used by the record data. This value doesn't take text strings into account (these are placed at the end of the record), so the actual length of the record may be (and is often) greater than the displayed value. .IP \(bu Decoded values. The information presented of course depends on the type of record. Here, we learn about the board's manufacturer, model, version and serial number. .SH OPTIONS .TP .BR "-d" ", " "--dev-mem FILE" Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR) .TP .BR "-q" ", " "--quiet" Be less verbose. Unknown, inactive and \s-1OEM\s0-specific entries are not displayed. Meta-data and handle references are hidden. .TP .BR "-s" ", " "--string KEYWORD" Only display the value of the \s-1DMI\s0 string identified by \fBKEYWORD\fR. \fBKEYWORD\fR must be a keyword from the following list: \fBbios-vendor\fR, \fBbios-version\fR, \fBbios-release-date\fR, \fBsystem-manufacturer\fR, \fBsystem-product-name\fR, \fBsystem-version\fR, \fBsystem-serial-number\fR, \fBsystem-uuid\fR, \fBbaseboard-manufacturer\fR, \fBbaseboard-product-name\fR, \fBbaseboard-version\fR, \fBbaseboard-serial-number\fR, \fBbaseboard-asset-tag\fR, \fBchassis-manufacturer\fR, \fBchassis-type\fR, \fBchassis-version\fR, \fBchassis-serial-number\fR, \fBchassis-asset-tag\fR, \fBprocessor-family\fR, \fBprocessor-manufacturer\fR, \fBprocessor-version\fR, \fBprocessor-frequency\fR. Each keyword corresponds to a given \s-1DMI\s0 type and a given offset within this entry type. Not all strings may be meaningful or even defined on all systems. Some keywords may return more than one result on some systems (e.g. \fBprocessor-version\fR on a multi-processor system). If \fBKEYWORD\fR is not provided or not valid, a list of all valid keywords is printed and .B dmidecode exits with an error. This option cannot be used more than once. .TP .BR "-t" ", " "--type TYPE" Only display the entries of type \fBTYPE\fR. \fBTYPE\fR can be either a \s-1DMI\s0 type number, or a comma-separated list of type numbers, or a keyword from the following list: \fBbios\fR, \fBsystem\fR, \fBbaseboard\fR, \fBchassis\fR, \fBprocessor\fR, \fBmemory\fR, \fBcache\fR, \fBconnector\fR, \fBslot\fR. Refer to the DMI TYPES section below for details. If this option is used more than once, the set of displayed entries will be the union of all the given types. If \fBTYPE\fR is not provided or not valid, a list of all valid keywords is printed and .B dmidecode exits with an error. .TP .BR "-u" ", " "--dump" Do not decode the entries, dump their contents as hexadecimal instead. Note that this is still a text output, no binary data will be thrown upon you. The strings attached to each entry are displayed as both hexadecimal and \s-1ASCII\s0. This option is mainly useful for debugging. .TP .BR " " " " "--dump-bin FILE" Do not decode the entries, instead dump the DMI data to a file in binary form. The generated file is suitable to pass to \fB--from-dump\fR later. .TP .BR " " " " "--from-dump FILE" Read the DMI data from a binary file previously generated using \fB--dump-bin\fR. .TP .BR "-h" ", " "--help" Display usage information and exit .TP .BR "-V" ", " "--version" Display the version and exit .P Options --string, --type, --dump and --dump-bin determine the output format and are mutually exclusive. .SH "DMI TYPES" The \s-1SMBIOS\s0 specification defines the following \s-1DMI\s0 types: .TS r l __ r l. Type Information 0 BIOS 1 System 2 Base Board 3 Chassis 4 Processor 5 Memory Controller 6 Memory Module 7 Cache 8 Port Connector 9 System Slots 10 On Board Devices 11 OEM Strings 12 System Configuration Options 13 BIOS Language 14 Group Associations 15 System Event Log 16 Physical Memory Array 17 Memory Device 18 32-bit Memory Error 19 Memory Array Mapped Address 20 Memory Device Mapped Address 21 Built-in Pointing Device 22 Portable Battery 23 System Reset 24 Hardware Security 25 System Power Controls 26 Voltage Probe 27 Cooling Device 28 Temperature Probe 29 Electrical Current Probe 30 Out-of-band Remote Access 31 Boot Integrity Services 32 System Boot 33 64-bit Memory Error 34 Management Device 35 Management Device Component 36 Management Device Threshold Data 37 Memory Channel 38 IPMI Device 39 Power Supply .TE Additionally, type 126 is used for disabled entries and type 127 is an end-of-table marker. Types 128 to 255 are for \s-1OEM\s0-specific data. .B dmidecode will display these entries by default, but it can only decode them when the vendors have contributed documentation or code for them. Keywords can be used instead of type numbers with \fB--type\fR. Each keyword is equivalent to a list of type numbers: .TS l l __ l l. Keyword Types bios 0, 13 system 1, 12, 15, 23, 32 baseboard 2, 10 chassis 3 processor 4 memory 5, 6, 16, 17 cache 7 connector 8 slot 9 .TE Keywords are matched case-insensitively. The following command lines are equivalent: .IP \(bu "\w'\(bu'u+1n" dmidecode --type 0 --type 13 .IP \(bu dmidecode --type 0,13 .IP \(bu dmidecode --type bios .IP \(bu dmidecode --type BIOS .SH BINARY DUMP FILE FORMAT The binary dump files generated by --dump-bin and read using --from-dump are formatted as follows: .IP \(bu "\w'\(bu'u+1n" The SMBIOS or DMI entry point is located at offset 0x00. It is crafted to hard-code the table address at offset 0x20. .IP \(bu "\w'\(bu'u+1n" The DMI table is located at offset 0x20. .SH FILES .I /dev/mem .SH BUGS More often than not, information contained in the \s-1DMI\s0 tables is inaccurate, incomplete or simply wrong. .SH AUTHORS Alan Cox, Jean Delvare .SH "SEE ALSO" .BR biosdecode (8), .BR mem (4), .BR ownership (8), .BR vpddecode (8) python-dmidecode-3.10.13/man/ownership.80000644002425500234200000000145211401675045017366 0ustar nimaautonomy.TH OWNERSHIP 8 "February 2005" "dmidecode" .SH NAME ownership \- Compaq ownership tag retriever .SH SYNOPSIS .B ownership .RB [ OPTIONS ] .SH DESCRIPTION .B ownership retrieves and prints the "ownership tag" that can be set on Compaq computers. Contrary to all other programs of the .B dmidecode package, .B ownership doesn't print any version information, nor labels, but only the raw ownership tag. This should help its integration in scripts. .SH OPTIONS .TP .BR "-d" ", " "--dev-mem FILE" Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR) .TP .BR "-h" ", " "--help" Display usage information and exit .TP .BR "-V" ", " "--version" Display the version and exit .SH FILES .I /dev/mem .SH AUTHOR Jean Delvare .SH "SEE ALSO" .BR biosdecode (8), .BR dmidecode (8), .BR mem (4), .BR vpddecode (8) python-dmidecode-3.10.13/man/vpddecode.80000644002425500234200000000403111401675045017301 0ustar nimaautonomy.TH VPDDECODE 8 "February 2007" "dmidecode" .SH NAME vpddecode \- \s-1VPD\s0 structure decoder .SH SYNOPSIS .B vpddecode .RB [ OPTIONS ] .SH DESCRIPTION .B vpddecode prints the "vital product data" information that can be found in almost all IBM and Lenovo computers. Available items are: .IP \(bu "\w'\(bu'u+1n" \s-1BIOS\s0 Build \s-1ID\s0 .IP \(bu Box Serial Number .IP \(bu Motherboard Serial Number .IP \(bu Machine Type/Model .PP Some systems have these additional items: .IP \(bu "\w'\(bu'u+1n" BIOS Release Date .IP \(bu Default Flash Image File Name .PP Note that these additional items are not documented by IBM, so this is guess work, and as such should not be blindly trusted. Feedback about the accuracy of these labels is welcome. .SH OPTIONS .TP .BR "-d" ", " "--dev-mem FILE" Read memory from device \fBFILE\fR (default: \fB/dev/mem\fR) .TP .BR "-s" ", " "--string KEYWORD" Only display the value of the \s-1VPD\s0 string identified by \fBKEYWORD\fR. \fBKEYWORD\fR must be a keyword from the following list: \fBbios-build-id\fR, \fBbox-serial-number\fR, \fBmotherboard-serial-number\fR, \fBmachine-type-model\fR, \fBbios-release-date\fR. Each keyword corresponds to an offset and a length within the \s-1VPD\s0 record. Not all strings may be defined on all \s-1VPD\s0-enabled systems. If \fBKEYWORD\fR is not provided or not valid, a list of all valid keywords is printed and .B vpddecode exits with an error. This option cannot be used more than once. Mutually exclusive with \fB--dump\fR. .TP .BR "-u" ", " "--dump" Do not decode the VPD records, dump their contents as hexadecimal instead. Note that this is still a text output, no binary data will be thrown upon you. ASCII equivalent is displayed when possible. This option is mainly useful for debugging. Mutually exclusive with \fB--string\fR. .TP .BR "-h" ", " "--help" Display usage information and exit .TP .BR "-V" ", " "--version" Display the version and exit .SH FILES .I /dev/mem .SH AUTHOR Jean Delvare .SH "SEE ALSO" .BR biosdecode (8), .BR dmidecode (8), .BR mem (4), .BR ownership (8) python-dmidecode-3.10.13/src/0000755002425500234200000000000011401712100015251 5ustar nimaautonomypython-dmidecode-3.10.13/src/compat.h0000644002425500234200000000303011401675045016721 0ustar nimaautonomy/* 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 python-dmidecode-3.10.13/src/config.h0000644002425500234200000000434111401675045016711 0ustar nimaautonomy/* * © 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 */ #ifndef CONFIG_H #define CONFIG_H /* Default memory device file */ #ifdef __BEOS__ #define DEFAULT_MEM_DEV "/dev/misc/mem" #else #define DEFAULT_MEM_DEV "/dev/mem" #endif /* Use mmap or not */ #ifndef __BEOS__ #define USE_MMAP #endif /* Use memory alignment workaround or not */ #ifdef __ia64__ #define ALIGNMENT_WORKAROUND #endif #ifndef PYTHON_XML_MAP #define PYTHON_XML_MAP "/usr/share/python-dmidecode/pymap.xml" #endif #endif python-dmidecode-3.10.13/src/dmidecode.h0000644002425500234200000000332011401675045017355 0ustar nimaautonomy /* * This file is part of the dmidecode project. * * (C) 2005-2007 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 */ #include #include "dmihelper.h" #include "dmierror.h" struct dmi_header { u8 type; u8 length; u16 handle; u8 *data; }; 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); 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(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode); int legacy_decode(Log_t *logp, 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); void dmi_chassis_type(xmlNode *node, u8 code); int dmi_processor_frequency(const u8 * p); python-dmidecode-3.10.13/src/dmidecodemodule.c0000644002425500234200000007403011401675045020564 0ustar nimaautonomy /*. ******* 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 #include "libxml_wrap.h" #include "dmidecodemodule.h" #include "dmixml.h" #include "dmierror.h" #include "dmilog.h" #include "xmlpythonizer.h" #include "version.h" #include "dmidump.h" #include static void init(options *opt) { opt->devmem = DEFAULT_MEM_DEV; opt->dumpfile = NULL; opt->flags = 0; opt->type = -1; opt->dmiversion_n = NULL; opt->mappingxml = NULL; opt->python_xml_map = strdup(PYTHON_XML_MAP); opt->logdata = log_init(); /* sanity check */ if(sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, "%s: compiler incompatibility", "dmidecodemodule"); } } int parse_opt_type(Log_t *logp, const char *arg) { while(*arg != '\0') { int val; char *next; val = strtoul(arg, &next, 0); if(next == arg) { log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type keyword: %s", arg); return -1; } if(val > 0xff) { log_append(logp, LOGFL_NODUPS, LOG_ERR, "Invalid type number: %i", val); return -1; } if( val >= 0 ) { return val; } arg = next; while(*arg == ',' || *arg == ' ') arg++; } return -1; } xmlNode *dmidecode_get_version(options *opt) { int found = 0; size_t fp; int efi; u8 *buf = NULL; xmlNode *ver_n = NULL; /* Set default option values */ if( opt->devmem == NULL ) { opt->devmem = DEFAULT_MEM_DEV; } /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { //. printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { 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, opt->dumpfile); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } } } } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(opt->logdata, &fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ if((buf = mem_chunk(opt->logdata, 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); 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); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } } } } } else if(efi == EFI_NO_SMBIOS) { ver_n = NULL; } else { // Process as EFI if((buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem)) != NULL) { ver_n = smbios_decode_get_version(buf, opt->devmem); if( dmixml_GetAttrValue(ver_n, "unknown") == NULL ) { found++; } //. TODO: dmixml_AddAttribute(dmixml_n, "efi_address", efiAddress); } } } if( buf != NULL ) { free(buf); } if( !found ) { log_append(opt->logdata, LOGFL_NODUPS, LOG_WARNING, "No SMBIOS nor DMI entry point found, sorry."); } return ver_n; } int dmidecode_get_xml(options *opt, xmlNode* dmixml_n) { assert(dmixml_n != NULL); if(dmixml_n == NULL) { return 0; } //mtrace(); int ret = 0; int found = 0; size_t fp; int efi; u8 *buf = NULL; const char *f = opt->dumpfile ? opt->dumpfile : opt->devmem; if(access(f, R_OK) < 0) { log_append(opt->logdata, LOGFL_NORMAL, LOG_WARNING, "Permission denied to memory file/device (%s)", f); return 0; } /* Read from dump if so instructed */ if(opt->dumpfile != NULL) { // printf("Reading SMBIOS/DMI data from file %s.\n", dumpfile); if((buf = mem_chunk(opt->logdata, 0, 0x20, opt->dumpfile)) != NULL) { if(memcmp(buf, "_SM_", 4) == 0) { if(smbios_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) found++; } else if(memcmp(buf, "_DMI_", 5) == 0) { if(legacy_decode(opt->logdata, opt->type, buf, opt->dumpfile, dmixml_n)) found++; } } else { ret = 1; } } else { /* Read from /dev/mem */ /* First try EFI (ia64, Intel-based Mac) */ efi = address_from_efi(opt->logdata, &fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ if((buf = mem_chunk(opt->logdata, 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->logdata, opt->type, buf + fp, opt->devmem, dmixml_n)) { found++; fp += 16; } } else if(memcmp(buf + fp, "_DMI_", 5) == 0) { if(legacy_decode(opt->logdata, opt->type, buf + fp, opt->devmem, dmixml_n)) found++; } } } else ret = 1; } else if(efi == EFI_NO_SMBIOS) { ret = 1; } else { if((buf = mem_chunk(opt->logdata, fp, 0x20, opt->devmem)) == NULL) ret = 1; else if(smbios_decode(opt->logdata, opt->type, buf, opt->devmem, dmixml_n)) found++; // TODO: dmixml_AddAttribute(dmixml_n, "efi_address", "0x%08x", efiAddress); } } if(ret == 0) { free(buf); } //muntrace(); return ret; } xmlNode* load_mappingxml(options *opt) { if( opt->mappingxml == NULL ) { // Load mapping into memory opt->mappingxml = xmlReadFile(opt->python_xml_map, NULL, 0); if( opt->mappingxml == NULL ) { PyReturnError(PyExc_IOError, "Could not open tje XML mapping file '%s'", opt->python_xml_map); } } return dmiMAP_GetRootElement(opt->mappingxml); } xmlNode *__dmidecode_xml_getsection(options *opt, const char *section) { xmlNode *dmixml_n = NULL; xmlNode *group_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)); } // 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 ) { 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 ) { PyReturnError(PyExc_LookupError, "Could not find the XML->Python Mapping section for '%s'", section); } if( group_n->children == 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 foreach_xmlnode(dmixml_FindNode(group_n, "TypeMap"), group_n) { char *typeid = dmixml_GetAttrValue(group_n, "id"); if( group_n->type != XML_ELEMENT_NODE ) { continue; } // The children of tags must only be and // they must have an 'id' attribute if( (typeid == NULL) || (xmlStrcmp(group_n->name, (xmlChar *) "TypeMap") != 0) ) { PyReturnError(PyExc_RuntimeError, "Invalid TypeMap node in mapping XML"); } // Parse the typeid string to a an integer opt->type = parse_opt_type(opt->logdata, typeid); if(opt->type == -1) { char *err = log_retrieve(opt->logdata, LOG_ERR); log_clear_partial(opt->logdata, LOG_ERR, 0); PyReturnError(PyExc_RuntimeError, "Invalid type id '%s' -- %s", typeid, err); } // Parse the DMI data and put the result into dmixml_n node chain. if( dmidecode_get_xml(opt, dmixml_n) != 0 ) { PyReturnError(PyExc_RuntimeError, "Error decoding DMI data"); } } #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 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->logdata, opt->mappingxml, section); if( mapping == NULL ) { // Exception already set xmlFreeNode(dmixml_n); return NULL; } // Generate Python dict out of XML node pydata = pythonizeXMLnode(opt->logdata, mapping, dmixml_n); // Clean up and return the resulting Python dictionary ptzmap_Free(mapping); xmlFreeNode(dmixml_n); return pydata; } xmlNode *__dmidecode_xml_gettypeid(options *opt, int typeid) { xmlNode *dmixml_n = 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 ) { 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->logdata, opt->mappingxml, opt->type); if( mapping == 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(opt->logdata, mapping, dmixml_n); // Clean up and return the resulting Python dictionary ptzmap_Free(mapping); xmlFreeNode(dmixml_n); return pydata; } // 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_group(global_options, "bios"); } static PyObject *dmidecode_get_system(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "system"); } static PyObject *dmidecode_get_baseboard(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "baseboard"); } static PyObject *dmidecode_get_chassis(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "chassis"); } static PyObject *dmidecode_get_processor(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "processor"); } static PyObject *dmidecode_get_memory(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "memory"); } static PyObject *dmidecode_get_cache(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "cache"); } static PyObject *dmidecode_get_connector(PyObject * self, PyObject * args) { return dmidecode_get_group(global_options, "connector"); } 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; PyObject *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 { PyReturnError(PyExc_RuntimeError, "Type '%i' is not a valid type identifier%c", typeid); } pydata = dmidecode_get_typeid(global_options, typeid); return pydata; } static PyObject *dmidecode_xmlapi(PyObject *self, PyObject *args, PyObject *keywds) { static char *keywordlist[] = {"query_type", "result_type", "section", "typeid", NULL}; 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; 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(DEFAULT_MEM_DEV, f) ) { Py_RETURN_TRUE; } } Py_RETURN_FALSE; } static PyObject *dmidecode_get_dev(PyObject * self, PyObject * null) { PyObject *dev = NULL; dev = PyString_FromString((global_options->dumpfile != NULL ? global_options->dumpfile : global_options->devmem)); Py_INCREF(dev); return dev; } static PyObject *dmidecode_set_dev(PyObject * self, PyObject * arg) { if(PyString_Check(arg)) { struct stat buf; char *f = PyString_AsString(arg); if( (f != NULL) && (global_options->dumpfile != NULL ) && (strcmp(global_options->dumpfile, f) == 0) ) { Py_RETURN_TRUE; } if( (f == NULL) || (strlen(f) < 0) ) { PyReturnError(PyExc_RuntimeError, "set_dev() file name string cannot be empty"); } errno = 0; if( stat(f, &buf) < 0 ) { if( errno == ENOENT ) { // If this file does not exist, that's okay. // python-dmidecode will create it. global_options->dumpfile = strdup(f); Py_RETURN_TRUE; } PyReturnError(PyExc_RuntimeError, strerror(errno)); } if(S_ISCHR(buf.st_mode)) { if(memcmp(f, "/dev/mem", 8) == 0) { if( global_options->dumpfile != NULL ) { free(global_options->dumpfile); global_options->dumpfile = NULL; } Py_RETURN_TRUE; } else { PyReturnError(PyExc_RuntimeError, "Invalid memory device: %s", f); } } else if(S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode) ) { global_options->dumpfile = strdup(f); Py_RETURN_TRUE; } } PyReturnError(PyExc_RuntimeError, "set_dev(): Invalid input"); } 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 ) { PyReturnError(PyExc_IOError, "Could not access the file '%s'", fname); } free(global_options->python_xml_map); global_options->python_xml_map = strdup(fname); Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * dmidecode_get_warnings(PyObject *self, PyObject *null) { char *warn = NULL; PyObject *ret = NULL; warn = log_retrieve(global_options->logdata, LOG_WARNING); if( warn ) { ret = PyString_FromString(warn); free(warn); } else { ret = Py_None; } return ret; } static PyObject * dmidecode_clear_warnings(PyObject *self, PyObject *null) { log_clear_partial(global_options->logdata, LOG_WARNING, 1); Py_RETURN_TRUE; } 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 *)"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 *)"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}, {(char *)"xmlapi", dmidecode_xmlapi, METH_KEYWORDS, (char *) "Internal API for retrieving data as raw XML data"}, {(char *)"get_warnings", dmidecode_get_warnings, METH_NOARGS, (char *) "Retrieve warnings from operations"}, {(char *)"clear_warnings", dmidecode_clear_warnings, METH_NOARGS, (char *) "Clear all warnings"}, {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; } if( opt->logdata != NULL ) { char *warn = NULL; log_clear_partial(opt->logdata, LOG_WARNING, 0); warn = log_retrieve(opt->logdata, LOG_WARNING); if( warn ) { fprintf(stderr, "\n** COLLECTED WARNINGS **\n%s** END OF WARNINGS **\n\n", warn); free(warn); } log_close(opt->logdata); } free(ptr); } PyMODINIT_FUNC initdmidecodemod(void) { char *dmiver = NULL; PyObject *module = NULL; PyObject *version = NULL; options *opt; xmlInitParser(); xmlXPathInit(); opt = (options *) malloc(sizeof(options)+2); memset(opt, 0, sizeof(options)+2); init(opt); module = Py_InitModule3((char *)"dmidecodemod", DMIDataMethods, "Python extension module for dmidecode"); version = PyString_FromString(VERSION); Py_INCREF(version); PyModule_AddObject(module, "version", version); 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; } python-dmidecode-3.10.13/src/dmidecodemodule.h0000644002425500234200000000621611401675045020572 0ustar nimaautonomy/*. ******* 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 #include #include #include #include #include #include #include "compat.h" #include "version.h" #include "config.h" #include "types.h" #include "util.h" #include "dmidecode.h" #include "dmioem.h" #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) #include "dmihelper.h" xmlNode *dmidecode_get_version(options *); extern void dmi_dump(xmlNode *node, struct dmi_header *h); extern int address_from_efi(Log_t *logp, size_t * address); extern void to_dmi_header(struct dmi_header *h, u8 * data); extern int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *node); extern int legacy_decode(Log_t *logp, 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(Log_t *logp, size_t base, size_t len, const char *devmem); PyMODINIT_FUNC initdmidecode(void); python-dmidecode-3.10.13/src/dmidump.c0000644002425500234200000001451411401675045017101 0ustar nimaautonomy/* 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 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; } 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(NULL, 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(NULL, &fp); if(efi == EFI_NOT_FOUND) { /* Fallback to memory scan (x86, x86_64) */ if((buf = mem_chunk(NULL, 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(NULL, 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; } #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 python-dmidecode-3.10.13/src/dmidump.h0000644002425500234200000000273111401675045017104 0ustar nimaautonomy/* 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 python-dmidecode-3.10.13/src/dmierror.c0000644002425500234200000000543511401675045017267 0ustar nimaautonomy/* 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 // Enable for copy of error messages to stderr /** * 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; } python-dmidecode-3.10.13/src/dmierror.h0000644002425500234200000000413311401675045017266 0ustar nimaautonomy/* 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 python-dmidecode-3.10.13/src/dmihelper.h0000644002425500234200000001324211401675045017415 0ustar nimaautonomy/*. ******* 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 #include #include #include #include #include #include #include #include "types.h" #include "dmilog.h" #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"}, {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} }; /*** dmiopt.h ***/ typedef struct _options { const char *devmem; unsigned int flags; int type; xmlDoc *mappingxml; char *python_xml_map; xmlNode *dmiversion_n; char *dumpfile; Log_t *logdata; } options; #endif python-dmidecode-3.10.13/src/dmilog.c0000644002425500234200000001401511401675045016711 0ustar nimaautonomy/* * 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 dmilog.h * @brief A simple log module * @author David Sommerseth */ #include #include #include #include #include "dmilog.h" /** * Allocates memory for a new Log_t record * * @return Returns a pointer to a new Log_t record, otherwise NULL on error */ Log_t * log_init() { Log_t *ret = NULL; ret = (Log_t *) calloc(1, sizeof(Log_t)+2); if( !ret ) { fprintf(stderr, "** ERROR ** Could not allocate memory for log data\n"); } ret->level = -1; // Initialised - chain header pointer always have -1. return ret; } /** * Registers a new log entry * * @param logp Pointer to an allocated Log_t record. New records will be appended to the end * @param flags Log flags, to specify logging behaviour * @param level syslog log level values. LOG_ERR and LOG_WARNING are allowed * @param fmt stdarg based string with the log contents * * @return Returns 1 on successful registration of log entry, otherwise -1 and error is printed to stderr * unless LOGFL_NOSTDERR is set in flags. */ int log_append(Log_t *logp, Log_f flags, int level, const char *fmt, ...) { Log_t *ptr = NULL; va_list ap; char logmsg[4098]; // Prepare log message memset(&logmsg, 0, 4098); va_start(ap, fmt); vsnprintf(logmsg, 4096, fmt, ap); va_end(ap); // Go the end of the record chain ptr = logp; while( ptr && ptr->next ) { // Ignore duplicated messages if LOGFL_NODUPS is set if( (flags & LOGFL_NODUPS) && ptr->next && ptr->next->message && (strcmp(ptr->next->message, logmsg) == 0) ) { return 1; } ptr = ptr->next; } if( ptr && ((level == LOG_ERR) || (level == LOG_WARNING)) ) { ptr->next = log_init(); if( ptr->next ) { ptr->next->level = level; ptr->next->message = strdup(logmsg); return 1; } } if( !(flags & LOGFL_NOSTDERR) ) { if( logp ) { // Only print this if we logp is pointing somewhere. // If it is NULL, the caller did not establish a log // buffer on purpose (like dmidump.c) - thus this is // not an error with saving the log entry. fprintf(stderr, "** ERROR ** Failed to save log entry\n"); } fprintf(stderr, "%s\n", logmsg); } return -1; } /** * Retrieve all log entries in the Log_t record chain with the corresponding log level. * One string will be returned, with all log entries separated with newline. * * @param logp Pointer to Log_t record chain with log data * @param level Log entries to retrieve * * @return Returns a pointer to a buffer with all log lines. This must be freed after usage. */ char * log_retrieve(Log_t *logp, int level) { char *ret = NULL; size_t len = 0; Log_t *ptr = NULL; if( !logp ) { return NULL; } for( ptr = logp; ptr != NULL; ptr = ptr->next ) { if( ptr && ptr->level == level ) { if( ret ) { ret = realloc(ret, strlen(ptr->message)+len+3); } else { ret = calloc(1, strlen(ptr->message)+2); } if( !ret ) { fprintf(stderr, "** ERROR ** Could not allocate log retrieval memory buffer\n"); return NULL; } strcat(ret, ptr->message); strcat(ret, "\n"); ptr->read++; len = strlen(ret); } } return ret; } /** * Remove only log records of a particular log level from the log chain. Only * records that have been read (by using log_retrieve()) will be removed unless * the unread argument == 1. * * @param logp Pointer to log chain to work on * @param level Log level to remove * @param unread Set to 1 to also clear unread log entriesz * * @return Returns number of removed elements. */ size_t log_clear_partial(Log_t *logp, int level, int unread) { Log_t *ptr = NULL, *prev = NULL; size_t elmnt = 0; if( !logp ) { return 0; } prev = logp; for( ptr = logp->next; ptr != NULL; ptr = ptr->next ) { if( !ptr ) { break; } // Only remove log entries which is of the expected log level // and that have been read. if( (ptr->level == level) && ((unread == 1) || (ptr->read > 0)) ) { prev->next = ptr->next; if( ptr->message ) { free(ptr->message); ptr->message = NULL; } free(ptr); ptr = prev; elmnt++; } prev = ptr; } return elmnt; } /** * Free all memory used by a Log_t pointer chain. * * @param logp Pointer to log entries to free up. */ void log_close(Log_t *logp) { Log_t *ptr = NULL, *next = NULL; ptr = logp; while( ptr ) { next = ptr->next; ptr->next = NULL; if( ptr->message ) { free(ptr->message); ptr->message = NULL; } free(ptr); ptr = next; } } python-dmidecode-3.10.13/src/dmilog.h0000644002425500234200000000434611401675045016724 0ustar nimaautonomy/* * 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 dmilog.h * @brief A simple log module * @author David Sommerseth */ #ifndef DMILOG_H #define DMILOG_H #include #include /** * Struct defining log records. Organised as a pointer chain. */ struct _Log_t { int level; /**< Log type, based on syslog levels (LOG_ERR|LOG_WARNING) */ char *message; /**< Formated log text */ unsigned int read; /**< Number of times this log entry has been read */ struct _Log_t *next; /**< Next log entry */ }; typedef struct _Log_t Log_t; /** * Log flags. These flags can be OR'ed together */ typedef enum { LOGFL_NORMAL = 1, /**< Normal behaviour, log everything and use stderr on errors */ LOGFL_NODUPS = 2, /**< Don't log messages we already have logged */ LOGFL_NOSTDERR = 4 /**< Don't use stderr even if log functions fails */ } Log_f; Log_t * log_init(); int log_append(Log_t *logp, Log_f flags, int level, const char *fmt, ...); char * log_retrieve(Log_t *logp, int level); size_t log_clear_partial(Log_t *logp, int level, int unread); void log_close(Log_t *logp); #endif python-dmidecode-3.10.13/src/dmioem.c0000644002425500234200000001015511401675045016711 0ustar nimaautonomy /* * Decoding of OEM-specific entries * This file is part of the dmidecode project. * * (C) 2007 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 */ #include #include #include "types.h" #include "dmidecode.h" #include "dmioem.h" /* * Globals for vendor-specific decodes */ enum DMI_VENDORS { VENDOR_UNKNOWN, VENDOR_HP }; static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN; /* * Remember the system vendor for later use. We only actually store the * value if we know how to decode at least one specific entry type for * that vendor. */ void dmi_set_vendor(const char *s) { if(strcmp(s, "HP") == 0) dmi_vendor = VENDOR_HP; } /* * HP-specific data structures are decoded here. * * Code contributed by John Cagle. */ static int dmi_decode_hp(struct dmi_header *h) { 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; 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; } /* * Dispatch vendor-specific entries decoding * Return 1 if decoding was successful, 0 otherwise */ int dmi_decode_oem(struct dmi_header *h) { switch (dmi_vendor) { case VENDOR_HP: return dmi_decode_hp(h); default: return 0; } } python-dmidecode-3.10.13/src/dmioem.h0000644002425500234200000000172211401675045016716 0ustar nimaautonomy /* * Decoding of OEM-specific entries * This file is part of the dmidecode project. * * (C) 2007 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 */ struct dmi_header; void dmi_set_vendor(const char *s); int dmi_decode_oem(struct dmi_header *h); python-dmidecode-3.10.13/src/dmixml.c0000644002425500234200000003271711401675045016741 0ustar nimaautonomy/* 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 * 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 dmixml.c * @brief Helper functions for XML nodes and documents. * @author David Sommerseth * @author Nima Talebi */ #include #include #include #include #include #include #include "dmilog.h" #include "dmixml.h" /** * 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; 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); // Right trim the string ptr = ret + xmlStrlen(ret)-1; while( (ptr >= ret) && (*ptr == ' ') ) { *ptr = 0; ptr--; } return ret; } /** * Add an XML property/attribute to the given XML node * @author David Sommerseth * @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; xmlAttr *res = NULL; va_list ap; if( (node == NULL) || (atrname == NULL) ) { return NULL; } atrname_s = xmlCharStrdup(atrname); assert( atrname_s != NULL ); if( fmt == NULL ) { res = xmlNewProp(node, atrname_s, NULL); goto exit; } va_start(ap, fmt); val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); res = xmlNewProp(node, atrname_s, (xmlStrcmp(val_s, (xmlChar *) "(null)") == 0 ? NULL : val_s)); free(val_s); exit: free(atrname_s); assert( res != NULL ); return res; } /** * 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; xmlNode *res = NULL; va_list ap; if( (node == NULL) || (tagname == NULL) ) { return NULL; } tagname_s = xmlCharStrdup(tagname); assert( tagname_s != NULL ); if( fmt == NULL ) { res = xmlNewChild(node, NULL, tagname_s, NULL); goto exit; } va_start(ap, fmt); val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); // 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(val_s); exit: free(tagname_s); assert( res != NULL ); return res; } /** * 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; xmlNode *res = NULL; va_list ap; if( (node == NULL) || (fmt == NULL) ) { // Return node and not NULL, as node may not be NULL but fmt can be, // thus doing a similar string check (val_s != "(null)") as later on return node; } va_start(ap, fmt); val_s = dmixml_buildstr(2048, fmt, ap); va_end(ap); if( xmlStrcmp(val_s, (xmlChar *) "(null)") != 0 ) { res = xmlAddChild(node, xmlNewText(val_s)); } else { res = node; } free(val_s); assert( res != NULL ); 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; 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; } /** * 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, int casesens) { xmlNode *ptr_n = NULL; xmlChar *tag_s = NULL; int (*compare_func) (const char *, const char *); assert( node != NULL ); if( node->children == NULL ) { return NULL; } 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) && (compare_func(dmixml_GetAttrValue(ptr_n, attrkey), val) == 0 ) ) { goto exit; } } exit: free(tag_s); tag_s = NULL; 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; 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( (ptr_n->type == XML_ELEMENT_NODE) && (xmlStrcmp(ptr_n->name, key_s) == 0) ) { free(key_s); key_s = NULL; return ptr_n; } } free(key_s); key_s = NULL; 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(Log_t *logp, char *buf, size_t buflen, xmlXPathObject *xpo, int idx) { memset(buf, 0, buflen); if( xpo == NULL ) { return NULL; } switch( xpo->type ) { case XPATH_STRING: strncpy(buf, (char *)xpo->stringval, buflen-1); break; case XPATH_NUMBER: snprintf(buf, buflen-1, "%f", xpo->floatval); break; case XPATH_NODESET: if( (xpo->nodesetval != NULL) && (xpo->nodesetval->nodeNr >= (idx+1)) ) { char *str = dmixml_GetContent(xpo->nodesetval->nodeTab[idx]); if( str != NULL ) { strncpy(buf, str, buflen-1); } else { memset(buf, 0, buflen); } } break; default: log_append(logp, LOGFL_NORMAL, LOG_WARNING, "dmixml_GetXPathContent(...):: " "Do not know how to handle XPath type %i", xpo->type); return NULL; } return buf; } python-dmidecode-3.10.13/src/dmixml.h0000644002425500234200000000736411401675045016746 0ustar nimaautonomy/* 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 * (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 _XMLHELPER_H #define _XMLHELPER_H #include #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, ...); char *dmixml_GetAttrValue(xmlNode *node, const char *key); 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); char *dmixml_GetXPathContent(Log_t *logp, char *buf, size_t buflen, xmlXPathObject *xpo, int idx); #endif python-dmidecode-3.10.13/src/efi.c0000644002425500234200000000553111401675045016204 0ustar nimaautonomy/* * 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 "dmilog.h" #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(Log_t *logp, size_t * address) { FILE *efi_systab; const char *filename = NULL; 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); ret = 0; break; } } if(fclose(efi_systab) != 0) perror(filename); if(ret == EFI_NO_SMBIOS) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "%s: SMBIOS entry point missing", filename); } return ret; } python-dmidecode-3.10.13/src/efi.h0000644002425500234200000000262511401675045016212 0ustar nimaautonomy/* * 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(Log_t *logp, size_t * address); #endif python-dmidecode-3.10.13/src/libxml_wrap.h0000644002425500234200000002127511401675045017771 0ustar nimaautonomy/* * 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 #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); python-dmidecode-3.10.13/src/pymap.xml0000644002425500234200000013763311401675045017156 0ustar nimaautonomy python-dmidecode-3.10.13/src/setup-dbg.py0000644002425500234200000000466711401675045017552 0ustar nimaautonomy# # 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 from setup_common import * # # Some default values # incdir = [] libdir = [] libs = [] # Get libxml2 info libxml2_include(incdir) libxml2_lib(libdir, libs) # misc info dmidec_version = get_version() macros = get_macros() # # Python setup # setup( name = "python-dmidecode-dbg", version = dmidec_version, license='GPL-2', description = "Python extension module for dmidecode", 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/pymap.xml']) ], ext_modules = [ Extension( "dmidecodemod", sources = [ "src/dmidecodemodule.c", "src/util.c", "src/dmioem.c", "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", "src/dmilog.c", "src/xmlpythonizer.c", "src/efi.c", "src/dmidump.c" ], include_dirs = incdir, library_dirs = libdir, libraries = libs, undef_macros = [ "NDEBUG" ], define_macros = macros ) ], py_modules = [ "dmidecode-dbg" ] ) python-dmidecode-3.10.13/src/setup.py0000644002425500234200000000461211401675045017006 0ustar nimaautonomy# # 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 setup_common import * # # Some default values # incdir = [] libdir = [] libs = [] # Get libxml2 info libxml2_include(incdir) libxml2_lib(libdir, libs) # misc info dmidec_version = get_version() macros = get_macros() # # Python setup # setup( name = "python-dmidecode", version = dmidec_version, license='GPL-2', description = "Python extension module for dmidecode", 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/pymap.xml']) ], ext_modules = [ Extension( "dmidecodemod", sources = [ "src/dmidecodemodule.c", "src/util.c", "src/dmioem.c", "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", "src/dmilog.c", "src/xmlpythonizer.c", "src/efi.c", "src/dmidump.c" ], include_dirs = incdir, library_dirs = libdir, libraries = libs, undef_macros = [ "NDEBUG" ], define_macros = macros ) ], py_modules = [ "dmidecode" ] ) python-dmidecode-3.10.13/src/setup_common.py0000644002425500234200000000650711401675045020363 0ustar nimaautonomy# # 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 from os import path as os_path from distutils.sysconfig import get_python_lib # 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): 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." 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(): version = "0.0.0" try: f = open("src/version.h") except: f = open("version.h") 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 def get_macros(): "Sets macros which is relevant for all setup*.py files" macros = [] if sys.byteorder == 'big': macros.append(("ALIGNMENT_WORKAROUND", None)) return macros python-dmidecode-3.10.13/src/types.h0000644002425500234200000000530311401675045016607 0ustar nimaautonomy/* * 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 #include "config.h" typedef unsigned char u8; typedef unsigned short u16; typedef signed short i16; typedef unsigned int u32; /* * You may use the following defines to adjust the type definitions * depending on the architecture: * - Define BIGENDIAN on big-endian systems. Untested, as all target * systems to date are little-endian. * - Define ALIGNMENT_WORKAROUND if your system doesn't support * non-aligned memory access. In this case, we use a slower, but safer, * memory access method. This should be done automatically in config.h * for architectures which need it. */ #ifdef BIGENDIAN typedef struct { u32 h; u32 l; } u64; #else typedef struct { 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; } #endif #ifdef ALIGNMENT_WORKAROUND # ifdef BIGENDIAN # define WORD(x) (u16)((x)[1]+((x)[0]<<8)) # define DWORD(x) (u32)((x)[3]+((x)[2]<<8)+((x)[1]<<16)+((x)[0]<<24)) # define QWORD(x) (U64(DWORD(x+4), DWORD(x))) # else /* BIGENDIAN */ # define WORD(x) (u16)((x)[0]+((x)[1]<<8)) # define DWORD(x) (u32)((x)[0]+((x)[1]<<8)+((x)[2]<<16)+((x)[3]<<24)) # define QWORD(x) (U64(DWORD(x), DWORD(x+4))) # endif /* BIGENDIAN */ #else /* ALIGNMENT_WORKAROUND */ #define WORD(x) (u16)(*(const u16 *)(x)) #define DWORD(x) (u32)(*(const u32 *)(x)) #define QWORD(x) (*(const u64 *)(x)) #endif /* ALIGNMENT_WORKAROUND */ #endif python-dmidecode-3.10.13/src/util.c0000644002425500234200000001063211401675045016414 0ustar nimaautonomy /* * Common "util" functions * 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. */ #include #include #include "config.h" #ifdef USE_MMAP #include #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) #endif /* !MAP_FAILED */ #endif /* USE MMAP */ #include #include #include #include #include #include #include "types.h" #include "util.h" #include "dmilog.h" #ifndef USE_MMAP static int myread(Log_t *logp, 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); log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: Unexpected end of file", prefix); return -1; } return 0; } #endif int checksum(const u8 * buf, size_t len) { u8 sum = 0; size_t a; for(a = 0; a < len; a++) sum += buf[a]; return (sum == 0); } /* * Copy a physical memory chunk into a memory buffer. * This function allocates memory. */ void *mem_chunk(Log_t *logp, size_t base, size_t len, const char *devmem) { void *p; int fd; #ifdef USE_MMAP size_t mmoffset; void *mmp; #endif if((fd = open(devmem, O_RDONLY)) == -1) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s: %s", devmem, strerror(errno)); return NULL; } if((p = malloc(len)) == NULL) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "malloc: %s", strerror(errno)); return NULL; } #ifdef USE_MMAP #ifdef _SC_PAGESIZE mmoffset = base % sysconf(_SC_PAGESIZE); #else 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) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (mmap): %s", devmem, strerror(errno)); free(p); return NULL; } memcpy(p, (u8 *) mmp + mmoffset, len); if(munmap(mmp, mmoffset + len) == -1) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (munmap): %s", devmem, strerror(errno)); } #else /* USE_MMAP */ if(lseek(fd, base, SEEK_SET) == -1) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "%s (lseek): %s", devmem, strerror(errno)); free(p); return NULL; } if(myread(logp, fd, p, len, devmem) == -1) { free(p); return NULL; } #endif /* USE_MMAP */ if(close(fd) == -1) perror(devmem); return p; } python-dmidecode-3.10.13/src/util.h0000644002425500234200000000223411401675045016420 0ustar nimaautonomy /* * This file is part of the dmidecode project. * * Copyright (C) 2003-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 */ #include #include "types.h" #include "dmilog.h" #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) int checksum(const u8 * buf, size_t len); void *mem_chunk(Log_t *logp, 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); python-dmidecode-3.10.13/src/version.h0000644002425500234200000000003211401676122017117 0ustar nimaautonomy#define VERSION "3.10.13" python-dmidecode-3.10.13/src/xmlpythonizer.c0000644002425500234200000013400311401675045020372 0ustar nimaautonomy/*. ******* 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 * * 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 xmlpythonizer.c * @brief Generic parser for converting XML documents or XML nodes * into Python Dictionaries * @author David Sommerseth * @author Nima Talebi */ #include #include #include #include #include #include #include #include "util.h" #include "dmixml.h" #include "dmierror.h" #include "dmilog.h" #include "xmlpythonizer.h" #include "version.h" /** * 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, ptzMAP *child) { ptzMAP *ret = NULL; assert( (ktyp == ptzCONST) || (ktyp == ptzSTR) || (ktyp == ptzINT) || (ktyp == ptzFLOAT) ); assert( key != NULL ); ret = (ptzMAP *) malloc(sizeof(ptzMAP)+2); assert( ret != NULL ); memset(ret, 0, sizeof(ptzMAP)+2); if( rootp != NULL ) { ret->rootpath = strdup(rootp); } ret->type_key = ktyp; ret->key = strdup(key); ret->type_value = vtyp; if( value != NULL ) { ret->value = strdup(value); } if( child != NULL ) { ret->child = child; } return ptzmap_AppendMap(chain, ret); }; /** * 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 ) { 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; } } /** * 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 ) { return; } if( ptr->rootpath != NULL ) { free(ptr->rootpath); ptr->rootpath = NULL; } if( ptr->list_index != NULL ) { free(ptr->list_index); ptr->list_index = NULL; } if( ptr->emptyValue != NULL ) { free(ptr->emptyValue); ptr->emptyValue = NULL; } 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 0 // DEBUG FUNCTIONS static const char *ptzTYPESstr[] = { "ptzCONST", "ptzSTR", "ptzINT", "ptzFLOAT", "ptzBOOL", "ptzLIST_STR", "ptzLIST_INT", "ptzLIST_FLOAT", "ptzLIST_BOOL", "ptzDICT", "ptzLIST_DICT", 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; } 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 %s\n", ptr->type_value, ptzTYPESstr[ptr->type_value], ptr->value, (ptr->emptyIsNone ? "(EmptyIsNone)": "")); 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); indent(level); printf(" ** ---------\n"); } if( ptr->next != NULL ) { printf("\n"); ptzmap_Dump_func(ptr->next, level); } } #endif // END OF DEBUG FUNCTIONS /** * 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(Log_t *logp, 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, "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 if( strcmp(str, "list:dict") == 0 ) { return ptzLIST_DICT; } else { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "Unknown field type: %s - defaulting to 'constant'", str); return ptzCONST; } } /** * 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(Log_t *logp, xmlNode *node) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL;; // Go to the next XML_ELEMENT_NODE foreach_xmlnode(node, map_n) { if( map_n->type == XML_ELEMENT_NODE ) { break; } } if( map_n == 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; } } // Loop through it's children foreach_xmlnode(map_n, ptr_n) { 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; } // Get the attributes defining key, keytype, value and valuetype key = dmixml_GetAttrValue(ptr_n, "key"); type_key = _convert_maptype(logp, dmixml_GetAttrValue(ptr_n, "keytype")); value = dmixml_GetAttrValue(ptr_n, "value"); type_value = _convert_maptype(logp, dmixml_GetAttrValue(ptr_n, "valuetype")); 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) || (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, (type_value == ptzLIST_DICT ? value : NULL), _do_dmimap_parsing_typeid(logp, ptr_n->children->next)); } else { 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( (tmpstr = 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 = (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) ) { ptzmap_SetFixedList(retmap, listidx, fixedsize); } value = NULL; key = NULL; } 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; // 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 )) { 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 ) { PyReturnError(PyExc_RuntimeError, "Unsupported XML-Python mapping file format. " "Only version 1 is supported"); } return rootnode; } /** * 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(Log_t *logp, xmlNode *mapnode, const char *typeid) { xmlNode *node = NULL; assert( mapnode != NULL); // Find the tag with our type ID node = dmixml_FindNodeByAttr_NoCase(mapnode, "TypeMap", "id", typeid); if( node == NULL ) { // No exception handling possible here, as we don't return PyObject log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** WARNING: Could not find any XML->Python " "mapping for type ID '%s'", typeid); return NULL; } // Create an internal map structure and return this structure return _do_dmimap_parsing_typeid(logp, node); } /** * 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(Log_t *logp, xmlDoc *xmlmap, int typeid) { xmlNode *node = NULL; char typeid_s[16]; node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { PyReturnError(PyExc_RuntimeError, "Could not locate root XML node for mapping file"); } 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(logp, node, typeid_s); } /** * 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(Log_t *logp, xmlNode *node, xmlDoc *xmlmap) { ptzMAP *retmap = NULL; xmlNode *ptr_n = NULL, *map_n = NULL, *typemap = NULL; char *type_id; // Go to the next XML_ELEMENT_NODE foreach_xmlnode(node, map_n) { if( map_n->type == XML_ELEMENT_NODE ) { break; } } if( map_n == 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 ) { PyReturnError(PyExc_NameError, "Expected to find node"); } // Go to the first node map_n = dmixml_FindNode(node, "TypeMap"); if( map_n == 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"); if( typemap == NULL ) { PyReturnError(PyExc_NameError, "Could not locate the node"); } // Loop through it's children foreach_xmlnode(map_n, ptr_n) { // 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(logp, typemap, type_id); if( map ) { retmap = ptzmap_AppendMap(retmap, map); } } } return retmap; } /** * 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(Log_t *logp, xmlDoc *xmlmap, const char *mapname) { xmlNode *node = NULL; // Validate the XML mapping document and get the root element node = dmiMAP_GetRootElement(xmlmap); if( node == NULL ) { PyReturnError(PyExc_RuntimeError, "No valid mapping XML received"); } // Find the section node = dmixml_FindNode(node, "GroupMapping"); 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 ) { 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 return _do_dmimap_parsing_group(logp, node, xmlmap); } /** * 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(Log_t *logp, ptzMAP *val_m, const char *instr) { PyObject *value; const char *workstr = NULL; if( instr == NULL ) { return Py_None; } if( (val_m->emptyIsNone == 1) || (val_m->emptyValue != NULL) ) { char *cp = strdup(instr); 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); if( val_m->emptyIsNone == 1 ) { return Py_None; } if( val_m->emptyValue != NULL ) { workstr = (const char *)val_m->emptyValue; } } else { free(cp); } } if( workstr == NULL ) { workstr = instr; } switch( val_m->type_value ) { case ptzINT: case ptzLIST_INT: value = PyInt_FromLong(atoi(workstr)); break; case ptzFLOAT: case ptzLIST_FLOAT: value = PyFloat_FromDouble(atof(workstr)); break; case ptzBOOL: case ptzLIST_BOOL: value = PyBool_FromLong((atoi(workstr) == 1 ? 1:0)); break; case ptzSTR: case ptzLIST_STR: value = PyString_FromString(workstr); break; default: log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Invalid type '%i' for value '%s'", val_m->type_value, instr); value = Py_None; } return value; } /** * 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; if( xpath == NULL ) { return NULL; } xp_xpr = xmlCharStrdup(xpath); xp_obj = xmlXPathEvalExpression(xp_xpr, xpctx); assert( xp_obj != NULL ); free(xp_xpr); 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(Log_t *logp, 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: strncpy(key, map_p->key, buflen-1); break; case ptzSTR: case ptzINT: case ptzFLOAT: xpobj = _get_xpath_values(xpctx, map_p->key); if( xpobj == NULL ) { return NULL; } if( dmixml_GetXPathContent(logp, key, buflen, xpobj, idx) == NULL ) { xmlXPathFreeObject(xpobj); return NULL; } xmlXPathFreeObject(xpobj); break; default: log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown key type: %i", map_p->type_key); return NULL; } // We consider to have a key, if the first byte is a readable // character (usually starting at 0x20/32d) return ((key != NULL) && (strlen(key) > 0) ? key : NULL) ; } /** * 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); \ if( v != Py_None ) { \ 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(Log_t *logp, 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: if( value->nodesetval == NULL ) { break; } if( value->nodesetval->nodeNr == 0 ) { if( _get_key_value(logp, 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(logp, key, 256, map_p, xpctx, i) != NULL ) { dmixml_GetXPathContent(logp, val, 4097, value, i); PyADD_DICT_VALUE(pydat, key, StringToPyObj(logp, map_p, val)); } } } break; default: if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { dmixml_GetXPathContent(logp, val, 4097, value, 0); PyADD_DICT_VALUE(pydat, key, StringToPyObj(logp, map_p, val)); } break; } free(key); free(val); } /** * 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(Log_t *logp, 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 ); xmlDocSetRootElement(xpdoc, xmlCopyNode(data_n, 1)); xpctx = xmlXPathNewContext(xpdoc); assert( xpctx != NULL ); xpctx->node = data_n; key = (char *) malloc(258); assert( key != NULL ); // Extract value switch( map_p->type_value ) { case ptzCONST: if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { value = PyString_FromString(map_p->value); PyADD_DICT_VALUE(retdata, key, value); } else { PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); } break; case ptzSTR: case ptzINT: case ptzFLOAT: case ptzBOOL: xpo = _get_xpath_values(xpctx, map_p->value); if( xpo != NULL ) { _add_xpath_result(logp, 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(logp, key, 256, map_p, xpctx, 0) != NULL ) { if( (xpo->nodesetval != NULL) && (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(logp, valstr, 4097, xpo, i); // 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(logp, map_p, valstr) ); } } else { // No list index - append the value PyList_Append(value,StringToPyObj(logp,map_p,valstr)); } free(valstr); } } else { value = Py_None; } PyADD_DICT_VALUE(retdata, key, value); xmlXPathFreeObject(xpo); } else { PyReturnError(PyExc_ValueError, "Could not get key value: " "%s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); } } break; case ptzDICT: // Traverse children nodes if( map_p->child == NULL ) { break; } if( _get_key_value(logp, key, 256, map_p, xpctx, 0) == NULL ) { 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(logp, map_p->child, data_n); 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(logp, key, 256, map_p, xpctx, 0) == NULL ) { 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) ) { if( xpo != NULL ) { xmlXPathFreeObject(xpo); } PyReturnError(PyExc_ValueError, "Could not get key value: %s [%i] (Defining key: %s)", map_p->rootpath, elmtid, map_p->key); } // 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(logp, 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); } } else { // If NULL, something is wrong - exception is already set. return NULL; } } PyADD_DICT_VALUE(retdata, key, value); xmlXPathFreeObject(xpo); break; default: log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Unknown value type: %i", map_p->type_value); break; } free(key); xmlXPathFreeContext(xpctx); xmlFreeDoc(xpdoc); return retdata; } /** * 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(Log_t *logp, 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) ) { PyReturnError(PyExc_RuntimeError, "pythonXMLnode() - xmlNode or ptzMAP is NULL"); } key = (char *) malloc(258); if( key == NULL ) { PyReturnError(PyExc_MemoryError, "Could not allocate temporary buffer"); } // Loop through all configured elements retdata = PyDict_New(); foreach_xmlnode(in_map, map_p) { 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); 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) ) { for( i = 0; i < xpo->nodesetval->nodeNr; i++ ) { xpctx->node = xpo->nodesetval->nodeTab[i]; if( _get_key_value(logp, key, 256, map_p, xpctx, 0) != NULL ) { PyObject *res = _deep_pythonize(logp, 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; } } } xmlXPathFreeContext(xpctx); xmlFreeDoc(xpdoc); } #ifdef DEBUG else { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "** pythonizeXMLnode :: Could not locate node for key value: " "root path '%s', key '%s'", map_p->rootpath, map_p->key); } #endif if( xpo != NULL ) { xmlXPathFreeObject(xpo); xpo = NULL; } } else { PyObject *res = _deep_pythonize(logp, 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); return retdata; } /** * 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(Log_t *logp, ptzMAP *map, xmlDoc *doc) { xmlNode *node = NULL; node = xmlDocGetRootElement(doc); return pythonizeXMLnode(logp, map, node); } #if 0 // Simple independent main function - only for debugging int main(int argc, char **argv) { xmlDoc *doc = NULL, *data = NULL; ptzMAP *map = NULL; PyObject *pydat = NULL; Py_Initialize(); doc = xmlReadFile("pymap.xml", NULL, 0); assert( doc != NULL ); map = dmiMAP_ParseMappingXML_GroupName(doc, argv[1]); // map = dmiMAP_ParseMappingXML_TypeID(doc, atoi(rgv[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); Py_DECREF(pydat); printf("\n\n"); ptzmap_Free(map); xmlFreeDoc(data); 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, "bios"); assert( mapping != NULL ); // Read XML data from file doc = xmlReadFile("cpu.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(VERSION); Py_INCREF(version); PyModule_AddObject(module, "version", version); } #endif // Python test module python-dmidecode-3.10.13/src/xmlpythonizer.h0000644002425500234200000000572211401675045020404 0ustar nimaautonomy/* 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, ptzBOOL, ptzLIST_STR, ptzLIST_INT, ptzLIST_FLOAT, ptzLIST_BOOL, ptzDICT, ptzLIST_DICT } 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; 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 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 == (ptzDICT || ptzLIST_DICT) struct ptzMAP_s *next; // Pointer chain } ptzMAP; xmlNode *dmiMAP_GetRootElement(xmlDoc *mapdoc); ptzMAP *dmiMAP_ParseMappingXML_TypeID(Log_t *logp, xmlDoc *xmlmap, int typeid); ptzMAP *dmiMAP_ParseMappingXML_GroupName(Log_t *logp, xmlDoc *xmlmap, const char *mapname); #define ptzmap_Free(ptr) { ptzmap_Free_func(ptr); ptr = NULL; } void ptzmap_Free_func(ptzMAP *ptr); PyObject *pythonizeXMLdoc(Log_t *logp, ptzMAP *map, xmlDoc *xmldoc); PyObject *pythonizeXMLnode(Log_t *logp, ptzMAP *map, xmlNode *nodes); #endif // _XMLPYTHONIZER_H python-dmidecode-3.10.13/src/dmidecode.c0000644002425500234200000057053511401675117017371 0ustar nimaautonomy /*. ******* 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 * * 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/. * * Note to contributors: * Please reference every value you add or modify, especially if the * information does not come from the above mentioned specification. * * Additional references: * - Intel AP-485 revision 32 * "Intel Processor Identification and the CPUID Instruction" * http://developer.intel.com/design/xeon/applnots/241618.htm * - DMTF Common Information Model * CIM Schema version 2.19.1 * http://www.dmtf.org/standards/cim/ * - IPMI 2.0 revision 1.0 * "Intelligent Platform Management Interface Specification" * http://developer.intel.com/design/servers/ipmi/spec.htm * - AMD publication #25481 revision 2.28 * "CPUID Specification" * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf * - BIOS Integrity Services Application Programming Interface version 1.0 * http://www.intel.com/design/archives/wfm/downloads/bisspec.htm * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #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" #include "efi.h" #include "dmidump.h" #include "dmihelper.h" /******************************************************************************* ** Type-independant Stuff */ 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 NULL; /* ASCII filtering */ len = strlen(bp); for(i = 0; i < len; i++) if(bp[i] < 32 || bp[i] == 127) bp[i] = '.'; return bp; } xmlNode *dmi_smbios_structure_type(xmlNode *node, u8 code) { 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( (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) { if(value > 0x99 || (value & 0x0F) > 0x09) return 0; if(value < low || value > high) return 0; return 1; } 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; 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++) { 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; } 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; 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++) { * for(j=0; j<16 && j> 10); } } /* 3.3.1.1 */ void dmi_bios_characteristics(xmlNode *node, 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 */ }; dmixml_AddAttribute(node, "dmispec", "3.3.1.1"); dmixml_AddAttribute(node, "flags", "0x%04x", code); if(code.l&(1<<3)) { dmixml_AddAttribute(node, "unavailable", "1"); dmixml_AddTextContent(node, characteristics[0]); } else { int i = 0; xmlNode *flags_n = xmlNewChild(node, NULL, (xmlChar *) "flags", NULL); assert( flags_n != NULL ); 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 )); } } } /* 3.3.1.2.1 */ void dmi_bios_characteristics_x1(xmlNode *node, u8 code) { int i = 0; static const char *characteristics[] = { "ACPI", /* 0 */ "USB legacy", "AGP", "I2O boot", "LS-120 boot", "ATAPI Zip drive boot", "IEEE 1394 boot", "Smart battery" /* 7 */ }; dmixml_AddAttribute(node, "dmispec", "3.3.1.2.1"); dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 7; i++) { xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]); dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0)); } } /* 3.3.1.2.2 */ 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 */ }; dmixml_AddAttribute(node, "dmispec", "3.3.1.2.2"); dmixml_AddAttribute(node, "flags", "0x%04x", code); for(i = 0; i <= 2; i++) { xmlNode *chr_n = dmixml_AddTextChild(node, "characteristic", characteristics[i]); dmixml_AddAttribute(chr_n, "enabled", "%i", (code & (1 << i) ? 1: 0)); } } /******************************************************************************* ** 3.3.2 System Information (Type 1) */ 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) only0x00 = 0; if(p[i] != 0xFF) only0xFF = 0; } 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){ 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 * 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) { 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 */ void dmi_system_wake_up_type(xmlNode *node, u8 code) { static const char *type[] = { "Reserved", /* 0x00 */ "Other", "Unknown", "APM Timer", "Modem Ring", "LAN Remote", "Power Switch", "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) { dmixml_AddTextContent(swut_n, type[code]); } else { dmixml_AddAttribute(swut_n, "outofspec", "1"); } } /******************************************************************************* ** 3.3.3 Base Board Information (Type 2) */ /* 3.3.3.1 */ void dmi_base_board_features(xmlNode *node, 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 */ }; 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) { int i; for(i = 0; i <= 4; i++) { if(code & (1 << i)) { dmixml_AddTextChild(feat_n, "feature", features[i]); } } } else { dmixml_AddAttribute(feat_n, "unavailable", "1"); } } void dmi_base_board_type(xmlNode *node, const char *tagname, u8 code) { /* 3.3.3.2 */ static const char *type[] = { "Unknown", /* 0x01 */ "Other", "Server Blade", "Connectivity Switch", "System Management Module", "Processor Module", "I/O Module", "Memory Module", "Daughter Board", "Motherboard", "Processor+Memory Module", "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) { dmixml_AddTextContent(type_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(type_n, "unavailable", "1"); } } void dmi_base_board_handles(xmlNode *node, u8 count, const u8 * p) { int i; xmlNode *dict_n = NULL; dict_n = xmlNewChild(node, NULL, (xmlChar *) "ContainedObjectHandles", NULL); assert( dict_n != NULL ); dmixml_AddAttribute(dict_n, "count", "%i", count); 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)); } } /******************************************************************************* ** 3.3.4 Chassis Information (Type 3) */ /* 3.3.4.1 */ void dmi_chassis_type(xmlNode *node, 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 */ }; 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"); } } void dmi_chassis_lock(xmlNode *node, u8 code) { static const char *lock[] = { "Not Present", /* 0x00 */ "Present" /* 0x01 */ }; 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 */ void dmi_chassis_state(xmlNode *node, const char *tagname, u8 code) { static const char *state[] = { "Other", /* 0x01 */ "Unknown", "Safe", /* master.mif says OK */ "Warning", "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) { dmixml_AddTextContent(state_n, "%s", state[code - 0x01]); } else { dmixml_AddAttribute(state_n, "unavailable", "1"); } } /* 3.3.4.3 */ void dmi_chassis_security_status(xmlNode *node, u8 code) { static const char *status[] = { "Other", /* 0x01 */ "Unknown", "None", "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) { dmixml_AddTextContent(secstat_n, "%s", status[code - 0x01]); } else { dmixml_AddAttribute(secstat_n, "unavailable", "1"); } } void dmi_chassis_height(xmlNode *node, u8 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); } } void dmi_chassis_power_cords(xmlNode *node, u8 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); } } 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 ); dmixml_AddAttribute(data_n, "count", "%i", count); for(i = 0; i < count; i++) { if(len >= 0x03) { xmlNode *key_n = NULL; 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 ); 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]); } } } } /******************************************************************************* ** 3.3.5 Processor Information (Type 4) */ void dmi_processor_type(xmlNode *node, u8 code) { /* 3.3.5.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Central Processor", "Math Processor", "DSP Processor", "Video Processor" /* 0x06 */ }; xmlNode *proct_n = xmlNewChild(node, NULL, (xmlChar *) "Type", NULL); assert( proct_n != NULL ); 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"); } } void dmi_processor_family(xmlNode *node, 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]; 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) { 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 */ low = 0; high = ARRAY_SIZE(family2) - 1; while(1) { i = (low + high) / 2; 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; } dmixml_AddAttribute(family_n, "outofspec", "1"); } xmlNode *dmi_processor_id(xmlNode *node, u8 type, const u8 * p, const char *version) { /* Intel AP-485 revision 31, table 3-4 */ static struct _cpuflags { const char *flag; const char *descr; } flags[] = { /* *INDENT-OFF* */ {"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", "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", "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* */ }; xmlNode *flags_n = NULL; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "CPUCore", NULL); assert( data_n != NULL ); /* ** 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. */ 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); /* ** 80386 have a different signature. */ 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 */ 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 { 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 */ ||(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(version && (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_n; } } else { /* not X86-class */ return data_n; } eax = DWORD(p); edx = DWORD(p + 4); switch (sig) { case 1: /* Intel */ 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 */ 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); flags_n = xmlNewChild(data_n, NULL, (xmlChar *) "cpu_flags", NULL); if((edx & 0xFFEFFBFF) != 0) { int i; for(i = 0; i <= 31; 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); } } } return data_n; } /* 3.3.5.4 */ void dmi_processor_voltage(xmlNode *node, u8 code) { static const char *voltage[] = { "5.0", /* 0 */ "3.3", "2.9" /* 2 */ }; int i; 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) { 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 { for(i = 0; i <= 2; i++) { 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; } } } int dmi_processor_frequency(const u8 * p) { u16 code = WORD(p); if(code) return code; //. Value measured in MHz else return -1; //. Unknown } void dmi_processor_status(xmlNode *node, u8 code) { static const char *status[] = { "Unknown", /* 0x00 */ "Enabled", "Disabled By User", "Disabled By BIOS", "Idle", /* 0x04 */ "Other" /* 0x07 */ }; xmlNode *prst_n = xmlNewChild(node, NULL, (xmlChar *) "Populated", NULL); assert( prst_n != NULL ); 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"); } } void dmi_processor_upgrade(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(upgr_n, "%s", upgrade[code - 0x01]); } else { dmixml_AddAttribute(upgr_n, "outofspec", "1"); } } void dmi_processor_cache(xmlNode *cache_n, u16 code, u16 ver) { assert( cache_n != NULL ); 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"); } else { dmixml_AddAttribute(cache_n, "available", "0"); } } else { dmixml_AddAttribute(cache_n, "provided", "1"); dmixml_AddAttribute(cache_n, "available", "1"); dmixml_AddAttribute(cache_n, "handle", "0x%04x", code); } } /* 3.3.5.9 */ void dmi_processor_characteristics(xmlNode *node, u16 code) { static const char *characteristics[] = { "Unknown", /* 1 */ "64-bit capable" /* 2 */ }; 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) { int i; for(i = 1; i <= 2; i++) { if(code & (1 << i)) { dmixml_AddTextChild(data_n, "Flag", "%s", characteristics[i - 1]); } } } } /******************************************************************************* ** 3.3.6 Memory Controller Information (Type 5) */ void dmi_memory_controller_ed_method(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(ercm_n, method[code - 0x01]); } else { dmixml_AddAttribute(ercm_n, "outofspec", "1"); } } /* 3.3.6.2 */ void dmi_memory_controller_ec_capabilities(xmlNode *node, const char *tagname, u8 code) { static const char *capabilities[] = { "Other", /* 0 */ "Unknown", "None", "Single-bit Error Correcting", "Double-bit Error Correcting", "Error Scrubbing" /* 5 */ }; 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) { int i; 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+1); } } } } void dmi_memory_controller_interleave(xmlNode *node, const char *tagname, 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 */ }; 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) { dmixml_AddTextContent(mci_n, interleave[code - 0x01]); } else { dmixml_AddAttribute(mci_n, "outofspec", "1"); } } /* 3.3.6.4 */ void dmi_memory_controller_speeds(xmlNode *node, u16 code) { 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); if((code & 0x001F) == 0) { int i; 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; } } } } 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 ); for(i = 0; i < count; i++) { xmlNode *sl_n = dmixml_AddTextChild(mslts_n, "Slot", "0x%x:", WORD(p + sizeof(u16) * i)); dmixml_AddAttribute(sl_n, "index", "%i", i); } } /******************************************************************************* ** 3.3.7 Memory Module Information (Type 6) */ /* 3.3.7.1 */ void dmi_memory_module_types(xmlNode *node, const char *tagname, u16 code) { static const char *types[] = { "Other", /* 0 */ "Unknown", "Standard", "FPM", "EDO", "Parity", "ECC", "SIMM", "DIMM", "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); if((code & 0x07FF) != 0) { int i; 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+1); } } } } void dmi_memory_module_connections(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BankConnections", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code != 0xFF) { if((code & 0xF0) != 0xF0) { dmixml_AddTextChild(data_n, "Connection", "%ld", (code >> 4)); } if((code & 0x0F) != 0x0F) { dmixml_AddTextChild(data_n, "Connection", "%ld", (code & 0x0F)); } } } void dmi_memory_module_speed(xmlNode *node, const char *tagname, u8 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 */ void dmi_memory_module_size(xmlNode *node, const char *tagname, u8 code) { 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: dmixml_AddAttribute(data_n, "Error", "Size not determinable"); break; case 0x7E: dmixml_AddAttribute(data_n, "Error", "Disabled"); break; case 0x7F: dmixml_AddAttribute(data_n, "installed", "0"); check_conn = 0; default: dmixml_AddAttribute(data_n, "installed", "1"); dmixml_AddAttribute(data_n, "unit", "MB"); dmixml_AddTextContent(data_n, "%i", 1 << (code & 0x7F)); } if(check_conn) { dmixml_AddAttribute(data_n, "Connection", ((code & 0x80) ? "Double-bank" : "Single-bank")); } } void dmi_memory_module_error(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ModuleErrorStatus", NULL); assert( data_n != NULL ); 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"); } } } /******************************************************************************* ** 3.3.8 Cache Information (Type 7) */ static const char *dmi_cache_mode(u8 code) { static const char *mode[] = { "Write Through", /* 0x00 */ "Write Back", "Varies With Memory Address", "Unknown" /* 0x03 */ }; return mode[code]; } void dmi_cache_location(xmlNode *node, u8 code) { static const char *location[4] = { "Internal", /* 0x00 */ "External", NULL, /* 0x02 */ "Unknown" /* 0x03 */ }; 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) { dmixml_AddTextContent(data_n, location[code]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_cache_size(xmlNode *node, const char *tagname, u16 code) { 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); 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 */ void dmi_cache_types(xmlNode *node, const char *tagname, u16 code) { static const char *types[] = { "Other", /* 0 */ "Unknown", "Non-burst", "Burst", "Pipeline Burst", "Synchronous", "Asynchronous" /* 6 */ }; 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); if((code & 0x007F) != 0) { int i; for(i = 0; i <= 6; i++) { if(code & (1 << i)) { xmlNode *n = dmixml_AddTextChild(data_n, "CacheType", "%s", types[i]); dmixml_AddAttribute(n, "index", "%i", i+1); } } } } void dmi_cache_ec_type(xmlNode *node, u8 code) { /* 3.3.8.3 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "None", "Parity", "Single-bit ECC", "Multi-bit ECC" /* 0x06 */ }; 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) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_cache_type(xmlNode *node, u8 code) { /* 3.3.8.4 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Instruction", "Data", "Unified" /* 0x05 */ }; 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) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_cache_associativity(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } /******************************************************************************* ** 3.3.9 Port Connector Information (Type 8) */ void dmi_port_connector_type(xmlNode *node, const char *tpref, 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 */ }; 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"); } } void dmi_port_type(xmlNode *node, 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 */ }; 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) */ void dmi_slot_type(xmlNode *node, 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 */ }; 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"); } } void dmi_slot_bus_width(xmlNode *node, 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 */ }; 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) ) { dmixml_AddTextContent(data_n, "%s", width[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_slot_current_usage(xmlNode *node, u8 code) { /* 3.3.10.3 */ static const char *usage[] = { "Other", /* 0x01 */ "Unknown", "Available", "In Use" /* 0x04 */ }; 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 */ void dmi_slot_length(xmlNode *node, u8 code) { static const char *length[] = { "Other", /* 0x01 */ "Unknown", "Short", "Long" /* 0x04 */ }; 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 */ 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) { 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(slotid_n, "id", "%i", code1); break; case 0x05: /* EISA */ dmixml_AddAttribute(slotid_n, "id", "%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 */ dmixml_AddAttribute(slotid_n, "id", "%i", code1); break; case 0x07: /* PCMCIA */ 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) { /* 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 */ }; 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; for(i = 1; i <= 7; i++) { 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)) { xmlNode *c_n = dmixml_AddTextChild(data_n, "Characteristic", "%s", characteristics2[i]); dmixml_AddAttribute(c_n, "index", "%i", i+8); c_n = NULL; } } } } void dmi_slot_segment_bus_func(xmlNode *node, u16 code1, u8 code2, u8 code3) { /* 3.3.10.8 */ 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)) { dmixml_AddTextContent(data_n, "%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7); } } /******************************************************************************* ** 3.3.11 On Board Devices Information (Type 10) */ void dmi_on_board_devices_type(xmlNode *node, 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 */ }; 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"); } } void dmi_on_board_devices(xmlNode *node, const char *tagname, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = (h->length - 0x04) / 2; int i; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "dmispec", "3.3.11"); for(i = 0; i < count; i++) { xmlNode *dev_n = xmlNewChild(data_n, NULL, (xmlChar *) "Device", NULL); assert( dev_n != NULL ); 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; } } /******************************************************************************* * 3.3.12 OEM Strings (Type 11) */ void dmi_oem_strings(xmlNode *node, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int i; dmixml_AddAttribute(node, "count", "%i", count); for(i = 1; i <= count; i++) { xmlNode *str_n = dmixml_AddTextChild(node, "Record", "%s", dmi_string(h, i)); assert( str_n != NULL ); dmixml_AddAttribute(str_n, "index", "%i", i); } } /******************************************************************************* ** 3.3.13 System Configuration Options (Type 12) */ void dmi_system_configuration_options(xmlNode *node, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int i; 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++) { xmlNode *o_n = dmixml_AddTextChild(data_n, "Option", "%s", dmi_string(h, i)); assert( o_n != NULL ); dmixml_AddAttribute(o_n, "index", "%ld", i); } } /******************************************************************************* ** 3.3.14 BIOS Language Information (Type 13) */ void dmi_bios_languages(xmlNode *node, struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int 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); for(i = 1; i <= count; 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); } } /******************************************************************************* ** 3.3.15 Group Associations (Type 14) */ void dmi_group_associations_items(xmlNode *node, u8 count, const u8 * p) { dmixml_AddAttribute(node, "dmispec", "3.3.15"); dmixml_AddAttribute(node, "items", "%i", count); int i; for(i = 0; i < count; i++) { 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]); } } /******************************************************************************* ** 3.3.16 System Event Log (Type 15) */ 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 */ "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 */ }; 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"); } } void dmi_event_log_status(xmlNode *node, u8 code) { static const char *valid[] = { "Invalid", /* 0 */ "Valid" /* 1 */ }; static const char *full[] = { "Not Full", /* 0 */ "Full" /* 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]); } 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: dmixml_AddAttribute(data_n, "Index", "0x%04x", WORD(p)); dmixml_AddAttribute(data_n, "Data", "0x%04x", WORD(p + 2)); break; case 0x03: dmixml_AddAttribute(data_n, "Data", "0x%08x", DWORD(p)); break; case 0x04: dmixml_AddAttribute(data_n, "Data", "0x%04x", WORD(p)); break; default: dmixml_AddAttribute(data_n, "unknown", "1"); } } void dmi_event_log_header_type(xmlNode *node, u8 code) { static const char *type[] = { "No Header", /* 0x00 */ "Type 1" /* 0x01 */ }; 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"); } } void dmi_event_log_descriptor_type(xmlNode *node, 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 */ }; 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"); } } void dmi_event_log_descriptor_format(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, format[code]); } else if(code >= 0x80) { dmixml_AddTextContent(data_n, "OEM-specific"); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_event_log_descriptors(xmlNode *node, u8 count, const u8 len, const u8 * p) { /* 3.3.16.1 */ int i; dmixml_AddAttribute(node, "dmispec", "3.3.16.1"); for(i = 0; i < count; i++) { if(len >= 0x02) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "LogType", NULL); assert( data_n != NULL ); dmi_event_log_descriptor_type(data_n, p[i * len]); dmi_event_log_descriptor_format(data_n, p[i * len + 1]); } } } /******************************************************************************* ** 3.3.17 Physical Memory Array (Type 16) */ void dmi_memory_array_location(xmlNode *node, 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 */ }; 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"); } } void dmi_memory_array_use(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, use[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_array_ec_type(xmlNode *node, u8 code) { /* 3.3.17.3 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "None", "Parity", "Single-bit ECC", "Multi-bit ECC", "CRC" /* 0x07 */ }; 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"); } } void dmi_memory_array_capacity(xmlNode *node, u32 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxCapacity", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", 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); } } } void dmi_memory_array_error_handle(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "ErrorInfoHandle", NULL); assert( data_n != NULL ); 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) */ void dmi_memory_device_width(xmlNode *node, const char *tagname, u16 code) { /* ** If no memory module is present, width may be 0 */ xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); if(code == 0xFFFF || code == 0) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "unit", "bit"); dmixml_AddTextContent(data_n, "%i", code); } } void dmi_memory_device_size(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Size", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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... dmixml_AddAttribute(data_n, "unit", "%s", (code & 0x8000 ? "KB" : "MB")); dmixml_AddTextContent(data_n, "%d", (code & 0x8000 ? code & 0x7FFF : code)); } } void dmi_memory_device_form_factor(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", form_factor[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_device_set(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Set", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0xFF) { dmixml_AddAttribute(data_n, "outofspec", "1"); } else if( code > 0 ) { dmixml_AddTextContent(data_n, "%ld", code); } } void dmi_memory_device_type(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_device_type_detail(xmlNode *node, 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 */ }; 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); if((code & 0x1FFE) != 0) { int i; 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); } } } } void dmi_memory_device_speed(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Speed", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "speed_ns", "%.1f", (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) */ void dmi_memory_error_type(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_error_granularity(xmlNode *node, u8 code) { /* 3.3.19.2 */ static const char *granularity[] = { "Other", /* 0x01 */ "Unknown", "Device Level", "Memory Partition Level" /* 0x04 */ }; 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) { dmixml_AddTextContent(data_n, "%s", granularity[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_error_operation(xmlNode *node, u8 code) { /* 3.3.19.3 */ static const char *operation[] = { "Other", /* 0x01 */ "Unknown", "Read", "Write", "Partial Write" /* 0x05 */ }; 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) { dmixml_AddTextContent(data_n, "%s", operation[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_error_syndrome(xmlNode *node, u32 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "VendorSyndrome", NULL); assert( data_n != NULL ); if(code == 0x00000000) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddTextContent(data_n, "0x%08x", code); } } void dmi_32bit_memory_error_address(xmlNode *node, char *tagname, u32 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); 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) */ void dmi_mapped_address_size(xmlNode *node, u32 code) { 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) { 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) */ void dmi_mapped_address_row_position(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "PartitionRowPosition", NULL); assert( data_n != NULL ); 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); } } void dmi_mapped_address_interleave_position(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterleavePosition", NULL); assert( data_n != NULL ); if( code <= 0xFE ) { dmixml_AddTextContent(data_n, "%i", code); } else { dmixml_AddAttribute(data_n, "unknown", "1"); } } void dmi_mapped_address_interleaved_data_depth(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "InterleaveDataDepth", NULL); assert( data_n != NULL ); 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) */ void dmi_pointing_device_type(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_pointing_device_interface(xmlNode *node, 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 */ }; 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) { 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) */ void dmi_battery_chemistry(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", chemistry[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_battery_capacity(xmlNode *node, u16 code, u8 multiplier) { 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) { dmixml_AddAttribute(data_n, "unit", "mWh"); dmixml_AddTextContent(data_n, "%i", code * multiplier); } } void dmi_battery_voltage(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "DesignVoltage", NULL); assert( data_n != NULL ); if(code == 0) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "unit", "mV"); dmixml_AddTextContent(data_n, "%i", code); } } void dmi_battery_maximum_error(xmlNode *node, u8 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaximumError", NULL); assert( data_n != NULL ); if(code == 0xFF) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddTextContent(data_n, "%i%%", code); } } /******************************************************************************* ** 3.3.24 System Reset (Type 23) */ 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 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if( (code > 0) && (code < 4) ) { dmixml_AddTextContent(data_n, option[code - 0x1]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_system_reset_count(xmlNode *node, const char *tagname, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0xFFFF) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddTextContent(data_n, "%ld", code); } } void dmi_system_reset_timer(xmlNode *node, const char *tagname, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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) */ void dmi_hardware_security_status(xmlNode *node, const char *tagname, u8 code) { static const char *status[] = { "Disabled", /* 0x00 */ "Enabled", "Not Implemented", "Unknown" /* 0x03 */ }; 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) */ #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 */ 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) */ void dmi_voltage_probe_location(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", location[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_probe_status(xmlNode *node, u8 code) { /* 3.3.27.1 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", "OK", "Non-critical", "Critical", "Non-recoverable" /* 0x06 */ }; 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) { dmixml_AddTextContent(data_n, "%s", status[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_voltage_probe_value(xmlNode *node, const char *tagname, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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); } } void dmi_voltage_probe_resolution(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", 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) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Accuracy", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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) */ void dmi_cooling_device_type(xmlNode *node, 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 */ }; 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) { 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"); } } void dmi_cooling_device_speed(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "NominalSpeed", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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) */ void dmi_temperature_probe_location(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", location[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_temperature_probe_value(xmlNode *node, const char *tagname, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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); } } void dmi_temperature_probe_resolution(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0x8000) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "unit", "C"); dmixml_AddTextContent(data_n, "%.3f", (float)code / 1000); } } /******************************************************************************* ** 3.3.30 Electrical Current Probe (Type 29) */ void dmi_current_probe_value(xmlNode *node, const char *tagname, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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); } } void dmi_current_probe_resolution(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Resolution", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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) */ void dmi_system_boot_status(xmlNode *node, 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 */ }; 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) */ void dmi_64bit_memory_error_address(xmlNode *node, const char *tagname, u64 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) tagname, NULL); assert( data_n != NULL ); 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) */ void dmi_management_device_type(xmlNode *node, 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 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_management_device_address_type(xmlNode *node, u8 code) { /* 3.3.35.2 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "I/O Port", "Memory", "SMBus" /* 0x05 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } /******************************************************************************* ** 3.3.38 Memory Channel (Type 37) */ void dmi_memory_channel_type(xmlNode *node, u8 code) { /* 3.3.38.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "RamBus", "SyncLink" /* 0x04 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_memory_channel_devices(xmlNode *node, u8 count, const u8 * p) { int i; for(i = 1; i <= count; i++) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "Device", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "Load", "%i", p[3 * i]); dmixml_AddAttribute(data_n, "Handle", "0x%04x", WORD(p + 3 * i + 1)); } } /******************************************************************************* ** 3.3.39 IPMI Device Information (Type 38) */ 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[] = { "Unknown", /* 0x00 */ "KCS (Keyboard Control Style)", "SMIC (Server Management Interface Chip)", "BT (Block Transfer)", "SSIF (SMBus System Interface)" /* 0x04 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_ipmi_base_address(xmlNode *node, u8 type, const u8 * p, u8 lsb) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "BaseAddress", NULL); assert( data_n != NULL ); if(type == 0x04) { /* SSIF */ dmixml_AddAttribute(data_n, "interface", "SMBus-SSIF"); dmixml_AddTextContent(data_n, "0x%02x", (*p) >> 1); } else { u64 address = QWORD(p); 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); } } void dmi_ipmi_register_spacing(xmlNode *node, 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 */ }; xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "RegisterSpacing", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); 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) */ void dmi_power_supply_power(xmlNode *node, u16 code) { xmlNode *data_n = xmlNewChild(node, NULL, (xmlChar *) "MaxPowerCapacity", NULL); assert( data_n != NULL ); dmixml_AddAttribute(data_n, "flags", "0x%04x", code); if(code == 0x8000) { dmixml_AddAttribute(data_n, "unknown", "1"); } else { dmixml_AddAttribute(data_n, "unit", "W"); dmixml_AddTextContent(data_n, "%.3f", (float)code / 1000); } } void dmi_power_supply_type(xmlNode *node, u8 code) { /* 3.3.40.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Linear", "Switching", "Battery", "UPS", "Converter", "Regulator" /* 0x08 */ }; 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) { dmixml_AddTextContent(data_n, "%s", type[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_power_supply_status(xmlNode *node, u8 code) { /* 3.3.40.1 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", "OK", "Non-critical", "Critical" /* 0x05 */ }; 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) { dmixml_AddTextContent(data_n, "%s", status[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } void dmi_power_supply_range_switching(xmlNode *node, u8 code) { /* 3.3.40.1 */ static const char *switching[] = { "Other", /* 0x01 */ "Unknown", "Manual", "Auto-switch", "Wide Range", "N/A" /* 0x06 */ }; 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) { dmixml_AddTextContent(data_n, "%s", switching[code - 0x01]); } else { dmixml_AddAttribute(data_n, "outofspec", "1"); } } /* ** 3.3.41 Additional Information (Type 40) ** ** Proper support of this entry type would require redesigning a large part of ** the code, so I am waiting to see actual implementations of it to decide ** whether it's worth the effort. */ 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; assert( node != NULL ); for(i = 0; i < count; i++) { xmlNode *data_n = NULL, *str_n = NULL, *val_n = NULL; /* Check for short entries */ if(h->length < offset + 1) { break; } length = p[0x00]; if(length < 0x05 || h->length < offset + length) break; data_n = xmlNewChild(node, NULL, (xmlChar *) "Record", NULL); assert( data_n != NULL ); 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]); str_n = dmixml_AddTextChild(data_n, "String", "%s", dmi_string(h, p[0x04])); switch (length - 0x05) { case 1: dmixml_AddTextChild(data_n, "Value", "0x%02x", p[0x05]); break; case 2: dmixml_AddTextChild(data_n, "Value", "0x%04x", WORD(p + 0x05)); break; case 4: dmixml_AddTextChild(data_n, "Value", "0x%08x", DWORD(p + 0x05)); break; default: val_n = xmlNewChild(data_n, NULL, (xmlChar *) "Value", NULL); dmixml_AddAttribute(val_n, "unexpected_size", "1"); break; } p += length; offset += length; } } /******************************************************************************* ** Main */ 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; sect_n = xmlNewChild(prnt_n, NULL, (xmlChar *) dmiMajor->tagname, NULL); assert( sect_n != NULL ); dmixml_AddAttribute(sect_n, "dmispec", "%s", dmiMajor->id); dmixml_AddAttribute(sect_n, "type", "%i", h->type); dmixml_AddTextChild(sect_n, "DMIdescription", "%s", dmiMajor->desc); switch (h->type) { case 0: /* 3.3.1 BIOS Information */ if(h->length < 0x12) { break; } 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 * there is no BIOS. Skip the base address and the * runtime size in this case. */ if(WORD(data + 0x06) != 0) { dmixml_AddTextChild(sect_n, "Address", "0x%04x0", WORD(data + 0x06)); dmi_bios_runtime_size(sect_n, (0x10000 - WORD(data + 0x06)) << 4); } 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 ); dmixml_AddAttribute(sub_n, "level", "0"); dmi_bios_characteristics(sub_n, QWORD(data + 0x0A)); sub_n = NULL; if(h->length < 0x13) { 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) { break; } 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) { dmixml_AddTextChild(sect_n, "BIOSrevision", "%i.%i", data[0x14], data[0x15]); } if(data[0x16] != 0xFF && data[0x17] != 0xFF) { dmixml_AddTextChild(sect_n, "FirmwareRevision", "%i.%i", data[0x16], data[0x17]); } break; case 1: /* 3.3.2 System Information */ if(h->length < 0x08) { 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) { break; } dmi_system_uuid(sect_n, data + 0x08, ver); dmi_system_wake_up_type(sect_n, data[0x18]); if(h->length < 0x1B) { break; } dmixml_AddTextChild(sect_n, "SKUnumber", "%s", dmi_string(h, data[0x19])); dmixml_AddTextChild(sect_n, "Family", "%s", dmi_string(h, data[0x1A])); break; case 2: /* 3.3.3 Base Board Information */ if(h->length < 0x08) { 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) { break; } dmixml_AddTextChild(sect_n, "AssetTag", "%s", dmi_string(h, data[0x08])); dmi_base_board_features(sect_n, data[0x09]); dmixml_AddTextChild(sect_n, "ChassisLocation", "%s", dmi_string(h, data[0x0A])); dmixml_AddTextChild(sect_n, "ChassisHandle", "0x%04x", WORD(data + 0x0B)); dmi_base_board_type(sect_n, "Type", data[0x0D]); if(h->length < 0x0F + data[0x0E] * sizeof(u16)) { break; } dmi_base_board_handles(sect_n, data[0x0E], data + 0x0F); break; case 3: /* 3.3.4 Chassis Information */ if(h->length < 0x09) { break; } 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; } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ChassisStates", NULL); assert( sub_n != NULL ); 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) { break; } dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x0D)); if(h->length < 0x13) { break; } dmi_chassis_height(sect_n, data[0x11]); dmi_chassis_power_cords(sect_n, data[0x12]); if((h->length < 0x15) || (h->length < 0x15 + data[0x13] * data[0x14])){ break; } dmi_chassis_elements(sect_n, data[0x13], data[0x14], data + 0x15); break; case 4: /* 3.3.5 Processor Information */ if(h->length < 0x1A) { 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); dmi_processor_id(sect_n, data[0x06], data + 8, dmi_string(h, data[0x10])); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Manufacturer", NULL); assert( sub_n != NULL ); dmixml_AddTextChild(sub_n, "Vendor", dmi_string(h, data[0x07])); dmixml_AddTextChild(sub_n, "Version", dmi_string(h, data[0x10])); sub_n = NULL; dmi_processor_voltage(sect_n, data[0x11]); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Frequencies", NULL); assert( sub_n != NULL ); 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: * * 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)) { dmixml_AddAttribute(sect_n, "populated", "1"); dmi_processor_status(sect_n, data[0x18] & 0x07); } else { dmixml_AddAttribute(sect_n, "populated", "0"); dmixml_AddTextChild(sect_n, "Populated", "No"); } dmi_processor_upgrade(sect_n, data[0x19]); if(h->length < 0x20) { break; } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Cache", NULL); assert( sub_n != NULL ); 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; } 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( sub_n != NULL ); if(data[0x23] != 0) { dmixml_AddTextChild(sub_n, "CoreCount", "%i", data[0x23]); } if(data[0x24] != 0) { dmixml_AddTextChild(sub_n, "CoresEnabled", "%i", data[0x24]); } if(data[0x25] != 0) { dmixml_AddTextChild(sub_n, "ThreadCount", "%i", data[0x25]); } dmi_processor_characteristics(sub_n, WORD(data + 0x26)); sub_n = NULL; break; case 5: /* 3.3.6 Memory Controller Information */ if(h->length < 0x0F) { break; } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "ErrorCorrection", NULL); assert( sub_n != NULL ); dmi_memory_controller_ed_method(sub_n, data[0x04]); dmi_memory_controller_ec_capabilities(sub_n, "Capabilities", data[0x05]); sub_n = NULL; dmi_memory_controller_interleave(sect_n, "SupportedInterleave", data[0x06]); dmi_memory_controller_interleave(sect_n, "CurrentInterleave", data[0x07]); sub_n = dmixml_AddTextChild(sect_n, "MaxMemoryModuleSize", "%i", (1 << data[0x08])); dmixml_AddAttribute(sub_n, "unit", "MB"); sub_n = NULL; sub_n = dmixml_AddTextChild(sect_n, "MaxTotalMemorySize", "%i", data[0x0E] * (1 << data[0x08])); dmixml_AddAttribute(sub_n, "unit", "MB"); sub_n = NULL; 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; } dmi_memory_controller_slots(sect_n, data[0x0E], data + 0x0F); if(h->length < 0x10 + data[0x0E] * sizeof(u16)) { break; } dmi_memory_controller_ec_capabilities(sect_n, "EnabledErrorCorrection", data[0x0F + data[0x0E] * sizeof(u16)]); break; case 6: /* 3.3.7 Memory Module Information */ if(h->length < 0x0C) { break; } 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)); 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]); break; case 7: /* 3.3.8 Cache Information */ if(h->length < 0x0F) { break; } 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)); 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)); dmi_cache_size(sect_n, "MaximumSize", WORD(data + 0x07)); dmi_cache_types(sect_n, "SupportedSRAMtypes", WORD(data + 0x0B)); dmi_cache_types(sect_n, "InstalledSRAMtypes", WORD(data + 0x0D)); if(h->length < 0x13) { break; } 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]); break; case 8: /* 3.3.9 Port Connector Information */ if(h->length < 0x09) { break; } 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; dmi_port_connector_type(sect_n, "internal", data[0x05]); 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; dmi_port_connector_type(sect_n, "external", data[0x07]); dmi_port_type(sect_n, data[0x08]); break; case 9: /* 3.3.10 System Slots */ if(h->length < 0x0C) { break; } dmixml_AddTextChild(sect_n, "Designation", "%s", dmi_string(h, data[0x04])); 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]); if( h->length < 0x0D ) { dmi_slot_characteristics(sect_n, data[0x0B], 0x00); } else { dmi_slot_characteristics(sect_n, data[0x0B], data[0x0C]); } break; case 10: /* 3.3.11 On Board Devices Information */ dmi_on_board_devices(sect_n, "dmi_on_board_devices", h); break; case 11: /* 3.3.12 OEM Strings */ if(h->length < 0x05) { break; } dmi_oem_strings(sect_n, h); break; case 12: /* 3.3.13 System Configuration Options */ if(h->length < 0x05) { break; } dmi_system_configuration_options(sect_n, h); break; case 13: /* 3.3.14 BIOS Language Information */ if(h->length < 0x16) { break; } dmixml_AddAttribute(sect_n, "installable_languages", "%i", data[0x04]); dmi_bios_languages(sect_n, h); break; case 14: /* 3.3.15 Group Associations */ if(h->length < 0x05) { 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; break; case 15: /* 3.3.16 System Event Log */ // SysEventLog - sect_n if(h->length < 0x14) { break; } dmi_event_log_status(sect_n, data[0x0B]); // SysEventLog/Access - sub sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Access", NULL); assert( sub_n != NULL ); 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); // SysEventLog/Access/Header - sub2 sub2_n = xmlNewChild(sub_n, NULL, (xmlChar *) "Header", NULL); assert( sub2_n != NULL ); dmixml_AddTextChild(sub2_n, "OffsetStart", "0x%04x", WORD(data + 0x06)); if((WORD(data + 0x08) - WORD(data + 0x06)) >= 0) { dmixml_AddTextChild(sub2_n, "Length", "%i", WORD(data + 0x08) - WORD(data + 0x06)); } 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; } // 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; } 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; break; case 16: /* 3.3.17 Physical Memory Array */ if(h->length < 0x0F) { break; } 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)); break; case 17: /* 3.3.18 Memory Device */ if(h->length < 0x15) { break; } dmixml_AddAttribute(sect_n, "ArrayHandle", "0x%04x", WORD(data + 0x04)); dmi_memory_array_error_handle(sect_n, WORD(data + 0x06)); 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])); dmi_memory_device_type(sect_n, data[0x12]); dmi_memory_device_type_detail(sect_n, WORD(data + 0x13)); if(h->length < 0x17) { break; } dmi_memory_device_speed(sect_n, WORD(data + 0x15)); if(h->length < 0x1B) { break; } 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])); break; case 18: /* 3.3.19 32-bit Memory Error Information */ case 33: /* 3.3.34 64-bit Memory Error Information */ if( h->type == 18 ) { dmixml_AddAttribute(sect_n, "bits", "32"); } else { dmixml_AddAttribute(sect_n, "bits", "64"); } if( ((h->type == 18) && (h->length < 0x17)) /* 32-bit */ || ((h->type == 33) && (h->length < 0x1F)) ) /* 64-bit */ { break; } 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)); } break; case 19: /* 3.3.20 Memory Array Mapped Address */ if(h->length < 0x0F) { break; } 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]); break; case 20: /* 3.3.21 Memory Device Mapped Address */ if(h->length < 0x13) { break; } 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, "PhysicalDeviceHandle", "0x%04x", WORD(data + 0x0C)); dmixml_AddTextChild(sect_n, "MemArrayMappedAddrHandle", "0x%04x", WORD(data + 0x0E)); dmi_mapped_address_row_position(sect_n, data[0x10]); dmi_mapped_address_interleave_position(sect_n, data[0x11]); dmi_mapped_address_interleaved_data_depth(sect_n, data[0x12]); break; case 21: /* 3.3.22 Built-in Pointing Device */ if(h->length < 0x07) { break; } dmi_pointing_device_type(sect_n, data[0x04]); dmi_pointing_device_interface(sect_n, data[0x05]); dmixml_AddTextChild(sect_n, "Buttons", "%i", data[0x06]); break; case 22: /* 3.3.23 Portable Battery */ if(h->length < 0x10) { break; } 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) { dmixml_AddTextChild(sect_n, "ManufactureDate", "%s", dmi_string(h, data[0x06])); } if(data[0x07] || h->length < 0x1A) { dmixml_AddTextChild(sect_n, "SerialNumber", "%s", dmi_string(h, data[0x07])); } dmixml_AddTextChild(sect_n, "Name", "%s", dmi_string(h, data[0x08])); if(data[0x09] != 0x02 || 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) { break; } if(data[0x07] == 0) { dmixml_AddTextChild(sect_n, "SBDSserialNumber", "%04x", WORD(data + 0x10)); } if(data[0x06] == 0) { 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) { dmixml_AddTextChild(sect_n, "SBDSchemistry", "%s", dmi_string(h, data[0x14])); } dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x16)); break; case 23: /* 3.3.24 System Reset */ if(h->length < 0x0D) { break; } 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; 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; if(!(data[0x04] & (1 << 5))) { break; } dmi_system_reset_boot_option(sect_n, "BootOption", (data[0x04] >> 1) & 0x3); dmi_system_reset_boot_option(sect_n, "BootOptionOnLimit", (data[0x04] >> 3) & 0x3); dmi_system_reset_count(sect_n, "ResetCount", WORD(data + 0x05)); dmi_system_reset_count(sect_n, "ResetLimit", WORD(data + 0x07)); dmi_system_reset_timer(sect_n, "TimerInterval", WORD(data + 0x09)); dmi_system_reset_timer(sect_n, "Timeout", WORD(data + 0x0B)); break; case 24: /* 3.3.25 Hardware Security */ if(h->length < 0x05) { break; } 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); break; case 25: /* 3.3.26 System Power Controls */ if(h->length < 0x09) { break; } dmi_power_controls_power_on(sect_n, "NextSchedPowerOn", data + 0x04); break; case 26: /* 3.3.27 Voltage Probe */ dmixml_AddAttribute(sect_n, "probetype", "Voltage"); if(h->length < 0x14) { break; } dmixml_AddTextChild(sect_n, "Description", "%s", dmi_string(h, data[0x04])); dmi_voltage_probe_location(sect_n, data[0x05] & 0x1f); dmi_probe_status(sect_n, data[0x05] >> 5); 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)); dmi_probe_accuracy(sect_n, WORD(data + 0x0E)); dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); if(h->length < 0x16) { break; } dmi_voltage_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); break; case 27: /* 3.3.28 Cooling Device */ if(h->length < 0x0C) { break; } if(WORD(data + 0x04) != 0xFFFF) { dmixml_AddTextContent(sect_n, "TemperatureProbeHandle", "0x%04x", WORD(data + 0x04)); } dmi_cooling_device_type(sect_n, data[0x06] & 0x1f); dmi_probe_status(sect_n, data[0x06] >> 5); if(data[0x07] != 0x00) { dmixml_AddTextChild(sect_n, "UnitGroup", "%i", data[0x07]); } dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x08)); if(h->length < 0x0E) { break; } dmi_cooling_device_speed(sect_n, WORD(data + 0x0C)); break; case 28: /* 3.3.29 Temperature Probe */ dmixml_AddAttribute(sect_n, "probetype", "Temperature"); if(h->length < 0x14) { break; } 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); 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)); dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); if(h->length < 0x16) { break; } dmi_temperature_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); break; case 29: /* 3.3.30 Electrical Current Probe */ dmixml_AddAttribute(sect_n, "probetype", "Electrical Current"); if(h->length < 0x14) { break; } 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); 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)); dmi_probe_accuracy(sect_n, WORD(data + 0x0E)); dmixml_AddTextChild(sect_n, "OEMinformation", "0x%08x", DWORD(data + 0x10)); if(h->length < 0x16) { break; } dmi_current_probe_value(sect_n, "NominalValue", WORD(data + 0x14)); break; case 30: /* 3.3.31 Out-of-band Remote Access */ if(h->length < 0x06) { 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); break; case 31: /* 3.3.32 Boot Integrity Services Entry Point */ dmixml_AddAttribute(sect_n, "NOT_IMPLEMENTED", "1"); break; case 32: /* 3.3.33 System Boot Information */ if(h->length < 0x0B) { break; } dmi_system_boot_status(sect_n, data[0x0A]); break; case 34: /* 3.3.35 Management Device */ dmixml_AddAttribute(sect_n, "mgmtype", ""); if(h->length < 0x0B) { break; } 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]); break; case 35: /* 3.3.36 Management Device Component */ dmixml_AddAttribute(sect_n, "mgmtype", "Component"); if(h->length < 0x0B) { break; } 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) { dmixml_AddTextChild(sect_n, "ThresholdHandle", "0x%04x", WORD(data + 0x09)); } break; case 36: /* 3.3.37 Management Device Threshold Data */ dmixml_AddAttribute(sect_n, "mgmtype", "Threshold Data"); if(h->length < 0x10) { 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) { dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x04)); } if(WORD(data + 0x06) != 0x8000) { 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) { dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x08)); } if(WORD(data + 0x0A) != 0x8000) { 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) { dmixml_AddAttribute(sub_n, "Lower", "%d", (i16) WORD(data + 0x0C)); } if(WORD(data + 0x0E) != 0x8000) { dmixml_AddAttribute(sub_n, "Upper", "%d", (i16) WORD(data + 0x0E)); } sub_n = NULL; break; case 37: /* 3.3.38 Memory Channel */ if(h->length < 0x07) { break; } dmi_memory_channel_type(sect_n, data[0x04]); dmixml_AddTextChild(sect_n, "MaxLoad", "%i", data[0x05]); 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]) { sub_n = NULL; break; } dmi_memory_channel_devices(sub_n, data[0x06], data + 0x07); sub_n = NULL; 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; } dmi_ipmi_interface_type(sect_n, data[0x04]); dmixml_AddAttribute(sect_n, "spec_version", "%i.%i", data[0x05] >> 4, data[0x05] & 0x0F); dmixml_AddAttribute(sect_n, "I2CslaveAddr", "0x%02x", data[0x06] >> 1); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "NVstorageDevice", NULL); assert( sub_n != NULL ); if(data[0x07] != 0xFF) { dmixml_AddAttribute(sub_n, "Address", "%i", data[0x07]); } else { dmixml_AddAttribute(sub_n, "NotPresent", "1"); } sub_n = NULL; dmi_ipmi_base_address(sect_n, data[0x04], data + 0x08, h->length < 0x12 ? 0 : (data[0x10] >> 5) & 1); if(h->length < 0x12) { break; } sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Interrupt", NULL); assert( sub_n != NULL ); if(data[0x04] != 0x04) { dmi_ipmi_register_spacing(sect_n, data[0x10] >> 6); if(data[0x10] & (1 << 3)) { 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) { dmixml_AddTextChild(sub_n, "InterruptNumber", "%x", data[0x11]); } sub_n = NULL; break; case 39: /* 3.3.40 System Power Supply */ if(h->length < 0x10) { break; } if(data[0x04] != 0x00) { dmixml_AddAttribute(sect_n, "UnitGroup", "%i", data[0x04]); } 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])); dmi_power_supply_power(sect_n, WORD(data + 0x0C)); if(WORD(data + 0x0E) & (1 << 1)) { dmi_power_supply_status(sect_n, (WORD(data + 0x0E) >> 7) & 0x07); } else { sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Status", NULL); assert( sub_n != NULL ); dmixml_AddAttribute(sub_n, "present", "0"); sub_n = NULL; } dmi_power_supply_type(sect_n, (WORD(data + 0x0E) >> 10) & 0x0F); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "Input", NULL); assert( sub_n != NULL ); dmi_power_supply_range_switching(sub_n, (WORD(data + 0x0E) >> 3) & 0x0F); 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) { sub_n = NULL; break; } if(WORD(data + 0x10) != 0xFFFF) { dmixml_AddTextChild(sub_n, "ProbeHandle", "0x%04x", WORD(data + 0x10)); } if(WORD(data + 0x12) != 0xFFFF) { dmixml_AddTextChild(sect_n, "CoolingDeviceHandle", "0x%04x", WORD(data + 0x12)); } if(WORD(data + 0x14) != 0xFFFF) { dmixml_AddTextChild(sub_n, "CurrentProbeHandle", "0x%04x", WORD(data + 0x14)); } sub_n = NULL; break; case 40: /* 3.3.41 Additional Information */ dmixml_AddAttribute(sect_n, "subtype", "AdditionalInformation"); dmixml_AddAttribute(sect_n, "dmispec", "3.3.41"); if(h->length < 0x0B) { break; } dmi_additional_info(sect_n, h); break; case 41: /* 3.3.42 Onboard Device Extended Information */ dmixml_AddAttribute(sect_n, "subtype", "OnboardDeviceExtendedInformation"); dmixml_AddAttribute(sect_n, "dmispec", "3.3.42"); if(h->length < 0x0B) { break; } dmixml_AddTextChild(sect_n, "ReferenceDesignation", "%s", dmi_string(h, data[0x04])); sub_n = xmlNewChild(sect_n, NULL, (xmlChar *) "OnboardDevice", NULL); dmi_on_board_devices_type(sub_n, data[0x05] & 0x7F); 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; break; case 126: /* 3.3.43 Inactive */ case 127: /* 3.3.44 End Of Table */ break; default: if(dmi_decode_oem(h)) break; 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); break; } return sect_n; } 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; } 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(Log_t *logp, 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; 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)) * dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base); */ dmixml_AddAttribute(info_n, "dmi_table_base", "0x%08x", base); info_n = NULL; } if((buf = mem_chunk(logp, base, len, devmem)) == NULL) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Table is unreachable, sorry." #ifndef USE_MMAP "Try compiling dmidecode with -DUSE_MMAP." #endif ); return; } data = buf; while(i < num && data + 4 <= buf + len) { /* 4 is the length of an SMBIOS structure header */ u8 *next; struct dmi_header h; to_dmi_header(&h, data); /* ** 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) { log_append(logp, LOGFL_NORMAL, LOG_WARNING, "Invalid entry length (%i) for type %i. DMI table is broken! Stop.", (unsigned int)h.length, type); break; } /* In quiet mode (FLAG_QUIET - removed for python-dmidecode all together), * stop decoding at end of table marker */ /* 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; 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)); * } */ 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 %i bytes on type 0x%02X", (next - buf - len), h.type); dmixml_AddAttribute(handle_n, "type", "%i", h.type); dmixml_AddAttribute(handle_n, "truncated", "1"); dmixml_AddAttribute(handle_n, "length", "%i", (next - buf)); dmixml_AddAttribute(handle_n, "expected_length", "%i", len); log_append(logp, LOGFL_NODUPS, LOG_WARNING, "DMI/SMBIOS type 0x%02X is exceeding the expected buffer " "size by %i bytes. Will not decode this entry.", h.type, (next - buf - len)); } 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) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures count: %d announced, only %d decoded.", num, i); } if(data - buf != len) { log_append(logp, LOGFL_NODUPS, LOG_WARNING, "Wrong DMI structures length: %d bytes announced, structures occupy %d bytes.", 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; } xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem) { int check = _smbios_decode_check(buf); 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]; /* 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) { 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); } } else if(check == 0) { dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); dmixml_AddAttribute(data_n, "unknown", "1"); } return data_n; } int smbios_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) { 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(logp, type, DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver, devmem, xmlnode); } return check; } int _legacy_decode_check(u8 * buf) { int check; if(!checksum(buf, 0x0F)) check = 0; //. Bad else check = 1; //. Good return check; } xmlNode *legacy_decode_get_version(u8 * buf, const char *devmem) { int check = _legacy_decode_check(buf); 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); dmixml_AddAttribute(data_n, "version", "%i.%i", buf[0x0E] >> 4, buf[0x0E] & 0x0F); } else if(check == 0) { dmixml_AddTextContent(data_n, "No SMBIOS nor DMI entry point found"); dmixml_AddAttribute(data_n, "unknown", "1"); } return data_n; } int legacy_decode(Log_t *logp, int type, u8 *buf, const char *devmem, xmlNode *xmlnode) { int check = _legacy_decode_check(buf); if(check == 1) dmi_table(logp, type, DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F), devmem, xmlnode); return check; } python-dmidecode-3.10.13/unit-tests/0000755002425500234200000000000011401675045016621 5ustar nimaautonomypython-dmidecode-3.10.13/unit-tests/Makefile0000644002425500234200000000007411401675045020262 0ustar nimaautonomytest : python unit -vv clean : rm -f *.{py[oc],o,so} *~ python-dmidecode-3.10.13/unit-tests/private/0000755002425500234200000000000011401675045020273 5ustar nimaautonomypython-dmidecode-3.10.13/unit-tests/private/DellPrecisionWorkStation-490.dmp0000644002425500234200000000751711401675045026262 0ustar nimaautonomy_SM__DMI_/ f#Aڲ 8XXYYuuvvSڲ 8 00!1qڲ 8 00@@!!11AA"2B##33CCڡڲ 8%%55EE&&66FF''77GG((88HH))99II**::JJ)<Dell Inc. A0505/24/2007DELLLVXO13JDell Inc. Precision WorkStation 490 BLVX13JDell Inc. 0GU083A00..CN1374076601D8. Dell Inc. BLVX13J (*@AMicroprocessorIntel(dMicroprocessorIntel   PARALLEL  SERIAL1  SERIAL2  KYBD MOUSE USB1 USB2 USB3 USB4 USB5 USB6 USB7 USB8  ENET MIC LINE-OUT LINE-IN HP-OUT   SLOT1   SLOT2   SLOT3  SLOT4  SLOT5  SLOT6 ~   ~    Broadcom 5752 NetXtreme Gigabit Controller  Intel(R) High Definition Audio Controller  www.dell.com  en|US|iso8859-1H@DIMM 1 80CE808980CE100F93AAM395T2953EZ4-CE65 010726H@DIMM 2 80CE808980CE100F937DM395T2953EZ4-CE65 010726H@DIMM 3 FFFFFFFFFFFFFFFFFFFF FFFFFFH@DIMM 4 FFFFFFFFFFFFFFFFFFFF FFFFFFH@DIMM 5 FFFFFFFFFFFFFFFFFFFF FFFFFFH@DIMM 6 FFFFFFFFFFFFFFFFFFFF FFFFFFH@DIMM 7 FFFFFFFFFFFFFFFFFFFF FFFFFFH@DIMM 8 FFFFFFFFFFFFFFFFFFFF FFFFFF~~~~~~f g NCPU0 Voltage~gNCPU1 VoltagegN+VTT~gReservedg+VCC c c c c~ c~ cc CPU0~c CPU1 ZZ  x  pq-.BC%%%%%%%% ## # # # # #0 #@#A#B"""" %?&&&&&T#U#\x@]xx x{{7 7gpq@Ym-Y.YnY'Y(Y?)Y?@*Y?+Z,[UYmYYYUUUUU#U"UX@XUUQ?Q?@Q?Q?@TATBTCTJTKTLSMShViV@upq-.-!.! ''''@"">"@?"D"E"@7!8!9!N(O( ԓpq@YmRRRRRRRR @R@R @R @R R R@!R"RY YqArAsAtAAA@@AA@A 0@!1A"2B#3C$4D 0!1python-dmidecode-3.10.13/unit-tests/private/IBM-x3950-M2.0.dmidump0000644002425500234200000001175711401675045023476 0ustar nimaautonomy_SM_ q_DMI_ T$IBM-[A3E148AUS-1.07]-11/05/2008@!hd5pIBMIBM 3850 M2 / x3950 M2 -[71413RM]-99A3888 _ :BCDEFGHIJKLMtIBMNode1 Processor CardNode1, Bottom Front_ :+,-./01cIBMNode1 PCI I/O PlanarNode1, Rear Center:rstuvwxyIBMNode1 Memory Card1Node1, Rear Left 1st From Top:z{|}~IBMNode1 Memory Card2Node1, Rear Left 2nd From Top:IBMNode1 Memory Card3Node1, Rear Left 3rd From Top:IBMNode1 Memory Card4Node1, Rear Left 4th From Top :IBM C@Internal L2 CacheF@Internal L2 CacheI@Internal L2 CacheL@Internal L2 Cache(` ABCDNode 1 CPU 3GenuineIntelIntel Xeon MP (` AEFGNode 1 CPU 1GenuineIntelIntel Xeon MP (` AHIJNode 1 CPU 2GenuineIntelIntel Xeon MP (` AKLMNode 1 CPU 4GenuineIntelIntel Xeon MP  Scalability 1 Scalability 2 Scalability 3  10/100/1000 Ethernet (port A)  10/100/1000 Ethernet (port B) USB 1 USB 2 USB 3 Video Diskette/CDROM Internal SAS SCSI External SAS SCSI  Serial-A / System Management  RSA Ethernet Scalability 1 Scalability 2 Scalability 3 + Node1 PCI-Express Slot 1 , Node1 PCI-Express Slot 2 - Node1 PCI-Express Slot 3 . Node1 PCI-Express Slot 4 / Node1 PCI-Express Slot 5 0 Node1 PCI-Express Slot 6 1 Node1 PCI-Express Slot 7 kIBM Preboot Diagnostics (DSA) 1.00.55 -[A3YT55AUS-1.00.55]-IBM CRTM Code 1.00 -[A3CP08AUS-1.00]-IBM Backup CRTM Code 1.00 -[A3CP08AUS-1.00]-IBM BaseBoard Management Controller -[A3BT50A ]-IBM Remote Supervisor Adapter -[A3EP26AUS]-IBM Processor Card FPGA Version 001.013IBM PCI I/O Planar FPGA Version 001.004 lJ33-Power on Password Override jumperChanging the position of this jumper bypasses thepower-on password checking on the next power-on. You do not need to move the jumper back to the default position after the password is overridden. Changing the position of this jumper does not affect the administrator password check if an administrator password is set. mJ17-Flash ROM page swap jumperPrimary-on pins 1-2, Backup-on pins 2-3The Primary(default) position is a jumper installed on pins marked by a white block under the pins.Changing the position of this jumper will change which of the two pages of flash ROM is used when the system is started. nJ16- Force Power On JumperPin 1-2 Force Power On disabledPin 2-3 Force Power On enabled oJ21- BMC Disable JumperPin 1-2 BMC EnabledPin 2-3 BMC Disabled pen|US|iso8859-1q  rqH@ DIMM1Node1/Bank1/MemCard1sqH@ DIMM5Node1/Bank1/MemCard1tqH@ DIMM2Node1/Bank2/MemCard1uqH@ DIMM6Node1/Bank2/MemCard1vqH@ DIMM3Node1/Bank3/MemCard1wqH@ DIMM7Node1/Bank3/MemCard1xqH@ DIMM4Node1/Bank4/MemCard1yqH@ DIMM8Node1/Bank4/MemCard1zqH@ DIMM1Node1/Bank5/MemCard2{qH@ DIMM5Node1/Bank5/MemCard2|qH@ DIMM2Node1/Bank6/MemCard2}qH@ DIMM6Node1/Bank6/MemCard2~qH@ DIMM3Node1/Bank7/MemCard2qH@ DIMM7Node1/Bank7/MemCard2qH@ DIMM4Node1/Bank8/MemCard2qH@ DIMM8Node1/Bank8/MemCard2qH@ DIMM1Node1/Bank9/MemCard3qH@ DIMM5Node1/Bank9/MemCard3qH@ DIMM2Node1/Bank10/MemCard3qH@ DIMM6Node1/Bank10/MemCard3qH@ DIMM3Node1/Bank11/MemCard3qH@ DIMM7Node1/Bank11/MemCard3qH@ DIMM4Node1/Bank12/MemCard3qH@ DIMM8Node1/Bank12/MemCard3qH@ DIMM1Node1/Bank13/MemCard4qH@ DIMM5Node1/Bank13/MemCard4qH@ DIMM2Node1/Bank14/MemCard4qH@ DIMM6Node1/Bank14/MemCard4qH@ DIMM3Node1/Bank15/MemCard4qH@ DIMM7Node1/Bank15/MemCard4qH@ DIMM4Node1/Bank16/MemCard4qH@ DIMM8Node1/Bank16/MemCard4rq s&t @|python-dmidecode-3.10.13/unit-tests/private/IBM-x3950-M2.1.dmidump0000644002425500234200000001175711401675045023477 0ustar nimaautonomy_SM_ q_DMI_ T$#IBM-[A3E129AUS-1.03]-03/05/2008@J}hd5\IBMIBM 3850 M2 / x3950 M2 -[71413RM]-99A3896 _ :BCDEFGHIJKLMtIBMNode1 Processor CardNode1, Bottom Front_ :+,-./01cIBMNode1 PCI I/O PlanarNode1, Rear Center:rstuvwxyIBMNode1 Memory Card1Node1, Rear Left 1st From Top:z{|}~IBMNode1 Memory Card2Node1, Rear Left 2nd From Top:IBMNode1 Memory Card3Node1, Rear Left 3rd From Top:IBMNode1 Memory Card4Node1, Rear Left 4th From Top :IBM C@Internal L2 CacheF@Internal L2 CacheI@Internal L2 CacheL@Internal L2 Cache(` ABCDNode 1 CPU 3GenuineIntelIntel Xeon MP (` AEFGNode 1 CPU 1GenuineIntelIntel Xeon MP (` AHIJNode 1 CPU 2GenuineIntelIntel Xeon MP (` AKLMNode 1 CPU 4GenuineIntelIntel Xeon MP  Scalability 1 Scalability 2 Scalability 3  10/100/1000 Ethernet (port A)  10/100/1000 Ethernet (port B) USB 1 USB 2 USB 3 Video Diskette/CDROM Internal SAS SCSI External SAS SCSI  Serial-A / System Management  RSA Ethernet Scalability 1 Scalability 2 Scalability 3 + Node1 PCI-Express Slot 1 , Node1 PCI-Express Slot 2 - Node1 PCI-Express Slot 3 . Node1 PCI-Express Slot 4 / Node1 PCI-Express Slot 5 0 Node1 PCI-Express Slot 6 1 Node1 PCI-Express Slot 7 kIBM Preboot Diagnostics (DSA) 1.00.55 -[A3YT55AUS-1.00.55]-IBM CRTM Code 1.00 -[A3CP08AUS-1.00]-IBM Backup CRTM Code 1.00 -[A3CP08AUS-1.00]-IBM BaseBoard Management Controller -[A3BT31A ]-IBM Remote Supervisor Adapter -[A3EP20AUS]-IBM Processor Card FPGA Version 001.006IBM PCI I/O Planar FPGA Version 001.004 lJ33-Power on Password Override jumperChanging the position of this jumper bypasses thepower-on password checking on the next power-on. You do not need to move the jumper back to the default position after the password is overridden. Changing the position of this jumper does not affect the administrator password check if an administrator password is set. mJ17-Flash ROM page swap jumperPrimary-on pins 1-2, Backup-on pins 2-3The Primary(default) position is a jumper installed on pins marked by a white block under the pins.Changing the position of this jumper will change which of the two pages of flash ROM is used when the system is started. nJ16- Force Power On JumperPin 1-2 Force Power On disabledPin 2-3 Force Power On enabled oJ21- BMC Disable JumperPin 1-2 BMC EnabledPin 2-3 BMC Disabled pen|US|iso8859-1q  rqH@ DIMM1Node1/Bank1/MemCard1sqH@ DIMM5Node1/Bank1/MemCard1tqH@ DIMM2Node1/Bank2/MemCard1uqH@ DIMM6Node1/Bank2/MemCard1vqH@ DIMM3Node1/Bank3/MemCard1wqH@ DIMM7Node1/Bank3/MemCard1xqH@ DIMM4Node1/Bank4/MemCard1yqH@ DIMM8Node1/Bank4/MemCard1zqH@ DIMM1Node1/Bank5/MemCard2{qH@ DIMM5Node1/Bank5/MemCard2|qH@ DIMM2Node1/Bank6/MemCard2}qH@ DIMM6Node1/Bank6/MemCard2~qH@ DIMM3Node1/Bank7/MemCard2qH@ DIMM7Node1/Bank7/MemCard2qH@ DIMM4Node1/Bank8/MemCard2qH@ DIMM8Node1/Bank8/MemCard2qH@ DIMM1Node1/Bank9/MemCard3qH@ DIMM5Node1/Bank9/MemCard3qH@ DIMM2Node1/Bank10/MemCard3qH@ DIMM6Node1/Bank10/MemCard3qH@ DIMM3Node1/Bank11/MemCard3qH@ DIMM7Node1/Bank11/MemCard3qH@ DIMM4Node1/Bank12/MemCard3qH@ DIMM8Node1/Bank12/MemCard3qH@ DIMM1Node1/Bank13/MemCard4qH@ DIMM5Node1/Bank13/MemCard4qH@ DIMM2Node1/Bank14/MemCard4qH@ DIMM6Node1/Bank14/MemCard4qH@ DIMM3Node1/Bank15/MemCard4qH@ DIMM7Node1/Bank15/MemCard4qH@ DIMM4Node1/Bank16/MemCard4qH@ DIMM8Node1/Bank16/MemCard4rq s&t @|python-dmidecode-3.10.13/unit-tests/private/LenovoThinkPad-T61p.dmp0000644002425500234200000000464511401675045024423 0ustar nimaautonomy_SM_x_DMI_q I? &LENOVO7LET56WW (1.26 )10/18/2007+(I˯ YlXLENOVO64606XGThinkPad T61pL3C7558LENOVO64606XGNot AvailableVF19X79H1H5  LENOVONot AvailableNot AvailableNo Asset Information~  LENOVONot AvailableNot AvailableNot Available~ LENOVONot AvailableNot AvailableNot Available#A NoneGenuineIntelIntel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz   DIMM Slot 1 #DIMM Slot 2 @@ Internal L1 Cache @@ Internal L1 Cache Internal L2 Cache Not AvailableExternal Monitor Not AvailableMicrophone Jack Not AvailableHeadphone Jack~ Not AvailableS/PDIF~ Not AvailableDigital Video  Not AvailableModem  Not AvailableEthernet Not AvailableUSB 1 Not AvailableUSB 2 Not AvailableUSB 3~ Not AvailableUSB 4~ Not AvailableUSB 5~ Not AvailableUSB 6~ Not AvailableUSB 7~ Not AvailableUSB 8~  Not AvailableSerial~ Not AvailableParallel~ Not AvailablePS/2 Port !Not AvailableIEEE1394 ExpressCard Slot 1 !CardBus Slot 1~ "PCI Express Slot 1~ #ExpressCard Slot 2 $Media Card Slot 1~ %SmartCard Slot 1~ &Media Card Slot 2 'IBM Embedded Security hardware (IBM ThinkPad Embedded Controller -[7KHT22WW-1.06 ]- )enUS*+@,+@@ DIMM 1Bank 0/1-+@@ DIMM 2Bank 2/3./+0,/1-/2340*L7 RearPanasonic92P113903.01LION~5Bay6 78BOOTINF 20hBOOTDEV 21hKEYPTRS 23h9TVT-Enablement:6;KHOIHGIUCCHHII < =ATMLTPM INFOSystem Reserved >TP?TP#@TPBAY I/O  HATPBZZC PWMS Information(D@@@@@BIOS Password Format%E PWMS Key InformationFIntel_ASFIntel_ASF_001G$AMTHpython-dmidecode-3.10.13/unit-tests/private/Parallels-Virtual-Platform.0.dmidump0000644002425500234200000000145111401675045027140 0ustar nimaautonomy_SM__DMI_  #xParallels Software International Inc.3.009/06/2008 =nnbOKParallels Software International Inc.Parallels Virtual PlatformNoneParallels-0D 3D 6E 6E 62 E5 4F A1 B9 F4 07 EF C0 1F 4B B2NN/ANoneNo Asset Tag#  ACPU Socket #0GenuineIntel ISA slot 1 PCI slot 1 PCI slot 2 PCI slot 3 PCI slot 4 PCI slot 5  Parallels Video AdapterParallels Sound Adapter @  DIMM #0BANK #0 DIMM #1BANK #1 DIMM #2BANK #2 DIMM #3BANK #3  python-dmidecode-3.10.13/unit-tests/private/PowerEdge-1800.0.dmidump0000644002425500234200000000600311401675045024260 0ustar nimaautonomy_SM__DMI_ R# ڲ }Dell Computer Corporation A0509/21/2005DELL4SYOG1SDell Computer Corporation PowerEdge 1800 H4SYG1S Dell Computer Corporation0P8611A04..CN7170359S1758.Dell Computer Corporation H4SYG1S #C  APROC_1Intel#PROC_2Intel SCSI              SLOT1   SLOT2   SLOT3  SLOT4  SLOT5  SLOT6 LSI Logic 53C1020 Ultra 320 SCSIATI RADEON 7000 PCI VideoIntel 82541GI Gigabit Ethernet  Dell System5[0000]~~1[ ]3[ ]5[0000]7[ ]8[ ]9[ ]10[ ]11[ ]12[ ]  NVRAM_CLR: Clear user settable NVRAM areas and set defaultsPASSWD: Close to enable password  en|US|iso8859-1H@ DIMM1_AC1000000000000000104C52344053872T64001HR5A H@ DIMM1_BC1000000000000000104C22744053872T64001HR5A H@ DIMM2_A H@ DIMM2_B H@ DIMM3_A H@ DIMM3_B ~@~~~~~~~~ ~ ~ ~ ~ ~ ~!~$~%~(~)~0@~1@~4@~5@~8@~9@ && @  x ԧpq-.%% %@ %` % %%%%.@%/@%%BCD E1@2@&&Q&?R&?@S&?T&?(@& )@&pq@YmkxlxXxYx\x@]xxx@Q @Q @Q @QUUUU@U UUPUUUSS3@S4@S5@S6@S@S@S@S@SnX-X.X"@X#@X/pq@YmUU\ gvwԱrs@]^(J)J*J@J@J~~*@~+@~,-KKKK5L7L9L;L=Lv&@B'@B7@B8@BGGHHH ATIRADEON 7000 V6.11python-dmidecode-3.10.13/unit-tests/private/ProLiant-BL460c-G1.0.dmidump0000644002425500234200000000426211401675045024703 0ustar nimaautonomy_SM__DMI_C G$?}HPI1511/13/2007416656CZJ7140658CZJ7140658 416656-B21 ProLiantHPProLiant BL460c G1 HPGB8714BMAF (5 A 0Proc 1Intel(&6Proc 2Intel@Processor 1 Internal L1 CacheProcessor 2 Internal L1 Cache @Processor 1 Internal L2 Cache&Processor 2 Internal L2 Cache0Processor 1 Internal L3 Cache6Processor 2 Internal L3 Cache J58USB Port 1 J58USB Port 2 J58USB Port 3   PCI-E Slot 1   PCI-E Slot 2   PCI-E Slot 3  Product ID: 416656-B21 H@DIMM 1AH@DIMM 2CH@DIMM 3AH@DIMM 4CH@DIMM 5BH@DIMM 6DH@DIMM 7BH@DIMM 8D      && 11/13/200709/18/2006$0E110761 fFp P <p  v  v t t  g & & dFATx  24 TTRAFLONBLD02 BladeSystem c7000 Enclosure 16 GB8714BMAF 6/6/x $CRU@6F,11  `     --6/6/yFpython-dmidecode-3.10.13/unit-tests/private/ProLiant-DL385-G1.0.dmidump0000644002425500234200000000321111401675045024541 0ustar nimaautonomy_SM__DMI_vi @#?}HPA0503/01/2006391112SGH615X1EMHPProLiant DL385 G1SGH615X1EM  HPSGH615X1EM   A&Node 1AMD  D$Node 2AMD@@Node 1 Internal L1 Cache@@Node 2 Internal L1 Cache& Node 1 Internal L2 Cache$ Node 2 Internal L2 Cache6Node 1 Internal L3 Cache4Node 2 Internal L3 Cache J508USB Port 1 J24USB Port 2 J24USB Port 3  PCI Slot 1  PCI Slot 2  PCI Slot 3  Product ID: 391112-371 H@ DIMM 01H@ DIMM 02H@ DIMM 03H@ DIMM 04H@ DIMM 05H@ DIMM 06H@ DIMM 07H@ DIMM 08 ? ? ? 12/15/200509/26/2004$0E110755  49 H: JA %PM ( <FATx0 1 $CRU@$SHF@6F,11  `     python-dmidecode-3.10.13/unit-tests/private/ProLiant-DL385-G1.1.dmidump0000644002425500234200000000316211401675045024547 0ustar nimaautonomy_SM__DMI_R ?#?}HPA0504/22/2005376138SGH514X0E2HPProLiant DL385 G1SGH514X0E2  HPSGH514X0E2  Q( ( A&Node 1AMD Q( ( D$Node 2AMD@@Node 1 Internal L1 Cache@@Node 2 Internal L1 Cache& Node 1 Internal L2 Cache$ Node 2 Internal L2 Cache6Node 1 Internal L3 Cache4Node 2 Internal L3 Cache J508USB Port 1 J24USB Port 2 J24USB Port 3  PCI Slot 1  PCI Slot 2  PCI Slot 3  Product ID: 376138-371 H@ DIMM 01H@ DIMM 02H@ DIMM 03H@ DIMM 04H@ DIMM 05H@ DIMM 06H@ DIMM 07H@ DIMM 08 / / / 04/22/200509/26/2004$0E110755  (9 H: JA %P <FATx0y,1y+$CRU@$SHF@6F,11  `     python-dmidecode-3.10.13/unit-tests/private/ProLiant-DL385-G1.2.dmidump0000644002425500234200000000321111401675045024543 0ustar nimaautonomy_SM__DMI_vi @#?}HPA0503/01/2006399684AUB631010MHPProLiant DL385 G1AUB631010M  HPAUB631010M   ` A&Node 1AMD  ` D$Node 2AMD@@Node 1 Internal L1 Cache@@Node 2 Internal L1 Cache& Node 1 Internal L2 Cache$ Node 2 Internal L2 Cache6Node 1 Internal L3 Cache4Node 2 Internal L3 Cache J508USB Port 1 J24USB Port 2 J24USB Port 3  PCI Slot 1  PCI Slot 2  PCI Slot 3  Product ID: 399684-371 H@ DIMM 01H@ DIMM 02H@ DIMM 03H@ DIMM 04H@ DIMM 05H@ DIMM 06H@ DIMM 07H@ DIMM 08OPOOOOPPPP 03/01/200609/26/2004 $0E110755  49 H: JA %PM ( <FATx01$CRU@$SHF@6F,11  `     python-dmidecode-3.10.13/unit-tests/private/ProLiant-DL385-G2.0.dmidump0000644002425500234200000000315111401675045024545 0ustar nimaautonomy_SM__DMI_I ?#?}HPA0901/08/2007407424AUB72001CYAUB72001CY HPProLiant DL385 G2 HPAUB72001CY ( ( A Proc 1AMD( ( D!Proc 2AMD@@Processor 1 Internal L1 Cache@@Processor 2 Internal L1 Cache  Processor 1 Internal L2 Cache! Processor 2 Internal L2 Cache J2USB Port 1 J2USB Port 2 J1USB Port 3   PCI-E Slot 1   PCI-E Slot 2   PCI-E Slot 3   PCI-E Slot 4   PCI-E Slot 5  Product ID: 407424-371 H@ DIMM 1AH@ DIMM 2AH@ DIMM 3BH@ DIMM 4BH@ DIMM 5CH@ DIMM 6CH@ DIMM 7DH@ DIMM 8D K K K && 01/08/200709/19/2006$0E11076F   <(b 'h m FATxKPbBKPb$CRU<@KPbBKPbpython-dmidecode-3.10.13/unit-tests/private/ProLiant-DL580-G5.0.dmidump0000644002425500234200000001102111401675045024540 0ustar nimaautonomy_SM__DMI_w %?}HPP6112/07/2007438087SGH802DTDBSGH802DTDB 438087-371 ProLiantHPProLiant DL580 G5 HPSGH802DTDB (*` A!1Proc 1Intel(*` D"2Proc 2Intel(*` D#3Proc 3Intel(*` D$4Proc 4Intel Processor 1 Internal L1 Cache Processor 2 Internal L1 Cache Processor 3 Internal L1 Cache Processor 4 Internal L1 Cache!`Processor 1 Internal L2 Cache"`Processor 2 Internal L2 Cache#`Processor 3 Internal L2 Cache$`Processor 4 Internal L2 Cache1Processor 1 Internal L3 Cache2Processor 2 Internal L3 Cache3Processor 3 Internal L3 Cache4Processor 4 Internal L3 Cache J58USB Port 1 J58USB Port 2 J58USB Port 3 J58USB Port 4   PCI-E Slot 4   PCI-E Slot 5   PCI-E Slot 6   PCI-E Slot 7   PCI-E Slot 8   PCI-E Slot 9   PCI-E Slot 10   PCI-E Slot 11  Product ID: 438087-371     H@DIMM 1A H@DIMM 2C H@DIMM 3E H@DIMM 4G H@ Board 1, DIMM 1AH@ Board 1, DIMM 2BH@ Board 1, DIMM 3CH@Board 1, DIMM 4DH@DIMM 5A  H@DIMM 6C  H@DIMM 7E  H@DIMM 8G  H@ Board 2, DIMM 1A H@ Board 2, DIMM 2BH@ Board 2, DIMM 3CH@Board 2, DIMM 4DH@DIMM 9B H@DIMM 10D H@DIMM 11F H@DIMM 12H H@ Board 3, DIMM 1AH@ Board 3, DIMM 2BH@Board 3, DIMM 3CH@Board 3, DIMM 4DH@DIMM 13B H@DIMM 14D H@DIMM 15F H@DIMM 16H H@ Board 4, DIMM 1AH@ Board 4, DIMM 2BH@Board 4, DIMM 3CH@Board 4, DIMM 4DKKKKKKKKK K  K       KKKKKK && 12/07/200707/02/2007$0E110777    fFpLLLL <DŽ  FATx          ĖŒĖŔ$CRU@6F,11  `     U   }ĖœĖŕpython-dmidecode-3.10.13/unit-tests/private/ProLiant-DL585-G1.0.dmidump0000644002425500234200000000760511401675045024556 0ustar nimaautonomy_SM__DMI_e #}HPA0101/20/2006HXDZPGK16B HPProLiant DL585 G1HXDZPGK16B  HPHXDZPGK16B   ` D&Node 1AMD  ` A$Node 2AMD  ` D"Node 3AMD  ` D Node 4AMD@@Node 1 Internal L1 Cache@@Node 2 Internal L1 Cache@@Node 3 Internal L1 Cache@@Node 4 Internal L1 Cache& Node 1 Internal L2 Cache$ Node 2 Internal L2 Cache" Node 3 Internal L2 Cache  Node 4 Internal L2 Cache6Node 1 Internal L3 Cache4Node 2 Internal L3 Cache2Node 3 Internal L3 Cache0Node 4 Internal L3 Cache J58USB Port 1 J58USB Port 2  PCI Slot 1  PCI Slot 2  PCI Slot 3  PCI Slot 4  PCI Slot 5  PCI Slot 6  PCI Slot 7  PCI Slot 8    H@ Board 1, DIMM 01H@ Board 1, DIMM 02H@ Board 1, DIMM 03H@ Board 1, DIMM 04H@ Board 1, DIMM 05H@ Board 1, DIMM 06H@ Board 1, DIMM 07H@ Board 1, DIMM 08H@ Board 2, DIMM 01 H@ Board 2, DIMM 02 H@ Board 2, DIMM 03 H@ Board 2, DIMM 04 H@ Board 2, DIMM 05 H@ Board 2, DIMM 06H@ Board 2, DIMM 07H@ Board 2, DIMM 08H@ Board 3, DIMM 01H@ Board 3, DIMM 02H@ Board 3, DIMM 03H@ Board 3, DIMM 04H@ Board 3, DIMM 05H@ Board 3, DIMM 06H@ Board 3, DIMM 07H@ Board 3, DIMM 08H@ Board 4, DIMM 01H@ Board 4, DIMM 02H@ Board 4, DIMM 03H@ Board 4, DIMM 04H@ Board 4, DIMM 05H@ Board 4, DIMM 06H@ Board 4, DIMM 07H@ Board 4, DIMM 08           01/20/200611/28/2005 $0E11073A     <(9 H: JA %P     FATx05|V315|V2$CRU@$SHF@6F,11  `     python-dmidecode-3.10.13/unit-tests/private/ProLiant-DL585-G1.1.dmidump0000644002425500234200000000760511401675045024557 0ustar nimaautonomy_SM__DMI_e #}HPA0108/26/2005HXDMPGK16B HPProLiant DL585 G1HXDMPGK16B  HPHXDMPGK16B   ` D&Node 1AMD  ` A$Node 2AMD d "Node 3AMD d  Node 4AMD@@Node 1 Internal L1 Cache@@Node 2 Internal L1 Cache@Node 3 Internal L1 Cache@Node 4 Internal L1 Cache& Node 1 Internal L2 Cache$ Node 2 Internal L2 Cache" Node 3 Internal L2 Cache  Node 4 Internal L2 Cache6Node 1 Internal L3 Cache4Node 2 Internal L3 Cache2Node 3 Internal L3 Cache0Node 4 Internal L3 Cache J58USB Port 1 J58USB Port 2  PCI Slot 1  PCI Slot 2  PCI Slot 3  PCI Slot 4  PCI Slot 5  PCI Slot 6  PCI Slot 7  PCI Slot 8    ''''H@ Board 1, DIMM 05H@ Board 1, DIMM 06H@ Board 1, DIMM 07H@ Board 1, DIMM 08'' ' '  H@ Board 2, DIMM 05 H@ Board 2, DIMM 06H@ Board 2, DIMM 07H@ Board 2, DIMM 08''''H@ Board 3, DIMM 05H@ Board 3, DIMM 06H@ Board 3, DIMM 07H@ Board 3, DIMM 08''''H@ Board 4, DIMM 05H@ Board 4, DIMM 06H@ Board 4, DIMM 07H@ Board 4, DIMM 08           08/26/200503/16/2004 $0E11073A     <(9 H: JA %P!"#$%&'(  )*+,-./0FATx0XE1XE$CRU@$SHF@6F,11  `     python-dmidecode-3.10.13/unit-tests/private/ProLiant-DL585-G1.2.dmidump0000644002425500234200000000760511401675045024560 0ustar nimaautonomy_SM__DMI_e #}HPA0101/20/2006HXDZPGK16B HPProLiant DL585 G1HXDZPGK16B  HPHXDZPGK16B   ` D&Node 1AMD  ` A$Node 2AMD  ` D"Node 3AMD  ` D Node 4AMD@@Node 1 Internal L1 Cache@@Node 2 Internal L1 Cache@@Node 3 Internal L1 Cache@@Node 4 Internal L1 Cache& Node 1 Internal L2 Cache$ Node 2 Internal L2 Cache" Node 3 Internal L2 Cache  Node 4 Internal L2 Cache6Node 1 Internal L3 Cache4Node 2 Internal L3 Cache2Node 3 Internal L3 Cache0Node 4 Internal L3 Cache J58USB Port 1 J58USB Port 2  PCI Slot 1  PCI Slot 2  PCI Slot 3  PCI Slot 4  PCI Slot 5  PCI Slot 6  PCI Slot 7  PCI Slot 8    H@ Board 1, DIMM 01H@ Board 1, DIMM 02H@ Board 1, DIMM 03H@ Board 1, DIMM 04H@ Board 1, DIMM 05H@ Board 1, DIMM 06H@ Board 1, DIMM 07H@ Board 1, DIMM 08H@ Board 2, DIMM 01 H@ Board 2, DIMM 02 H@ Board 2, DIMM 03 H@ Board 2, DIMM 04 H@ Board 2, DIMM 05 H@ Board 2, DIMM 06H@ Board 2, DIMM 07H@ Board 2, DIMM 08H@ Board 3, DIMM 01H@ Board 3, DIMM 02H@ Board 3, DIMM 03H@ Board 3, DIMM 04H@ Board 3, DIMM 05H@ Board 3, DIMM 06H@ Board 3, DIMM 07H@ Board 3, DIMM 08H@ Board 4, DIMM 01H@ Board 4, DIMM 02H@ Board 4, DIMM 03H@ Board 4, DIMM 04H@ Board 4, DIMM 05H@ Board 4, DIMM 06H@ Board 4, DIMM 07H@ Board 4, DIMM 08           01/20/200611/28/2005 $0E11073A     <(9 H: JA %P     FATx05|V315|V2$CRU@$SHF@6F,11  `     python-dmidecode-3.10.13/unit-tests/private/ProLiant-DL585-G2.0.dmidump0000644002425500234200000000712511401675045024554 0ustar nimaautonomy_SM__DMI_M5 #?}HPA0702/27/2007413930SGH7194KJDSGH7194KJD HPProLiant DL585 G2 HPSGH7194KJD ( A Proc 1AMD( D!Proc 2AMD( D"Proc 3AMD( D#Proc 4AMD@@Processor 1 Internal L1 Cache@@Processor 2 Internal L1 Cache@@Processor 3 Internal L1 Cache@@Processor 4 Internal L1 Cache  Processor 1 Internal L2 Cache! Processor 2 Internal L2 Cache" Processor 3 Internal L2 Cache# Processor 4 Internal L2 Cache J58USB Port 1 J58USB Port 2 J58USB Port 3  PCI Slot 1  PCI Slot 2   PCI-E Slot 3   PCI-E Slot 4   PCI-E Slot 5   PCI-E Slot 6   PCI-E Slot 7   PCI-E Slot 8   PCI-E Slot 9  Product ID: 413930-371  H@ DIMM 1AH@ DIMM 2AH@ DIMM 3BH@ DIMM 4BH@ DIMM 5CH@ DIMM 6CH@ DIMM 7DH@ DIMM 8DH@ DIMM 9E H@ DIMM 10E H@ DIMM 11F H@ DIMM 12F H@ DIMM 13G H@ DIMM 14GH@ DIMM 15HH@ DIMM 16HH@ DIMM 17IH@ DIMM 18IH@ DIMM 19JH@ DIMM 20JH@ DIMM 21KH@ DIMM 22KH@ DIMM 23LH@ DIMM 24LH@ DIMM 25MH@ DIMM 26MH@ DIMM 27NH@ DIMM 28NH@ DIMM 29OH@ DIMM 30OH@ DIMM 31PH@ DIMM 32P                  && 01/08/200709/13/2006$0E110767     <(b 'h m FATx           AK|AK~$CRU<@-AK}AKpython-dmidecode-3.10.13/unit-tests/private/ProLiant-DL585-G2.1.dmidump0000644002425500234200000001000211401675045024541 0ustar nimaautonomy_SM__DMI_ $?}HPA0709/27/2008413930SGH7102PFASGH7102PFA 413930-371 ProLiantHPProLiant DL585 G2 HPSGH7102PFA ( A Proc 1AMD( D!Proc 2AMD( D"Proc 3AMD( D#Proc 4AMDProcessor 1 Internal L1 CacheProcessor 2 Internal L1 CacheProcessor 3 Internal L1 CacheProcessor 4 Internal L1 Cache  Processor 1 Internal L2 Cache! Processor 2 Internal L2 Cache" Processor 3 Internal L2 Cache# Processor 4 Internal L2 Cache4 2 3 4  J58USB Port 1 J58USB Port 2 J58USB Port 3 J58USB Port 4 J58USB Port 5  PCI Slot 1  PCI Slot 2   PCI-E Slot 3   PCI-E Slot 4   PCI-E Slot 5   PCI-E Slot 6   PCI-E Slot 7   PCI-E Slot 8   PCI-E Slot 9  Product ID: 413930-371  H@ DIMM 1AH@ DIMM 2AH@ DIMM 3BH@ DIMM 4BH@ DIMM 5CH@ DIMM 6CH@ DIMM 7DH@ DIMM 8DH@ DIMM 9E H@ DIMM 10E H@ DIMM 11F H@ DIMM 12F H@ DIMM 13G H@ DIMM 14GH@ DIMM 15HH@ DIMM 16HH@ DIMM 17IH@ DIMM 18IH@ DIMM 19JH@ DIMM 20JH@ DIMM 21KH@ DIMM 22KH@ DIMM 23LH@ DIMM 24LH@ DIMM 25MH@ DIMM 26MH@ DIMM 27NH@ DIMM 28NH@ DIMM 29OH@ DIMM 30OH@ DIMM 31PH@ DIMM 32P                && 02/27/200709/13/2006$0E110767     <d  & A @   0"b 'h m FATx           Av]Av]$CRU<@ۅ-UAv]Av]python-dmidecode-3.10.13/unit-tests/private/VMware-Virtual-Platform.0.dmidump0000644002425500234200000000332111401675045026420 0ustar nimaautonomy_SM_a_DMI_d -_Phoenix Technologies LTD6.0001/30/2008P6$v:ѱ}JVMware, Inc.VMware Virtual PlatformNoneVMware-50 36 00 e5 9f 24 76 3a-84 d1 b1 7d fc b7 4a ffIntel Corporation440BX Desktop Reference PlatformNoneNone4No EnclosureN/ANoneNo Asset Tag# UUA CPU socket #0GenuineIntelPentium(R) Pro#CPU socket #100000000000000000000000000000000000000000000#CPU socket #200000000000000000000000000000000000000000000#CPU socket #300000000000000000000000000000000000000000000    RAM socket #0 #RAM socket #1 ERAM socket #2 gRAM socket #3 X@L1 Cache@XL2 Cache  J19COM 1 J23Parallel  J11Keyboard  J12PS/2 Mouse ISA Slot J8 ISA Slot J9 ISA Slot J10 PCI Slot J11 PCI Slot J12 PCI Slot J13 PCI Slot J14 VMware SVGA IIES1371 [MS_VM_CERT/SHA1/27d66596a61c48dd3dc7216fd715126e33f59ae7]Welcome to the Virtual Machine6@  RAM slot #0RAM slot #0 RAM slot #1RAM slot #1  RAM slot #2RAM slot #2! RAM slot #3RAM slot #3"#$#%# &?'7(Intel )  !*~+,python-dmidecode-3.10.13/unit-tests/private/kvm-QEMU.0.dmidump0000644002425500234200000000041211401675045023351 0ustar nimaautonomy_SM_T)_DMI_0 $QEMU01/01/2007 #ACPU 1@@ DIMM 0 python-dmidecode-3.10.13/unit-tests/unit0000755002425500234200000002726611401675045017543 0ustar nimaautonomy#!/usr/bin/env python #.awk '$0 ~ /case [0-9]+: .. 3/ { sys.stdout.write($2 }' src/dmidecode.c|tr ':\n' ', ' from pprint import pprint import os, sys, random, tempfile, time import commands from getopt import getopt # Setup temporary sys.path() with our build dir (sysname, nodename, release, version, machine) = os.uname() pyver = sys.version[:3] sys.path.insert(0,'../build/lib.%s-%s-%s' % (sysname.lower(), machine, pyver)) root_user = (os.getuid() == 0 and True or False) ERROR = False HELP = False VERBOSITY = 0 COLOR = False DUMPS_D = "private" try: opts, args = getopt( sys.argv[1:], "hcv", ["help", "color", "verbose"] ) for o, a in opts: if o in ("-v", "--verbose"): VERBOSITY += 1 elif o in ("-c", "--color"): COLOR = True elif o in ("-h", "--help"): HELP = True except getopt.GetoptError, err: # print help information and exit: HELP = True ERROR = True if HELP: sys.stdout.write(""" Usage: %s [] OPTIONS [-h|--help] #. Take a wild guess. [-c|--color] #. Add pretty ANSI colors. [-v|--verbose] #. The more you add, the louder it gets. NOTES Due to developer laziness, a single verbosity flag does nothing, so if you actually want to get some verbosity, add two verbosity flags (-vv) """ % os.path.basename(sys.argv[0])) sys.exit(ERROR and 1 or 0) def ascii(s, i): return (COLOR and "\033[%d;1m%s\033[0m" or "%d%s") % (30+i, str(s)) def black(s): return (COLOR and "\033[30;1m%s\033[0m" or "%s")%(str(s)) def red(s): return (COLOR and "\033[31;1m%s\033[0m" or "%s")%(str(s)) def green(s): return (COLOR and "\033[32;1m%s\033[0m" or "%s")%(str(s)) def yellow(s): return (COLOR and "\033[33;1m%s\033[0m" or "%s")%(str(s)) def blue(s): return (COLOR and "\033[34;1m%s\033[0m" or "%s")%(str(s)) def magenta(s): return (COLOR and "\033[35;1m%s\033[0m" or "%s")%(str(s)) def cyan(s): return (COLOR and "\033[36;1m%s\033[0m" or "%s")%(str(s)) def white(s): return (COLOR and "\033[37;1m%s\033[0m" or "%s")%(str(s)) DISPATCH = { 1 : red, 2 : green, 3 : yellow, 4 : blue, 5 : magenta, 6 : cyan, 7 : white, } LINE = "%s\n"%(magenta("="*80)) score = { "total" : 0, "skipped" : 0, "passed" : 0, "warned" : 0, "failed" : 0, } def passed(msg=None, indent=1): global score score["total"] += 1 score["passed"] += 1 vwrite("%s\n"%green("PASS"), 1) if msg: vwrite("%s %s %s\n"%(" "*indent, green("P"), msg), 1) def skipped(msg=None, indent=1): global score score["total"] += 1 score["skipped"] += 1 vwrite("%s\n"%yellow("SKIP"), 1) if msg: vwrite("%s %s %s\n"%(" "*indent, yellow("S"), msg), 1) def warned(msg=None, indent=1): global score score["total"] += 1 score["warned"] += 1 vwrite("%s\n"%yellow("WARN"), 1) if msg: vwrite("%s %s %s\n"%(" "*indent, yellow("S"), msg), 1) def failed(msg=None, indent=1): global score score["total"] += 1 score["failed"] += 1 vwrite("%s\n"%red("FAIL"), 1) if msg: vwrite("%s %s %s\n"%(" "*indent, red("F"), msg), 1) def test(r, msg=None, indent=1, bad=failed): if r: passed(msg, indent) return True else: bad(msg, indent) return False def vwrite(msg, vLevel=0): if vLevel < VERBOSITY: sys.stdout.write(msg) sys.stdout.flush() ################################################################################ #. Let's ignore warnings from the module for the test units... err = open('/dev/null', 'a+', 0) os.dup2(err.fileno(), sys.stderr.fileno()) vwrite(LINE, 1) vwrite(" * Testing for command line version of dmidecode ...", 1) dmidecode_bin = True in [ os.path.exists( os.path.join(_, "dmidecode") ) for _ in os.getenv("PATH").split(':') ] test(dmidecode_bin, bad=warned) if root_user: vwrite(" * Running test as root user, all tests will be executed\n", 1) else: vwrite(" * %s\n"%red("Running test as normal user, some tests will be skipped"), 1) vwrite(" * Creation of temporary files...", 1) try: FH, DUMP = tempfile.mkstemp() os.unlink(DUMP) os.close(FH) passed() except: failed() vwrite(LINE, 1) try: vwrite(" * Importing module...", 1) import libxml2 import dmidecode if not root_user: vwrite("\n%s"%cyan("Not running as root, a warning above can be expected..."), 1) passed() vwrite(" * Version: %s\n"%blue(dmidecode.version), 1) vwrite(" * DMI Version String: %s\n"%blue(dmidecode.dmi), 1) vwrite(" * Testing that default device is /dev/mem...", 1) test(dmidecode.get_dev() == "/dev/mem") if root_user: vwrite(" * Testing that write-lock will not break on dump()...", 1) test(not dmidecode.dump()) vwrite(" * Testing ability to change device to %s..."%DUMP, 1) test(dmidecode.set_dev(DUMP)) vwrite(" * Testing that device has changed to %s..."%DUMP, 1) test(dmidecode.get_dev() == DUMP) if root_user and dmidecode.dmi is not None: vwrite(" * Testing that write on new file is ok...", 1) test(dmidecode.dump()) vwrite(" * Testing that file was actually written...", 1) time.sleep(0.1) if test(os.path.exists(DUMP)): os.unlink(DUMP) else: if dmidecode.dmi is None: vwrite( " * %s\n" % yellow( "Skipped testing dump() function, dmidecode does not have access to DMI data" ), 1) else: vwrite( " * %s\n" % red( "Skip testing API function, missing root privileges: dmidecode.dump()" ), 1) types = range(0, 42)+range(126, 128) bad_types = [-1, -1000, 256] sections = [ "bios", "system", "baseboard", "chassis", "processor", "memory", "cache", "connector", "slot" ] devices = [] if os.path.exists(DUMPS_D): devices.extend([os.path.join(DUMPS_D, _) for _ in os.listdir(DUMPS_D)]) else: vwrite(" * If you have memory dumps to test, create a directory called `%s' and drop them in there.\n" % DUMPS_D, 1) if root_user and dmidecode.dmi is not None: devices.append("/dev/mem") else: if dmidecode.dmi is not None: vwrite(" * %s\n"%red("Running test as normal user, will not try to read /dev/mem"), 1) try: pymap = '../src/pymap.xml' vwrite(" * Loading %s for XML->Python dictonary mapping..." % pymap, 1) dmidecode.pythonmap(pymap) passed() except: failed() random.shuffle(types) random.shuffle(devices) random.shuffle(sections) for dev in devices: vwrite(LINE, 1) vwrite(" * Testing %s..."%yellow(dev), 1) try: fH = open(dev, 'r') fH.close() passed() vwrite(" * Testing set_dev/get_dev on %s..."%(yellow(dev)), 1) if test(dmidecode.set_dev(dev) and dmidecode.get_dev() == dev): i = 0 for section in sections: i += 1 vwrite(" * Testing %s (%d/%d)..."%(cyan(section), i, len(sections)), 1) try: output = getattr(dmidecode, section)() test(output is not False) if output: vwrite(" * %s\n"%black(output.keys()), 1) except LookupError, e: failed(e, 1) for i in bad_types: vwrite(" * Testing bad type %s..."%red(i), 1) try: output = dmidecode.type(i) test(output is False) except SystemError: failed() for i in types: vwrite(" * Testing type %s..."%red(i), 1) try: output = dmidecode.type(i) if dmidecode_bin: _output = commands.getoutput("dmidecode -t %d"%i).strip().split('\n') test(len(_output) == 1 and len(output) == 0 or True) else: test(output is not False) if output: vwrite(" * %s\n"%output.keys(), 1) except IOError, e: failed(e, 1) except LookupError, e: failed(e, 1) dmixml = dmidecode.dmidecodeXML() try: vwrite(" * XML: Swapping result type dmidecodeXML::SetResultType('-') - invalid type... ", 1) test(not dmixml.SetResultType('-')) except TypeError: vwrite("Not working => ", 1) passed() except: vwrite("Accepted => ", 1) failed() try: vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_DOC) - valid type...", 1) test(dmixml.SetResultType(dmidecode.DMIXML_DOC)) vwrite(" * XML: Swapping result type - dmidecodeXML::SetResultType(dmidecode.DMIXML_NODE) - valid type...", 1) test(dmixml.SetResultType(dmidecode.DMIXML_NODE)) except: failed() for i in bad_types: vwrite(" * XML: Testing bad type - dmidecodeXML::QueryTypeId(%s)..." % red(i), 1) try: output_node = dmixml.QueryTypeId(i) test(not isinstance(output_node, libxml2.xmlNode)) except SystemError: vwrite("Accepted => ", 1) failed() except TypeError: vwrite("Not working => ", 1) passed() except ValueError: vwrite("Not working => ", 1) passed() for i in types: vwrite(" * XML: Testing dmidecodeXML::QueryTypeId(%s)..." % red(i), 1) try: output_node = dmixml.QueryTypeId(i) test(isinstance(output_node, libxml2.xmlNode)) except Exception, e: failed(e, 1) except: failed() dmixml.SetResultType(dmidecode.DMIXML_DOC) i = 0 for section in sections: i += 1 vwrite(" * %s (%d/%d)..." % ( "XML: Testing dmidecodeXML::QuerySection('%s')" % cyan( section ), i, len(sections) ), 1) try: output_doc = dmixml.QuerySection(section) test(isinstance(output_doc, libxml2.xmlDoc)) except Exception, e: failed(e, 1) except: failed() except IOError: skipped() except ImportError, err: failed() print err vwrite(LINE, 1) vwrite("Devices : %s\n"%cyan(len(devices)), 1) vwrite("Total : %s\n"%blue(score["total"]), 1) vwrite("Skipped : %s\n"%yellow(score["skipped"]), 1) vwrite("Warned : %s\n"%yellow(score["warned"]), 1) vwrite("Passed : %s\n"%green(score["passed"]), 1) vwrite("Failed : %s\n"%red(score["failed"]), 1) sys.exit(score["failed"] != 0 and 1 or 0) python-dmidecode-3.10.13/utils/0000755002425500234200000000000011401675045015642 5ustar nimaautonomypython-dmidecode-3.10.13/utils/c-code-indent0000755002425500234200000000021111401675045020173 0ustar nimaautonomy#!/bin/sh PARAM="-npro -kr -nut -bbb -bad -i8 -ts8 -sob -l100 -ss -ncs -cp1 -sc -nsaf -nsai -nsaw -nbbo -hnl -br -ce" indent $PARAM "$@" python-dmidecode-3.10.13/utils/set_version0000755002425500234200000000430011401675045020125 0ustar nimaautonomy#!/bin/bash if [ $# != 1 ]; then echo "Usage: $0 " exit 1 fi if [ ! -d ./src -a ! -f redhat.spec ]; then echo "Cannot find the ./src directory or the ./redhat.spec file" echo "Are you in the project root directory?" exit 2 fi NEW_VERSION=$1 OLD_VERSION=$(cd src;python -c "from setup_common import *; print get_version();") # Prepare ChangeLog entry for the python-dmidecode.spec file TSTAMP="$(date +%a\ %b\ %d\ %Y)" FNAME="$(git config user.name)" EMAIL="$(git config user.email)" CHLOG="$TSTAMP $FNAME <$EMAIL> - ${NEW_VERSION}-1" # Prepare regexp script to modify python-dmidecode.spec { cat < .chversion # Get confirmation of version change cat </dev/null echo " ** Updating contrib/python-dmidecode.spec" cat .chversion | ed contrib/python-dmidecode.spec 2> /dev/null if [ $? = 0 ]; then rm -f .chversion fi echo echo " ** git add src/version.h contrib/python-dmidecode.spec" git add src/version.h contrib/python-dmidecode.spec echo "-----------------------------------------------------------------------------------" git diff --cached echo "-----------------------------------------------------------------------------------" echo echo " ** **" echo " ** REMEMBER to COMMIT this change when you have validated the result **" echo " ** **" echo ;; *) echo echo echo " ** Not confirmed. Aborting." echo ;; esac