View Javadoc
1   /*
2    * Copyright 2020-2023 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.driver.linux;
6   
7   import oshi.annotation.concurrent.ThreadSafe;
8   import oshi.util.ExecutingCommand;
9   import oshi.util.ParseUtil;
10  import oshi.util.UserGroupInfo;
11  import oshi.util.tuples.Pair;
12  
13  /**
14   * Utility to read info from {@code dmidecode}
15   */
16  @ThreadSafe
17  public final class Dmidecode {
18  
19      private Dmidecode() {
20      }
21  
22      // $ sudo dmidecode -t bios
23      // # dmidecode 2.11
24      // SMBIOS 2.4 present.
25      //
26      // Handle 0x0000, DMI type 0, 24 bytes
27      // BIOS Information
28      // Vendor: Phoenix Technologies LTD
29      // Version: 6.00
30      // Release Date: 07/02/2015
31      // Address: 0xEA5E0
32      // Runtime Size: 88608 bytes
33      // ROM Size: 64 kB
34      // Characteristics:
35      // ISA is supported
36      // PCI is supported
37      // PC Card (PCMCIA) is supported
38      // PNP is supported
39      // APM is supported
40      // BIOS is upgradeable
41      // BIOS shadowing is allowed
42      // ESCD support is available
43      // Boot from CD is supported
44      // Selectable boot is supported
45      // EDD is supported
46      // Print screen service is supported (int 5h)
47      // 8042 keyboard services are supported (int 9h)
48      // Serial services are supported (int 14h)
49      // Printer services are supported (int 17h)
50      // CGA/mono video services are supported (int 10h)
51      // ACPI is supported
52      // Smart battery is supported
53      // BIOS boot specification is supported
54      // Function key-initiated network boot is supported
55      // Targeted content distribution is supported
56      // BIOS Revision: 4.6
57      // Firmware Revision: 0.0
58  
59      /**
60       * Query the serial number from dmidecode
61       *
62       * @return The serial number if available, null otherwise
63       */
64      public static String querySerialNumber() {
65          // If root privileges this will work
66          if (UserGroupInfo.isElevated()) {
67              String marker = "Serial Number:";
68              for (String checkLine : ExecutingCommand.runNative("dmidecode -t system")) {
69                  if (checkLine.contains(marker)) {
70                      return checkLine.split(marker)[1].trim();
71                  }
72              }
73          }
74          return null;
75      }
76  
77      /**
78       * Query the UUID from dmidecode
79       *
80       * @return The UUID if available, null otherwise
81       */
82      public static String queryUUID() {
83          // If root privileges this will work
84          if (UserGroupInfo.isElevated()) {
85              String marker = "UUID:";
86              for (String checkLine : ExecutingCommand.runNative("dmidecode -t system")) {
87                  if (checkLine.contains(marker)) {
88                      return checkLine.split(marker)[1].trim();
89                  }
90              }
91          }
92          return null;
93      }
94  
95      /**
96       * Query the name and revision from dmidecode
97       *
98       * @return The a pair containing the name and revision if available, null values in the pair otherwise
99       */
100     public static Pair<String, String> queryBiosNameRev() {
101         String biosName = null;
102         String revision = null;
103 
104         // Requires root, may not return anything
105         if (UserGroupInfo.isElevated()) {
106             final String biosMarker = "SMBIOS";
107             final String revMarker = "Bios Revision:";
108 
109             for (final String checkLine : ExecutingCommand.runNative("dmidecode -t bios")) {
110                 if (checkLine.contains(biosMarker)) {
111                     String[] biosArr = ParseUtil.whitespaces.split(checkLine);
112                     if (biosArr.length >= 2) {
113                         biosName = biosArr[0] + " " + biosArr[1];
114                     }
115                 }
116                 if (checkLine.contains(revMarker)) {
117                     revision = checkLine.split(revMarker)[1].trim();
118                     // SMBIOS should be first line so if we're here we are done iterating
119                     break;
120                 }
121             }
122         }
123         return new Pair<>(biosName, revision);
124     }
125 }