├── LICENSE ├── README.md ├── thinklmi-kernel ├── COPYING ├── Makefile ├── README.md ├── think-lmi.c ├── think-lmi.conf └── think-lmi.h └── thinklmi-user ├── COPYING ├── README.md └── thinklmi.c /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # thinklmi 2 | Utility for easy access to BIOS WMI settings 3 | 4 | Note: ThinkLMI is now integrated upstream into the Linux kernel (5.17 onwards) using the firmware-attributes class. 5 | As long as it is included by your distro you can do 6 | sudo modprobe think-lmi 7 | and then access the WMI attributes under /sys/class/firmware-attributes/thinklmi 8 | 9 | The kernel documentation has details on how to use this: https://github.com/torvalds/linux/blob/master/Documentation/ABI/testing/sysfs-class-firmware-attributes 10 | 11 | The driver and matching user-space utility here should only be used if the kernel driver is not available. Note that thinklmi-user does not currently work with the upstream kernel driver as they use different interfaces (ioctl vs sysfs) 12 | -------------------------------------------------------------------------------- /thinklmi-kernel/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | 283 | -------------------------------------------------------------------------------- /thinklmi-kernel/Makefile: -------------------------------------------------------------------------------- 1 | obj-m := think-lmi.o 2 | 3 | KERNELRELEASE := $(shell uname -r) 4 | KDIR := /lib/modules/$(KERNELRELEASE)/build 5 | PWD := $(shell pwd) 6 | INSTALL := install 7 | MODLOADDIR := /etc/modules-load.d 8 | MODLOADCONF := $(MODLOADDIR)/think-lmi.conf 9 | 10 | default: 11 | $(MAKE) -C $(KDIR) M=$(PWD) modules 12 | 13 | clean: 14 | $(MAKE) -C $(KDIR) M=$(PWD) clean 15 | rm -f /lib/modules/$(KERNELRELEASE)/extra/think-lmi.ko 16 | 17 | modules_install: 18 | $(INSTALL) -d /lib/modules/$(KERNELRELEASE)/extra/ 19 | $(INSTALL) -m 644 think-lmi.ko /lib/modules/$(KERNELRELEASE)/extra/ 20 | 21 | install: modules_install 22 | $(INSTALL) -m 644 think-lmi.conf $(MODLOADDIR) 23 | depmod 24 | modprobe think-lmi 25 | -------------------------------------------------------------------------------- /thinklmi-kernel/README.md: -------------------------------------------------------------------------------- 1 | # think-lmi 2 | 3 | Linux Driver for Think WMI interface. 4 | This dirver allows you to control many BIOS settings from Linux via sysfs 5 | entrypoints or ioctls. 6 | 7 | ## sysfs interface 8 | 9 | Directory: /sys/bus/wmi/drivers/think-lmi/ 10 | 11 | Each setting exposed by the WMI interface is available under its own name 12 | in this sysfs directory. Read from the file to get the current value (line 1) 13 | and list of options (line 2), and write an option to the file to set it. 14 | 15 | Additionally, there are extra files for querying and managing BIOS password(s). 16 | 17 | ### password 18 | 19 | Must contain the BIOS supervisor password (aka 'pap'), if set, to be able to do 20 | any change. 21 | 22 | Every subsequent password change will be authorized with this password. The 23 | password may be unloaded by writing an empty string. Writing an invalid 24 | password may trigger the BIOS' invalid password limit, such that a reboot will 25 | be required in order to make any further BIOS changes. 26 | 27 | ### password_encoding 28 | 29 | Encoding used for the password, either '', 'scancode' or 'ascii'. 30 | 31 | Scan-code encoding appears to require the key-down scan codes, e.g. 0x1e, 0x30, 32 | 0x2e for the ASCII encoded password 'abc'. 33 | 34 | ### password_kbd_lang 35 | 36 | Keyboard language mapping, can be '', 'us', 'fr' or 'gr'. 37 | 38 | ### password_type 39 | 40 | Specify the password type to be changed when password_change is written to. 41 | Can be: 42 | * 'pap': supervisor password 43 | * 'pop': power-on-password 44 | 45 | Other types may be valid, e.g. for user and master disk passwords. 46 | 47 | ### password_change 48 | 49 | Writing to this file will change the password specified by password_type. The 50 | new password will not take effect until the next reboot. 51 | 52 | ### password_settings 53 | 54 | Display password related settings. This includes: 55 | 56 | * password_state: which passwords are set, if any 57 | * bit 0: user password (power on password) is installed / 'pop' 58 | * bit 1: admin/supervisor password is installed / 'pap' 59 | * bit 2: hdd password(s) installed 60 | * supported_encodings: supported keyboard encoding(s) 61 | * bit 0: ASCII 62 | * bit 1: scancode 63 | * supported_keyboard: support keyboard language(s) 64 | * bit 0: us 65 | * bit 1: fr 66 | * bit 2: gr 67 | 68 | ### load_default_settings 69 | 70 | Reset all settings to factory default. 71 | 72 | ## debugfs interface 73 | 74 | The debugfs interface maps closely to the WMI Interface (see driver and doc). 75 | 76 | * bios_settings: show all BIOS settings 77 | * bios_setting: show BIOS setting for 78 | * list_valid_choices: list settings for 79 | * set_bios_settings: call set bios settings command with . 80 | * save_bios_settings call save bios settings command with . 81 | * discard_bios_settings: call discard bios settings command with . 82 | * load_default: call load default with . 83 | * set_bios_password: call set BIOS password with . 84 | * argument: argument to be used in various commands. 85 | * instance: setting instance. 86 | * instance_count: number of settings. 87 | * password_settings: password settings. 88 | 89 | ## References 90 | 91 | Thinkpad WMI interface documentation: 92 | http://download.lenovo.com/ibmdl/pub/pc/pccbbs/thinkcentre_pdf/hrdeploy_en.pdf 93 | 94 | ## Legal 95 | This code is distributed under GPL-v2 license with full text of the license 96 | located in the COPYING file. 97 | 98 | ## Compile 99 | make 100 | make install - loads this module after a reboot 101 | - check the makefile for default path 102 | make clean - clears the compiled module and removes from the default path 103 | -------------------------------------------------------------------------------- /thinklmi-kernel/think-lmi.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | /* 3 | * Think LMI BIOS configuration driver 4 | * 5 | * Copyright(C) 2019-2020 Lenovo 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | * Original code from Thinkpad-wmi project 22 | * https://github.com/iksaif/thinkpad-wmi 23 | * Copyright(C) 2017 Corentin Chary 24 | * Distributed under the GPL-2.0 license 25 | */ 26 | 27 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include "think-lmi.h" 46 | 47 | #define THINK_LMI_FILE "think-lmi" 48 | 49 | MODULE_AUTHOR("Sugumaran L "); 50 | MODULE_AUTHOR("Mark Pearson "); 51 | MODULE_AUTHOR("Corentin Chary "); 52 | MODULE_DESCRIPTION("Think LMI Driver"); 53 | MODULE_LICENSE("GPL"); 54 | 55 | /* LMI interface */ 56 | 57 | /** 58 | * Name: 59 | * Lenovo_BiosSetting 60 | * Description: 61 | * Get item name and settings for current LMI instance. 62 | * Type: 63 | * Query 64 | * Returns: 65 | * "Item,Value" 66 | * Example: 67 | * "WakeOnLAN,Enable" 68 | */ 69 | #define LENOVO_BIOS_SETTING_GUID \ 70 | "51F5230E-9677-46CD-A1CF-C0B23EE34DB7" 71 | 72 | /** 73 | * Name: 74 | * Lenovo_SetBiosSetting 75 | * Description: 76 | * Change the BIOS setting to the desired value using the 77 | * Lenovo_SetBiosSetting class. To save the settings, 78 | * use the Lenovo_SaveBiosSetting class. 79 | * BIOS settings and values are case sensitive. 80 | * After making changes to the BIOS settings, 81 | * you must reboot the computer 82 | * before the changes will take effect. 83 | * Type: 84 | * Method 85 | * Arguments: 86 | * "Item,Value,Password,Encoding,KbdLang;" 87 | * Example: 88 | * "WakeOnLAN,Disable,pswd,ascii,us;" 89 | */ 90 | #define LENOVO_SET_BIOS_SETTINGS_GUID \ 91 | "98479A64-33F5-4E33-A707-8E251EBBC3A1" 92 | 93 | /** 94 | * Name: 95 | * Lenovo_SaveBiosSettings 96 | * Description: 97 | * Save any pending changes in settings. 98 | * Type: 99 | * Method 100 | * Arguments: 101 | * "Password,Encoding,KbdLang;" 102 | * Example: 103 | * "pswd,ascii,us;" 104 | */ 105 | #define LENOVO_SAVE_BIOS_SETTINGS_GUID \ 106 | "6A4B54EF-A5ED-4D33-9455-B0D9B48DF4B3" 107 | 108 | 109 | /** 110 | * Name: 111 | * Lenovo_DiscardBiosSettings 112 | * Description: 113 | * Discard any pending changes in settings. 114 | * Type: 115 | * Method 116 | * Arguments: 117 | * "Password,Encoding,KbdLang;" 118 | * Example: 119 | * "pswd,ascii,us;" 120 | */ 121 | #define LENOVO_DISCARD_BIOS_SETTINGS_GUID \ 122 | "74F1EBB6-927A-4C7D-95DF-698E21E80EB5" 123 | 124 | /** 125 | * Name: 126 | * Lenovo_LoadDefaultSettings 127 | * Description: 128 | * Load default BIOS settings. Use Lenovo_SaveBiosSettings to save the 129 | * settings. 130 | * Type: 131 | * Method 132 | * Arguments: 133 | * "Password,Encoding,KbdLang;" 134 | * Example: 135 | * "pswd,ascii,us;" 136 | */ 137 | #define LENOVO_LOAD_DEFAULT_SETTINGS_GUID \ 138 | "7EEF04FF-4328-447C-B5BB-D449925D538D" 139 | 140 | /** 141 | * Name: 142 | * Lenovo_BiosPasswordSettings 143 | * Description: 144 | * Return BIOS Password settings 145 | * Type: 146 | * Query 147 | * Returns: 148 | * PasswordMode, PasswordState, MinLength, MaxLength, 149 | * SupportedEncoding, SupportedKeyboard 150 | */ 151 | #define LENOVO_BIOS_PASSWORD_SETTINGS_GUID \ 152 | "8ADB159E-1E32-455C-BC93-308A7ED98246" 153 | 154 | /** 155 | * Name: 156 | * Lenovo_SetBiosPassword 157 | * Description: 158 | * Change a specific password. 159 | * - BIOS settings cannot be changed at the same boot as power-on 160 | * passwords (POP) and hard disk passwords (HDP). If you want to change 161 | * BIOS settings and POP or HDP, you must reboot the system after 162 | * changing one of them. 163 | * - A password cannot be set using this method when one does not already 164 | * exist. Passwords can only be updated or cleared. 165 | * Type: 166 | * Method 167 | * Arguments: 168 | * "PasswordType,CurrentPassword,NewPassword,Encoding,KbdLang;" 169 | * Example: 170 | * "pop,oldpop,newpop,ascii,us;” 171 | */ 172 | #define LENOVO_SET_BIOS_PASSWORD_GUID \ 173 | "2651D9FD-911C-4B69-B94E-D0DED5963BD7" 174 | 175 | /** 176 | * Name: 177 | * Lenovo_GetBiosSelections 178 | * Description: 179 | * Return a list of valid settings for a given item. 180 | * Type: 181 | * Method 182 | * Arguments: 183 | * "Item" 184 | * Returns: 185 | * "Value1,Value2,Value3,..." 186 | * Example: 187 | * -> "FlashOverLAN" 188 | * <- "Enabled,Disabled" 189 | */ 190 | #define LENOVO_GET_BIOS_SELECTIONS_GUID \ 191 | "7364651A-132F-4FE7-ADAA-40C6C7EE2E3B" 192 | 193 | /** 194 | * Name: 195 | * Lenovo_PlatformSettingGUID, Lenovo_SetPlatformSettingGUID 196 | * Description 197 | * debugfs method to get/set platform setting 198 | * Type: 199 | * Method 200 | * Arguments: 201 | * ??? 202 | * Example: 203 | * ??? 204 | * LMI-Internals: 205 | * Return big chunk of data 206 | */ 207 | #define LENOVO_PLATFORM_SETTING_GUID \ 208 | "7430019A-DCE9-4548-BAB0-9FDE0935CAFF" 209 | 210 | #define LENOVO_SET_PLATFORM_SETTINGS_GUID \ 211 | "7FF47003-3B6C-4E5E-A227-E979824A85D1" 212 | /* For future use 213 | * #define LENOVO_QUERY_GUID "05901221-D566-11D1-B2F0-00A0C9062910" 214 | */ 215 | 216 | 217 | /** 218 | * Name: 219 | * Lenovo_lmiopcode_setting_guid 220 | * Description 221 | * Alternative setting method with advanced features 222 | */ 223 | #define LENOVO_LMIOPCODE_SETTING_GUID \ 224 | "DFDDEF2C-57D4-48CE-B196-0FB787D90836" 225 | 226 | #define TLMI_NAME "thinklmi" 227 | 228 | /* Return values */ 229 | enum { 230 | /* 231 | * "Success" 232 | * Operation completed successfully. 233 | */ 234 | THINK_LMI_SUCCESS = 0, 235 | /* 236 | * "Not Supported" 237 | * The feature is not supported on this system. 238 | */ 239 | THINK_LMI_NOT_SUPPORTED = -ENODEV, 240 | /* 241 | * "Invalid" 242 | * The item or value provided is not valid parameter 243 | */ 244 | THINK_LMI_INVALID = -EINVAL, 245 | /* 246 | * "Access Denied" 247 | * The change could not be made due to an authentication problem. 248 | * If a supervisor password exists, the correct supervisor password 249 | * must be provided. 250 | */ 251 | THINK_LMI_ACCESS_DENIED = -EPERM, 252 | /* "System Busy" 253 | * BIOS changes have already been made that need to be committed. 254 | * Reboot the system and try again. 255 | */ 256 | THINK_LMI_SYSTEM_BUSY = -EBUSY 257 | }; 258 | 259 | #define TLMI_NUM_DEVICES 1 260 | 261 | MODULE_ALIAS("tlmi:"LENOVO_BIOS_SETTING_GUID); 262 | 263 | struct think_lmi_pcfg { 264 | uint32_t password_mode; 265 | uint32_t password_state; 266 | uint32_t min_length; 267 | uint32_t max_length; 268 | uint32_t supported_encodings; 269 | uint32_t supported_keyboard; 270 | }; 271 | 272 | struct think_lmi { 273 | struct wmi_device *wmi_device; 274 | 275 | int settings_count; 276 | 277 | char password[TLMI_PWD_MAXLEN]; 278 | char password_encoding[TLMI_ENC_MAXLEN]; 279 | char password_kbdlang[TLMI_LANG_MAXLEN]; /* 2 bytes for \n\0 */ 280 | char auth_string[TLMI_PWD_MAXLEN + TLMI_ENC_MAXLEN 281 | + TLMI_LANG_MAXLEN + 2]; 282 | char password_type[TLMI_PWDTYPE_MAXLEN]; 283 | char tpm_type[TLMI_TPMTYPE_MAXLEN]; 284 | char passcurr[TLMI_PWD_MAXLEN]; 285 | char passnew[TLMI_PWD_MAXLEN]; 286 | 287 | bool can_set_bios_settings; 288 | bool can_discard_bios_settings; 289 | bool can_load_default_settings; 290 | bool can_get_bios_selections; 291 | bool can_set_bios_password; 292 | bool can_get_password_settings; 293 | 294 | unsigned char *settings[TLMI_MAX_SETTINGS]; 295 | struct dev_ext_attribute *devattrs; 296 | struct cdev c_dev; 297 | }; 298 | 299 | static dev_t tlmi_dev; 300 | static struct class *tlmi_class; 301 | 302 | static int think_lmi_errstr_to_err(const char *errstr) 303 | { 304 | if (!strcmp(errstr, "Success")) 305 | return THINK_LMI_SUCCESS; 306 | if (!strcmp(errstr, "Not Supported")) 307 | return THINK_LMI_NOT_SUPPORTED; 308 | if (!strcmp(errstr, "Invalid")) 309 | return THINK_LMI_INVALID; 310 | if (!strcmp(errstr, "Access Denied")) 311 | return THINK_LMI_ACCESS_DENIED; 312 | if (!strcmp(errstr, "System Busy")) 313 | return THINK_LMI_SYSTEM_BUSY; 314 | 315 | pr_debug("Unknown error string: '%s'", errstr); 316 | 317 | return -EINVAL; 318 | } 319 | 320 | static int think_lmi_extract_error(const struct acpi_buffer *output) 321 | { 322 | const union acpi_object *obj; 323 | int ret; 324 | 325 | obj = output->pointer; 326 | if (!obj || obj->type != ACPI_TYPE_STRING || !obj->string.pointer) 327 | return -EIO; 328 | 329 | ret = think_lmi_errstr_to_err(obj->string.pointer); 330 | kfree(obj); 331 | return ret; 332 | } 333 | 334 | static int think_lmi_simple_call(const char *guid, 335 | const char *arg) 336 | { 337 | const struct acpi_buffer input = { strlen(arg), (char *)arg }; 338 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 339 | acpi_status status; 340 | /* 341 | * duplicated call required to match bios workaround for behavior 342 | * seen when WMI accessed via scripting on other OS 343 | */ 344 | status = wmi_evaluate_method(guid, 0, 0, &input, &output); 345 | status = wmi_evaluate_method(guid, 0, 0, &input, &output); 346 | 347 | if (ACPI_FAILURE(status)) 348 | return -EIO; 349 | 350 | return think_lmi_extract_error(&output); 351 | } 352 | 353 | static int think_lmi_extract_output_string(const struct acpi_buffer 354 | *output, char **string) 355 | { 356 | const union acpi_object *obj; 357 | 358 | obj = output->pointer; 359 | if (!obj || obj->type != ACPI_TYPE_STRING || !obj->string.pointer) 360 | return -EIO; 361 | 362 | *string = kstrdup(obj->string.pointer, GFP_KERNEL); 363 | kfree(obj); 364 | return *string ? 0 : -ENOMEM; 365 | } 366 | 367 | static int think_lmi_setting(int item, char **value, 368 | const char *guid_string) 369 | { 370 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 371 | acpi_status status; 372 | 373 | status = wmi_query_block(guid_string, item, &output); 374 | if (ACPI_FAILURE(status)) 375 | return -EIO; 376 | 377 | return think_lmi_extract_output_string(&output, value); 378 | } 379 | 380 | static int think_lmi_get_bios_selections(const char *item, char **value) 381 | { 382 | const struct acpi_buffer input = { strlen(item), (char *)item }; 383 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; 384 | acpi_status status; 385 | 386 | status = wmi_evaluate_method(LENOVO_GET_BIOS_SELECTIONS_GUID, 387 | 0, 0, &input, &output); 388 | 389 | if (ACPI_FAILURE(status)) 390 | return -EIO; 391 | 392 | return think_lmi_extract_output_string(&output, value); 393 | } 394 | 395 | static int think_lmi_set_bios_settings(const char *settings) 396 | { 397 | strreplace(settings,'\\','/'); 398 | return think_lmi_simple_call(LENOVO_SET_BIOS_SETTINGS_GUID, settings); 399 | } 400 | 401 | static int think_lmi_save_bios_settings(const char *password) 402 | { 403 | return think_lmi_simple_call(LENOVO_SAVE_BIOS_SETTINGS_GUID, password); 404 | } 405 | 406 | static int think_lmi_discard_bios_settings(const char *password) 407 | { 408 | return think_lmi_simple_call(LENOVO_DISCARD_BIOS_SETTINGS_GUID, password); 409 | } 410 | 411 | static int think_lmi_set_bios_password(const char *settings) 412 | { 413 | return think_lmi_simple_call(LENOVO_SET_BIOS_PASSWORD_GUID, settings); 414 | } 415 | 416 | static int think_lmi_set_platform_settings(const char *settings) 417 | { 418 | return think_lmi_simple_call(LENOVO_SET_PLATFORM_SETTINGS_GUID, settings); 419 | } 420 | 421 | static int think_lmi_set_lmiopcode_settings(const char *settings) 422 | { 423 | return think_lmi_simple_call(LENOVO_LMIOPCODE_SETTING_GUID, settings); 424 | } 425 | static int think_lmi_load_default(const char *password) 426 | { 427 | return think_lmi_simple_call(LENOVO_LOAD_DEFAULT_SETTINGS_GUID, password); 428 | } 429 | 430 | /* Create the auth string from password chunks */ 431 | static void update_auth_string(struct think_lmi *think) 432 | { 433 | if (!*think->password) { 434 | /* No password at all */ 435 | think->auth_string[0] = '\0'; 436 | return; 437 | } 438 | strcpy(think->auth_string, think->password); 439 | 440 | if (*think->password_encoding) { 441 | strcat(think->auth_string, ","); 442 | strcat(think->auth_string, think->password_encoding); 443 | } 444 | 445 | if (*think->password_kbdlang) { 446 | strcat(think->auth_string, ","); 447 | strcat(think->auth_string, think->password_kbdlang); 448 | } 449 | } 450 | 451 | static int validate_setting_name(struct think_lmi *think, char* setting) 452 | { 453 | int i; 454 | for (i = 0; i <= TLMI_MAX_SETTINGS; i++) { 455 | if (think->settings[i] != NULL) { 456 | if (!strcmp(setting, think->settings[i])) 457 | return i; 458 | } 459 | } 460 | /* No match found - return error condition */ 461 | return -EINVAL; 462 | } 463 | 464 | /* Character device open interface */ 465 | static int think_lmi_chardev_open(struct inode *inode, struct file *file) 466 | { 467 | struct think_lmi *think; 468 | think = container_of(inode->i_cdev, struct think_lmi, c_dev); 469 | file->private_data = think; 470 | return THINK_LMI_SUCCESS; 471 | } 472 | 473 | /* Character device ioctl interface */ 474 | static long think_lmi_chardev_ioctl(struct file *filp, unsigned int cmd, 475 | unsigned long arg) 476 | { 477 | struct think_lmi *think; 478 | int j,ret,item; 479 | unsigned char settings_str[TLMI_SETTINGS_MAXLEN]; 480 | char get_set_string[TLMI_GETSET_MAXLEN]; 481 | char newpassword[TLMI_PWD_MAXLEN]; 482 | char *settings = NULL, *choices = NULL; 483 | char *value; 484 | char *tmp_string = NULL; 485 | ssize_t count =0; 486 | 487 | think = filp->private_data; 488 | switch(cmd){ 489 | case THINKLMI_GET_SETTINGS: 490 | if (copy_to_user((int *)arg, &think->settings_count, 491 | sizeof(think->settings_count))) 492 | return -EFAULT; 493 | break; 494 | case THINKLMI_GET_SETTINGS_STRING: 495 | /* Get the string for given index */ 496 | if (copy_from_user(settings_str, (void *)arg, 497 | sizeof(settings_str))) 498 | return -EFAULT; 499 | j = settings_str[0]; 500 | if ((j > TLMI_MAX_SETTINGS) || (!think->settings[j])) 501 | return -EINVAL; 502 | strncpy(settings_str, think->settings[j], 503 | (TLMI_SETTINGS_MAXLEN-1)); 504 | if (copy_to_user((char *)arg, settings_str, 505 | sizeof(settings_str))) 506 | return -EFAULT; 507 | break; 508 | case THINKLMI_SET_SETTING: 509 | if (copy_from_user(get_set_string, (void *)arg, 510 | sizeof(get_set_string))) 511 | return -EFAULT; 512 | 513 | /* First validate that this is a valid setting name */ 514 | value = strchr(get_set_string, ','); 515 | if (!value) { 516 | ret = -EINVAL; 517 | goto error; 518 | } 519 | tmp_string = kmalloc(value - get_set_string + 1, GFP_KERNEL); 520 | snprintf(tmp_string, value - get_set_string + 1, "%s", 521 | get_set_string); 522 | ret = validate_setting_name(think, tmp_string); 523 | kfree(tmp_string); 524 | if (ret < 0) 525 | goto error; 526 | 527 | /* If authorisation required add that to command */ 528 | if (*think->auth_string) { 529 | count = strlen(get_set_string) + 530 | strlen(think->auth_string) + 2; 531 | tmp_string = kmalloc(count, GFP_KERNEL); 532 | snprintf(tmp_string, count, "%s,%s;", 533 | get_set_string, think->auth_string); 534 | } else { 535 | count = strlen(get_set_string) + 1; 536 | tmp_string = kmalloc(count, GFP_KERNEL); 537 | snprintf(tmp_string, count, "%s;", get_set_string); 538 | } 539 | 540 | ret = think_lmi_set_bios_settings(tmp_string); 541 | kfree(tmp_string); 542 | 543 | ret = think_lmi_save_bios_settings(think->auth_string); 544 | if (ret) { 545 | /* Try to discard the settings 546 | * if we failed to apply them */ 547 | think_lmi_discard_bios_settings(think-> 548 | auth_string); 549 | goto error; 550 | } 551 | break; 552 | case THINKLMI_SHOW_SETTING: 553 | item = -1; 554 | if (copy_from_user(get_set_string, (void *)arg, 555 | sizeof(get_set_string))) 556 | return -EFAULT; 557 | item = validate_setting_name(think, get_set_string); 558 | if (item < 0) { /* Invalid entry */ 559 | ret = -EINVAL; 560 | goto error; 561 | } 562 | /* Do a WMI query for the settings */ 563 | ret = think_lmi_setting(item, &settings, 564 | LENOVO_BIOS_SETTING_GUID); 565 | if (ret) 566 | goto error; 567 | 568 | if (think->can_get_bios_selections) 569 | { 570 | ret = think_lmi_get_bios_selections(get_set_string, 571 | &choices); 572 | if (ret) 573 | goto error; 574 | if (choices) { 575 | value = strchr(settings, ','); 576 | if (!value) 577 | goto error; 578 | value++; 579 | /* Allocate enough space for value, 580 | * choices, return chars and 581 | * null terminate 582 | */ 583 | tmp_string = (char *)kmalloc(strlen(value) 584 | + strlen(choices) + 5, 585 | GFP_KERNEL); 586 | count = sprintf(tmp_string, "%s\n", value); 587 | count += sprintf(tmp_string + count, 588 | "%s\n", choices); 589 | } 590 | } else { 591 | /* BIOS doesn't support choices 592 | * option - it's all in one string */ 593 | tmp_string = (char *)kmalloc(strlen(settings) 594 | + 3, GFP_KERNEL); 595 | count = sprintf(tmp_string, "%s\n", settings); 596 | } 597 | if (count > TLMI_SETTINGS_MAXLEN) { 598 | /* Unlikely to happen - but if the string is going 599 | * to overflow the amount of space that is 600 | * available then we need to truncate. 601 | * Issue a warning so we know about these 602 | */ 603 | count = TLMI_SETTINGS_MAXLEN; 604 | pr_warn("WARNING: Result truncated to fit string buffer\n"); 605 | } 606 | tmp_string[count-1] = '\0'; 607 | if (copy_to_user((char *)arg, tmp_string, count)) { 608 | kfree(tmp_string); 609 | goto error; 610 | } 611 | kfree(tmp_string); 612 | break; 613 | case THINKLMI_AUTHENTICATE: 614 | if (copy_from_user(get_set_string, (void *)arg, 615 | sizeof(get_set_string))) 616 | return -EFAULT; 617 | tmp_string = get_set_string; 618 | value = strsep(&tmp_string, ","); 619 | if (!value) 620 | return -EFAULT; 621 | snprintf(think->password, TLMI_PWD_MAXLEN, "%s", value); 622 | value = strsep(&tmp_string, ","); 623 | if (!value) 624 | return -EFAULT; 625 | snprintf(think->password_encoding, TLMI_ENC_MAXLEN, 626 | "%s", value); 627 | value = strsep(&tmp_string, ","); 628 | if (!value) 629 | return -EFAULT; 630 | snprintf(think->password_kbdlang, TLMI_LANG_MAXLEN, 631 | "%s", value); 632 | 633 | update_auth_string(think); 634 | break; 635 | 636 | case THINKLMI_CHANGE_PASSWORD: 637 | if (copy_from_user(get_set_string, (void *)arg, 638 | sizeof(get_set_string))) 639 | return -EFAULT; 640 | snprintf(settings_str, TLMI_SETTINGS_MAXLEN, "%s", 641 | get_set_string); 642 | tmp_string = get_set_string; 643 | 644 | value = strsep(&tmp_string, ","); 645 | if (!value) 646 | return -EFAULT; 647 | snprintf(think->password_type, TLMI_PWDTYPE_MAXLEN, 648 | "%s",value); 649 | value = strsep(&tmp_string, ","); 650 | if (!value) 651 | return -EFAULT; 652 | snprintf(think->password, TLMI_PWD_MAXLEN, "%s", value); 653 | value = strsep(&tmp_string, ","); 654 | if (!value) 655 | return -EFAULT; 656 | snprintf(newpassword, TLMI_PWD_MAXLEN, "%s",value); 657 | value = strsep(&tmp_string, ","); 658 | if (!value) 659 | return -EFAULT; 660 | snprintf(think->password_encoding, TLMI_ENC_MAXLEN, 661 | "%s",value); 662 | value = strsep(&tmp_string, ","); 663 | if (!value) 664 | return -EFAULT; 665 | snprintf(think->password_kbdlang, TLMI_LANG_MAXLEN, 666 | "%s",value); 667 | 668 | update_auth_string(think); 669 | 670 | ret = think_lmi_set_bios_password(settings_str); 671 | break; 672 | 673 | case THINKLMI_DEBUG: 674 | if (copy_from_user(get_set_string, (void *)arg, 675 | sizeof(get_set_string))) 676 | return -EFAULT; 677 | snprintf(settings_str, TLMI_SETTINGS_MAXLEN, "%s", 678 | get_set_string); 679 | ret = think_lmi_set_platform_settings(settings_str); 680 | if (ret) { 681 | goto error; 682 | } 683 | break; 684 | 685 | case THINKLMI_LMIOPCODE: 686 | if (copy_from_user(get_set_string, (void *)arg, sizeof(get_set_string))) 687 | return -EFAULT; 688 | snprintf(settings_str, TLMI_SETTINGS_MAXLEN, "%s", get_set_string); 689 | 690 | tmp_string = get_set_string; 691 | 692 | value = strsep(&tmp_string, ","); 693 | if (!value) 694 | return -EFAULT; 695 | 696 | snprintf(think->password, TLMI_PWD_MAXLEN, "%s", get_set_string); 697 | sprintf(settings_str, "WmiOpcodePasswordAdmin:%s;", think->password); 698 | 699 | ret = think_lmi_set_lmiopcode_settings(settings_str); 700 | if (ret) 701 | goto error; 702 | 703 | value = strsep(&tmp_string, ","); 704 | if (!value) 705 | return -EFAULT; 706 | 707 | snprintf(think->password_type, TLMI_PWDTYPE_MAXLEN, "%s", value); 708 | sprintf(settings_str, "WmiOpcodePasswordType:%s;", think->password_type); 709 | 710 | ret = think_lmi_set_lmiopcode_settings(settings_str); 711 | if (ret) 712 | goto error; 713 | 714 | value = strsep(&tmp_string, ","); 715 | if (!value) 716 | return -EFAULT; 717 | 718 | snprintf(think->passcurr, TLMI_PWD_MAXLEN, "%s", value); 719 | sprintf(settings_str, "WmiOpcodePasswordCurrent01:%s;", think->passcurr); 720 | ret = think_lmi_set_lmiopcode_settings(settings_str); 721 | if (ret) 722 | goto error; 723 | 724 | value = strsep(&tmp_string, ","); 725 | if (!value) 726 | return -EFAULT; 727 | 728 | snprintf(think->passnew, TLMI_PWD_MAXLEN, "%s", value); 729 | sprintf(settings_str, "WmiOpcodePasswordNew01:%s", think->passnew); 730 | ret = think_lmi_set_lmiopcode_settings(settings_str); 731 | if (ret) 732 | goto error; 733 | 734 | sprintf(settings_str, "WmiOpcodePasswordSetUpdate;"); 735 | ret = think_lmi_set_lmiopcode_settings(settings_str); 736 | if (ret) 737 | goto error; 738 | 739 | break; 740 | case THINKLMI_TPMTYPE: 741 | if (copy_from_user(get_set_string, (void *)arg, 742 | sizeof(get_set_string))) 743 | return -EFAULT; 744 | 745 | sprintf(settings_str, "WmiOpcodeTPM:"); 746 | strncat(settings_str, get_set_string, TLMI_SETTINGS_MAXLEN); 747 | ret = think_lmi_set_lmiopcode_settings(settings_str); 748 | if (ret) 749 | return -EFAULT; 750 | ret = think_lmi_save_bios_settings(think->auth_string); 751 | if (ret) 752 | return -EFAULT; 753 | 754 | break; 755 | case THINKLMI_LOAD_DEFAULT: 756 | ret = think_lmi_load_default(think->auth_string); 757 | if (ret) 758 | return -EFAULT; 759 | break; 760 | case THINKLMI_SAVE_SETTINGS: 761 | ret = think_lmi_save_bios_settings(think->auth_string); 762 | if (ret) 763 | return -EFAULT; 764 | break; 765 | default: 766 | return -EINVAL; 767 | } 768 | 769 | return THINK_LMI_SUCCESS; 770 | 771 | error: 772 | kfree(settings); 773 | kfree(choices); 774 | return ret ? ret : count; 775 | } 776 | 777 | static int think_lmi_chardev_release(struct inode *inode, 778 | struct file *file) 779 | { 780 | return THINK_LMI_SUCCESS; 781 | } 782 | 783 | static const struct file_operations think_lmi_chardev_fops = { 784 | .open = think_lmi_chardev_open, 785 | .unlocked_ioctl = think_lmi_chardev_ioctl, 786 | .release = think_lmi_chardev_release, 787 | }; 788 | 789 | static void think_lmi_chardev_initialize(struct think_lmi *think) 790 | { 791 | int ret; 792 | struct device *dev_ret; 793 | 794 | ret = alloc_chrdev_region(&tlmi_dev, 0, TLMI_NUM_DEVICES, TLMI_NAME); 795 | if (ret < 0) { 796 | pr_warn("tlmi: char dev allocation failed\n"); 797 | return; 798 | } 799 | 800 | cdev_init(&think->c_dev, &think_lmi_chardev_fops); 801 | 802 | ret = cdev_add(&think->c_dev, tlmi_dev, TLMI_NUM_DEVICES); 803 | if (ret < 0) { 804 | pr_warn("tlmi: char dev registration failed\n"); 805 | unregister_chrdev_region(tlmi_dev, TLMI_NUM_DEVICES); 806 | return; 807 | } 808 | 809 | tlmi_class = class_create(THIS_MODULE,"char"); 810 | if (IS_ERR(tlmi_class)) { 811 | pr_warn("tlmi: char dev class creation failed\n"); 812 | cdev_del(&think->c_dev); 813 | unregister_chrdev_region(tlmi_dev, TLMI_NUM_DEVICES); 814 | return; 815 | } 816 | dev_ret = device_create(tlmi_class, NULL, tlmi_dev, 817 | NULL, "thinklmi"); 818 | if (IS_ERR(dev_ret)) { 819 | pr_warn("tlmi: char dev device creation failed\n"); 820 | class_destroy(tlmi_class); 821 | cdev_del(&think->c_dev); 822 | unregister_chrdev_region(tlmi_dev, TLMI_NUM_DEVICES); 823 | } 824 | } 825 | 826 | static void think_lmi_chardev_exit(struct think_lmi *think) 827 | { 828 | device_destroy(tlmi_class, tlmi_dev); 829 | class_destroy(tlmi_class); 830 | cdev_del(&think->c_dev); 831 | unregister_chrdev_region(tlmi_dev, TLMI_NUM_DEVICES); 832 | } 833 | 834 | static void think_lmi_analyze(struct think_lmi *think) 835 | { 836 | acpi_status status; 837 | int i = 0; 838 | 839 | /* 840 | * Try to find the number of valid settings of this machine 841 | * and use it to create sysfs attributes 842 | */ 843 | for (i = 0; i < TLMI_MAX_SETTINGS; ++i) { 844 | char *item = NULL; 845 | int spleng = 0; 846 | int num = 0; 847 | char *p; 848 | 849 | status = think_lmi_setting(i, &item, 850 | LENOVO_BIOS_SETTING_GUID); 851 | if (ACPI_FAILURE(status)) 852 | break; 853 | if (!item ) 854 | break; 855 | if (!*item) 856 | continue; 857 | 858 | /* It is not allowed to have '/' for file name. 859 | * Convert it into '\'. */ 860 | spleng = strlen(item); 861 | for (num = 0; num < spleng; num++) { 862 | if (item[num] == '/') 863 | item[num] = '\\'; 864 | } 865 | 866 | /* Remove the value part */ 867 | p = strchr(item, ','); 868 | if (p) 869 | *p = '\0'; 870 | think->settings[i] = item; /* Cache setting name */ 871 | think->settings_count++; 872 | } 873 | 874 | if (wmi_has_guid(LENOVO_SET_BIOS_SETTINGS_GUID) && 875 | wmi_has_guid(LENOVO_SAVE_BIOS_SETTINGS_GUID)) 876 | think->can_set_bios_settings = true; 877 | 878 | if (wmi_has_guid(LENOVO_DISCARD_BIOS_SETTINGS_GUID)) 879 | think->can_discard_bios_settings = true; 880 | 881 | if (wmi_has_guid(LENOVO_LOAD_DEFAULT_SETTINGS_GUID)) 882 | think->can_load_default_settings = true; 883 | 884 | if (wmi_has_guid(LENOVO_GET_BIOS_SELECTIONS_GUID)) 885 | think->can_get_bios_selections = true; 886 | 887 | if (wmi_has_guid(LENOVO_SET_BIOS_PASSWORD_GUID)) 888 | think->can_set_bios_password = true; 889 | 890 | if (wmi_has_guid(LENOVO_BIOS_PASSWORD_SETTINGS_GUID)) 891 | think->can_get_password_settings = true; 892 | } 893 | 894 | static int think_lmi_add(struct wmi_device *wdev) 895 | { 896 | struct think_lmi *think; 897 | 898 | think = kzalloc(sizeof(struct think_lmi), GFP_KERNEL); 899 | if (!think) 900 | return -ENOMEM; 901 | 902 | think->wmi_device = wdev; 903 | dev_set_drvdata(&wdev->dev, think); 904 | 905 | think_lmi_chardev_initialize(think); 906 | 907 | think_lmi_analyze(think); 908 | return 0; 909 | } 910 | 911 | static 912 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) 913 | void 914 | #else 915 | int 916 | #endif 917 | think_lmi_remove(struct wmi_device *wdev) 918 | { 919 | struct think_lmi *think; 920 | int i; 921 | 922 | think = dev_get_drvdata(&wdev->dev); 923 | think_lmi_chardev_exit(think); 924 | 925 | for (i = 0; think->settings[i]; ++i) { 926 | kfree(think->settings[i]); 927 | think->settings[i] = NULL; 928 | } 929 | 930 | kfree(think); 931 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) 932 | return; 933 | #else 934 | return 0; 935 | #endif 936 | } 937 | 938 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) 939 | static int think_lmi_probe(struct wmi_device *wdev, const void *context) 940 | #else 941 | static int think_lmi_probe(struct wmi_device *wdev) 942 | #endif 943 | { 944 | return think_lmi_add(wdev); 945 | } 946 | 947 | static const struct wmi_device_id think_lmi_id_table[] = { 948 | /* Search for Lenovo_BiosSetting */ 949 | { .guid_string = LENOVO_BIOS_SETTING_GUID }, 950 | { }, 951 | }; 952 | 953 | static struct wmi_driver think_lmi_driver = { 954 | .driver = { 955 | .name = "think-lmi", 956 | }, 957 | .id_table = think_lmi_id_table, 958 | .probe = think_lmi_probe, 959 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) 960 | .remove = think_lmi_remove, 961 | #else 962 | .remove = (int (*)(struct wmi_device *))think_lmi_remove, 963 | #endif 964 | }; 965 | 966 | static int __init think_lmi_init(void) 967 | { 968 | return wmi_driver_register(&think_lmi_driver); 969 | } 970 | 971 | static void __exit think_lmi_exit(void) 972 | { 973 | wmi_driver_unregister(&think_lmi_driver); 974 | } 975 | 976 | module_init(think_lmi_init); 977 | module_exit(think_lmi_exit); 978 | -------------------------------------------------------------------------------- /thinklmi-kernel/think-lmi.conf: -------------------------------------------------------------------------------- 1 | # Config file to auto-load the think-lmi kernel module. 2 | # 3 | # This file should be installed to "/etc/modules-load.d/". It tries to load 4 | # think-lmi module located in: "/lib/modules/$(uname -r)/extra/" with system 5 | # startup. 6 | think-lmi 7 | -------------------------------------------------------------------------------- /thinklmi-kernel/think-lmi.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 | 3 | #ifndef _THINK_LMI_H_ 4 | #define _THINK_LMI_H_ 5 | 6 | #include 7 | 8 | #define TLMI_SETTINGS_MAXLEN 512 9 | #define TLMI_PWD_MAXLEN 64 10 | #define TLMI_PWDTYPE_MAXLEN 64 11 | #define TLMI_TPMTYPE_MAXLEN 64 12 | #define TLMI_ENC_MAXLEN 64 13 | #define TLMI_LANG_MAXLEN 4 14 | #define TLMI_MAX_SETTINGS 255 15 | /* 16 | * Longest string should be in the set command: allow size of BIOS 17 | * option and choice 18 | */ 19 | #define TLMI_GETSET_MAXLEN (TLMI_SETTINGS_MAXLEN + TLMI_SETTINGS_MAXLEN) 20 | 21 | #define THINKLMI_GET_SETTINGS _IOR('T', 1, int *) 22 | #define THINKLMI_GET_SETTINGS_STRING _IOWR('T', 2, char *) 23 | #define THINKLMI_SET_SETTING _IOW('T', 3, char *) 24 | #define THINKLMI_SHOW_SETTING _IOWR('T', 4, char *) 25 | #define THINKLMI_AUTHENTICATE _IOW('T', 5, char *) 26 | #define THINKLMI_CHANGE_PASSWORD _IOW('T', 6, char *) 27 | #define THINKLMI_DEBUG _IOW('T', 7, char *) 28 | #define THINKLMI_LMIOPCODE _IOW('T', 8, char *) 29 | #define THINKLMI_TPMTYPE _IOW('T', 10, char *) 30 | #define THINKLMI_LOAD_DEFAULT _IOW('T', 11, char *) 31 | #define THINKLMI_SAVE_SETTINGS _IOW('T', 12, char *) 32 | 33 | #endif /* !_THINK_LMI_H_ */ 34 | 35 | -------------------------------------------------------------------------------- /thinklmi-user/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | 283 | -------------------------------------------------------------------------------- /thinklmi-user/README.md: -------------------------------------------------------------------------------- 1 | # think-lmi : Userspace Utlity 2 | 3 | Linux userspace utility for Think WMI interface. 4 | When used in conjunction with the thinklmi kernel driver this utility allows you 5 | to easily control many BIOS settings from Linux using simple commands 6 | 7 | To compile: gcc -o thinklmi thinklmi.c 8 | 9 | ## display available settings 10 | ./thinklmi getsettings 11 | 12 | This retrieves all available settings that are available from the BIOS 13 | 14 | ## Get setting value 15 | ./thinklmi -g [BIOS Setting] 16 | 17 | Retrieves the given settings current value and lists available options for setting 18 | 19 | eg: ./thinklmi -g WakeOnLANDock 20 | The above command will get the available options for WakeOnLANDock 21 | 22 | ## Set setting value 23 | ./thinklmi -s [BIOS Setting] [option] 24 | 25 | Sets the given setting to the given value 26 | 27 | eg: ./thinklmi -s WakeOnLANDock Enable 28 | The above command will enable the WakeOnLANDock feature 29 | 30 | ## password authentication 31 | ./thinklmi -p [Password] [encoding] [keyboard language] 32 | 33 | Performs password authentication 34 | 35 | Must contain the BIOS supervisor password (aka 'pap'), if set, to be able to do 36 | any change. 37 | 38 | Every subsequent password change will be authorized with this password. The 39 | password may be unloaded by writing an empty string. Writing an invalid 40 | password may trigger the BIOS' invalid password limit, such that a reboot will 41 | be required in order to make any further BIOS changes. 42 | 43 | The encoding used for the password is either '', 'scancode' or 'ascii'. 44 | 45 | Scan-code encoding appears to require the key-down scan codes, e.g. 0x1e, 0x30, 46 | 0x2e for the ASCII encoded password 'abc'. 47 | 48 | The keyboard language mapping, can be '', 'us', 'fr' or 'gr'. 49 | 50 | eg: ./thinklmi -p hello ascii us 51 | If the supervisor password is set as hello, with ascii encoding 52 | and the keyboard type is US, the above command will authenticate the BIOS setting 53 | Once authenticated, it remains valid till the next restart. 54 | 55 | ## Password change 56 | ./thinklmi -c [Password] [New Password] [Password Type] [encoding] [keyboard language] 57 | 58 | This configures a new BIOS password. Use with care. 59 | 60 | The password type can be either 'pap' for the supervisor password or 'pop' for the power on password 61 | 62 | eg: ./thinklmi -p hello newpd pap ascii us 63 | Change the supervisor password or power on password using this command. 64 | Do a reboot for the new password to take effect. 65 | 66 | ## Debug 67 | ./thinklmi -d [BIOS Setting] [option] 68 | 69 | This configures the BIOS setting in debug mode. Use with care. 70 | 71 | eg: ./thinklmi -d FnSticky Enable 72 | 73 | ## Change Password using LMIOPCODE 74 | ./thinklmi -w [Admin Password] [Password Type] [Old Password] [New Pasword] 75 | 76 | This command changes the password on thinkstation systems, with Admin password 77 | The password type can be any BIOS supported password like pop, pap, mhdp, uhdp etc. 78 | 79 | eg: ./thinklmi -w hello pop oldpass newpass 80 | 81 | ## Change Password using LMIOPCODE, without Admin Password 82 | ./thinklmi -w [Password Type] [Old Password] [New Password] 83 | 84 | This command changes the password in thinkstation systems, without an Admin password 85 | 86 | eg: ./thinklmi -w pop oldpass newpass 87 | 88 | ## TPMTYPE Change 89 | ./thinklmi -t [TPM Type] 90 | 91 | This command changes the TPM Type in thinkstation systems 92 | The possible tpmtype values are tpm12, ftpm and tpm20 93 | 94 | eg: ./thinklmi -t tpm12 95 | 96 | ## Load Default Settings 97 | ./thinklmi -l 98 | 99 | This command loads the Default BIOS Settings 100 | 101 | ## Save Settings 102 | ./thinklmi save settings 103 | 104 | This command saves the BIOS Settings 105 | 106 | ## Discard Default Settings 107 | ./thinklmi discard settings 108 | 109 | This command discards the Default BIOS Settings 110 | 111 | ## References 112 | Thinkpad WMI interface documentation: 113 | http://download.lenovo.com/ibmdl/pub/pc/pccbbs/thinkcentre_pdf/hrdeploy_en.pdf 114 | 115 | ## Legal 116 | This code is distributed under GPL-v2 license with full text of the license 117 | located in the COPYING file. 118 | -------------------------------------------------------------------------------- /thinklmi-user/thinklmi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Think LMI BIOS configuration application 3 | * 4 | * Copyright(C) 2019-2020 Lenovo 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | */ 20 | 21 | /* Application to provide ioctl access to BIOS settings*/ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "../thinklmi-kernel/think-lmi.h" 33 | 34 | void get_settings_all(int fd) 35 | { 36 | int i, settings_count; 37 | unsigned char settings_str[TLMI_SETTINGS_MAXLEN]; 38 | 39 | if (ioctl(fd, THINKLMI_GET_SETTINGS, &settings_count) == -1) { 40 | perror("query_apps ioctl get"); 41 | } else { 42 | printf("Total settings: %d\n", settings_count); 43 | for(i=0; i <= TLMI_MAX_SETTINGS; i++) 44 | { 45 | settings_str[0] = i; 46 | 47 | if (ioctl(fd, THINKLMI_GET_SETTINGS_STRING, &settings_str) >= 0) 48 | printf("%3.3d: %s\n", i, settings_str); 49 | /*else 50 | printf("%3.3d:\n", i);*/ 51 | } 52 | } 53 | } 54 | 55 | void thinklmi_get(int fd, char * argv2) 56 | { 57 | char settings_str[TLMI_SETTINGS_MAXLEN]; 58 | int err; 59 | strncpy(settings_str, argv2, TLMI_SETTINGS_MAXLEN); 60 | err = ioctl(fd, THINKLMI_SHOW_SETTING, &settings_str); 61 | if(err == -1) 62 | perror("Invalid setting name"); 63 | else 64 | printf("%s\n", settings_str); 65 | } 66 | 67 | void thinklmi_set(int fd, char * argv2, char* argv3) 68 | { 69 | char setting_string[TLMI_GETSET_MAXLEN]; 70 | strncpy(setting_string, argv2, TLMI_SETTINGS_MAXLEN); 71 | strcat(setting_string, ","); 72 | strncat(setting_string, argv3, TLMI_SETTINGS_MAXLEN); 73 | 74 | if(ioctl(fd, THINKLMI_SET_SETTING, &setting_string) == -1) { 75 | perror("Unable to change setting"); 76 | } else { 77 | printf("BIOS Setting changed\n"); 78 | printf("Setting will not change until reboot\n"); 79 | } 80 | } 81 | 82 | void thinklmi_authenticate(int fd, char *passwd, char *encode, char *lang ) 83 | { 84 | char setting_string[TLMI_GETSET_MAXLEN]; 85 | 86 | snprintf(setting_string, TLMI_GETSET_MAXLEN, "%s,%s,%s", passwd, encode, lang); 87 | if(ioctl(fd, THINKLMI_AUTHENTICATE, &setting_string) == -1) { 88 | perror("BIOS authenticate failed"); 89 | } else { 90 | printf("BIOS authentication completed\n"); 91 | printf("This will be valid till the next reboot\n"); 92 | } 93 | } 94 | 95 | void thinklmi_change_password(int fd, char *oldpass, char *newpass, char *passtype, char *encode, char *lang) 96 | { 97 | char setting_string[TLMI_GETSET_MAXLEN]; 98 | 99 | snprintf(setting_string, TLMI_GETSET_MAXLEN, "%s,%s,%s,%s,%s;", passtype, oldpass, newpass, encode, lang); 100 | if(ioctl(fd, THINKLMI_CHANGE_PASSWORD, &setting_string) == -1) { 101 | perror("BIOS password change failed"); 102 | } else { 103 | printf("BIOS password changed\n"); 104 | printf("Setting will not change until reboot\n"); 105 | } 106 | } 107 | 108 | void thinklmi_debug(int fd, char *settingname, char *value) 109 | { 110 | char setting_string[TLMI_GETSET_MAXLEN]; 111 | strncpy(setting_string, settingname, TLMI_SETTINGS_MAXLEN); 112 | strcat(setting_string, ","); 113 | strncat(setting_string, value, TLMI_SETTINGS_MAXLEN); 114 | if(ioctl(fd, THINKLMI_DEBUG, &setting_string) == -1) { 115 | perror("Debug Setting Error"); 116 | } else { 117 | printf("Debug Setting changed\n"); 118 | } 119 | } 120 | 121 | void thinklmi_lmiopcode(int fd, char *admin, char *passtype, char *oldpass, char *newpass ) 122 | { 123 | char setting_string[TLMI_GETSET_MAXLEN]; 124 | snprintf(setting_string, TLMI_GETSET_MAXLEN, "%s,%s,%s,%s;", admin, passtype, oldpass, newpass); 125 | if(ioctl(fd, THINKLMI_LMIOPCODE, &setting_string) == -1) { 126 | perror("BIOS password change failed"); 127 | } else { 128 | printf("BIOS password changed\n"); 129 | printf("Setting will not change until reboot\n"); 130 | } 131 | } 132 | 133 | void thinklmi_tpmtype(int fd, char *tpmtype) 134 | { 135 | char setting_string[TLMI_GETSET_MAXLEN]; 136 | char option; 137 | 138 | printf("Before switching TPM, please make sure the TPM is not in use and all TPM related applications\n"); 139 | printf("must be disabled, otherwise the TPM will be cleared and you may not be able to access your data\n"); 140 | printf("\n Do you wish to continue(Y/N):"); 141 | scanf("%c", &option); 142 | if(tolower(option) == 'y' && tolower(option) != 'n') { 143 | snprintf(setting_string, TLMI_GETSET_MAXLEN, "%s;", tpmtype); 144 | if(ioctl(fd, THINKLMI_TPMTYPE, &setting_string) == -1) { 145 | perror("TPM type change failed"); 146 | } else { 147 | printf("TPM type changed\n"); 148 | printf("Setting will not change until reboot\n"); 149 | } 150 | } 151 | } 152 | 153 | void thinklmi_load_default(int fd) 154 | { 155 | if(ioctl(fd, THINKLMI_LOAD_DEFAULT) == -1) { 156 | perror(" Error loading Default Settings\n"); 157 | } else { 158 | printf("Default Settings Loaded\n"); 159 | } 160 | } 161 | 162 | 163 | void thinklmi_save_settings(int fd) 164 | { 165 | if(ioctl(fd, THINKLMI_SAVE_SETTINGS) == -1) { 166 | perror(" Error saving Settings\n"); 167 | } else { 168 | printf("Settings saved\n"); 169 | } 170 | } 171 | 172 | static void show_usage(void) 173 | { 174 | fprintf(stdout, "Usage: thinklmi [-g | -s | -p | -c | -d | -l | -w | getsettings| save settings] \n"); 175 | fprintf(stdout, "Option details: \n"); 176 | fprintf(stdout, "\t getsettings - display all available BIOS options: \n"); 177 | fprintf(stdout, "\t -g [BIOS option] - Get the current setting and choices for given BIOS option\n"); 178 | fprintf(stdout, "\t -s [BIOS option] [value] - Set the given BIOS option to given value\n"); 179 | fprintf(stdout, "\t -p [password] [encoding] [kbdlang] - Set authentication details. \n"); 180 | fprintf(stdout, "\t -c [password] [new password] [password type] [encoding] [kbdlang] - Change password. \n"); 181 | fprintf(stdout, "\t -d [debug setting] [option]\n"); 182 | fprintf(stdout, "\t -l load default settings\n"); 183 | fprintf(stdout, "\t -w [Admin password] [password type] [current password] [new password] - Change password using lmiopcode. \n"); 184 | fprintf(stdout, "\t -t [tpm type] - Change tpm type\n"); 185 | fprintf(stdout, "\t save settings - save BIOS settings \n"); 186 | fprintf(stdout, "Notes: \n"); 187 | fprintf(stdout, "\t password type can be \"pap\" or \"pop\" \n"); 188 | fprintf(stdout, "\t encoding can be \"ascii\" or \"scancode\" \n"); 189 | fprintf(stdout, "\t kbdland can be \"us\" or \"fr\" or \"gr\"\n"); 190 | exit(1); 191 | } 192 | 193 | int main(int argc, char *argv[]) 194 | { 195 | char *file_name = "/dev/thinklmi"; 196 | int fd; 197 | enum { 198 | get_settings, 199 | get, 200 | set, 201 | authenticate, 202 | change_password, 203 | debug, 204 | lmiopcode, 205 | tpmtype, 206 | load_default, 207 | save_settings 208 | } option; 209 | 210 | if (getuid()!=0) { 211 | printf("Please run with administrator privileges\n"); 212 | exit(0); 213 | } 214 | switch(argc) 215 | { 216 | 217 | case 2: 218 | if (strcmp(argv[1], "getsettings") == 0) 219 | option = get_settings; 220 | else 221 | 222 | if (strcmp(argv[1], "-l") == 0) 223 | option = load_default; 224 | else 225 | show_usage(); 226 | break; 227 | case 3: 228 | if (strcmp(argv[1], "-g") == 0) 229 | option = get; 230 | else 231 | 232 | if (strcmp(argv[1], "save") == 0) 233 | option = save_settings; 234 | else 235 | 236 | if (strcmp(argv[1], "-t") == 0) 237 | option = tpmtype; 238 | 239 | else 240 | show_usage(); 241 | break; 242 | case 4: 243 | if (strcmp(argv[1], "-s") == 0) { 244 | option = set; 245 | } else 246 | 247 | if (strcmp(argv[1], "-d") == 0) { 248 | option = debug; 249 | } else 250 | show_usage(); 251 | break; 252 | case 5: 253 | if (strcmp(argv[1], "-p") == 0) 254 | option = authenticate; 255 | else 256 | show_usage(); 257 | break; 258 | case 6: 259 | if (strcmp(argv[1], "-w") == 0) 260 | option = lmiopcode; 261 | else 262 | show_usage(); 263 | break; 264 | case 7: 265 | if (strcmp(argv[1], "-c") == 0) 266 | option = change_password; 267 | else 268 | show_usage(); 269 | break; 270 | case 8: 271 | if (strcmp(argv[1], "-l") == 0) 272 | option = load_default; 273 | else 274 | show_usage(); 275 | break; 276 | default: 277 | show_usage(); 278 | return 1; 279 | } 280 | fd = open(file_name, O_RDWR); 281 | if (fd == -1) { 282 | perror("query_apps open"); 283 | return 2; 284 | } 285 | 286 | switch (option) { 287 | case get_settings: 288 | get_settings_all(fd); 289 | break; 290 | case get: 291 | thinklmi_get(fd, argv[2]); 292 | break; 293 | case set: 294 | thinklmi_set(fd, argv[2], argv[3]); 295 | break; 296 | case authenticate: 297 | thinklmi_authenticate(fd, argv[2], argv[3], argv[4]); 298 | break; 299 | case change_password: 300 | thinklmi_change_password(fd, argv[2], argv[3], argv[4], argv[5], argv[6]); 301 | break; 302 | case debug: 303 | thinklmi_debug(fd, argv[2], argv[3]); 304 | break; 305 | case lmiopcode: 306 | thinklmi_lmiopcode(fd, argv[2], argv[3], argv[4], argv[5]); 307 | break; 308 | case tpmtype: 309 | thinklmi_tpmtype(fd, argv[2]); 310 | break; 311 | case load_default: 312 | thinklmi_load_default(fd); 313 | break; 314 | case save_settings: 315 | thinklmi_save_settings(fd); 316 | break; 317 | } 318 | close (fd); 319 | 320 | return 0; 321 | } 322 | --------------------------------------------------------------------------------