├── .gitignore ├── LICENSE ├── QRunInfo.pri ├── QRunInfo.pro ├── README.md ├── adminauthorization.h ├── adminauthorization_mac.cpp ├── adminauthorization_win.cpp ├── adminauthorization_x11.cpp ├── kdselfrestarter.cpp ├── kdselfrestarter.h ├── kdsysinfo.cpp ├── kdsysinfo.h ├── kdsysinfo_mac.cpp ├── kdsysinfo_win.cpp ├── kdsysinfo_x11.cpp ├── link.cpp ├── link.h ├── qruninfo_global.h ├── sysinfo_win.cpp ├── win32path.cpp └── win32path.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.user 2 | *.user.* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 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 | (This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.) 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | {description} 474 | Copyright (C) {year} {fullname} 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | {signature of Ty Coon}, 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | 506 | -------------------------------------------------------------------------------- /QRunInfo.pri: -------------------------------------------------------------------------------- 1 | 2 | CONFIG += C++11 3 | 4 | HEADERS +=\ 5 | $$PWD/qruninfo_global.h \ 6 | $$PWD/adminauthorization.h \ 7 | $$PWD/kdselfrestarter.h \ 8 | $$PWD/kdsysinfo.h \ 9 | $$PWD/link.h 10 | 11 | SOURCES += \ 12 | $$PWD/kdselfrestarter.cpp \ 13 | $$PWD/kdsysinfo.cpp \ 14 | $$PWD/link.cpp 15 | 16 | unix:!mac { 17 | SOURCES += \ 18 | $$PWD/adminauthorization_x11.cpp \ 19 | $$PWD/kdsysinfo_x11.cpp 20 | } 21 | 22 | win32 { 23 | HEADERS += $$PWD/win32path.h 24 | 25 | SOURCES += \ 26 | $$PWD/adminauthorization_win.cpp \ 27 | $$PWD/kdsysinfo_win.cpp \ 28 | $$PWD/sysinfo_win.cpp \ 29 | $$PWD/win32path.cpp 30 | 31 | LIBS += -lole32 -lshell32 -lmpr -lAdvapi32 32 | 33 | win32-g++*:LIBS += -luuid 34 | win32-g++*:QMAKE_CXXFLAGS += -Wno-missing-field-initializers 35 | } 36 | 37 | mac { 38 | SOURCES += \ 39 | $$PWD/kdsysinfo_mac.cpp \ 40 | $$PWD/adminauthorization_mac.cpp \ 41 | LIBS += -framework Carbon -framework Security 42 | } 43 | 44 | INCLUDEPATH += $$PWD/ 45 | -------------------------------------------------------------------------------- /QRunInfo.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-10-23T16:35:17 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets 8 | 9 | TARGET = $$qtLibraryTarget(QRunInfo) 10 | TEMPLATE = lib 11 | 12 | DEFINES += QRUNINFO_LIBRARY 13 | 14 | include(QRunInfo.pri) 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dushibaiyu/QRunInfo/a0ce8e9836ab60bcc0ce0a383258c50d4c944a09/README.md -------------------------------------------------------------------------------- /adminauthorization.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #ifndef ADMINAUTHORIZATION_H 36 | #define ADMINAUTHORIZATION_H 37 | 38 | #include "qruninfo_global.h" 39 | #include 40 | 41 | namespace QRunInfo { 42 | 43 | class QRUNINFOSHARED_EXPORT AdminAuthorization 44 | { 45 | public: 46 | static bool hasAdminRights(); 47 | static bool execute(QWidget *parent, const QString &programs, const QStringList &arguments); 48 | 49 | private: 50 | AdminAuthorization(){}}; 51 | 52 | } // QRUNINFO_NAMEPASE_END 53 | 54 | #endif // ADMINAUTHORIZATION_H 55 | -------------------------------------------------------------------------------- /adminauthorization_mac.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #include "adminauthorization.h" 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | namespace QRunInfo { 46 | 47 | bool AdminAuthorization::execute(QWidget *, const QString &program, const QStringList &arguments) 48 | { 49 | AuthorizationRef authorizationRef; 50 | OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, 51 | kAuthorizationFlagDefaults, &authorizationRef); 52 | if (status != errAuthorizationSuccess) 53 | return false; 54 | 55 | AuthorizationItem item = { kAuthorizationRightExecute, 0, 0, 0 }; 56 | AuthorizationRights rights = { 1, &item }; 57 | const AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed 58 | | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; 59 | 60 | status = AuthorizationCopyRights(authorizationRef, &rights, kAuthorizationEmptyEnvironment, 61 | flags, 0); 62 | if (status != errAuthorizationSuccess) 63 | return false; 64 | 65 | QVector args; 66 | QVector utf8Args; 67 | foreach (const QString &argument, arguments) { 68 | utf8Args.push_back(argument.toUtf8()); 69 | args.push_back(utf8Args.last().data()); 70 | } 71 | args.push_back(0); 72 | 73 | const QByteArray utf8Program = program.toUtf8(); 74 | status = AuthorizationExecuteWithPrivileges(authorizationRef, utf8Program.data(), 75 | kAuthorizationFlagDefaults, args.data(), 0); 76 | 77 | AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights); 78 | return status == errAuthorizationSuccess; 79 | } 80 | 81 | bool AdminAuthorization::hasAdminRights() 82 | { 83 | return geteuid() == 0; 84 | } 85 | 86 | } // QRUNINFO_NAMEPASE_END 87 | -------------------------------------------------------------------------------- /adminauthorization_win.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #ifdef _MSC_VER 36 | #pragma execution_character_set("utf-8") 37 | #endif 38 | 39 | 40 | #include "adminauthorization.h" 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | #include "win32path.h" 48 | 49 | #ifdef Q_CC_MINGW 50 | # ifndef SEE_MASK_NOASYNC 51 | # define SEE_MASK_NOASYNC 0x00000100 52 | # endif 53 | #endif 54 | 55 | namespace QRunInfo { 56 | // taken from qprocess_win.cpp 57 | static QString qt_create_commandline(const QString &program, const QStringList &arguments) 58 | { 59 | QString args; 60 | if (!program.isEmpty()) { 61 | QString programName = program; 62 | if (!programName.startsWith(QLatin1Char('\"')) && !programName.endsWith(QLatin1Char('\"')) 63 | && programName.contains(QLatin1Char(' '))) { 64 | programName = QLatin1Char('\"') + programName + QLatin1Char('\"'); 65 | } 66 | programName.replace(QLatin1Char('/'), QLatin1Char('\\')); 67 | 68 | // add the program as the first arg ... it works better 69 | args = programName + QLatin1Char(' '); 70 | } 71 | 72 | for (int i = 0; i < arguments.size(); ++i) { 73 | QString tmp = arguments.at(i); 74 | // in the case of \" already being in the string the \ must also be escaped 75 | tmp.replace(QLatin1String("\\\""), QLatin1String("\\\\\"")); 76 | // escape a single " because the arguments will be parsed 77 | tmp.replace(QLatin1Char('\"'), QLatin1String("\\\"")); 78 | if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) { 79 | // The argument must not end with a \ since this would be interpreted 80 | // as escaping the quote -- rather put the \ behind the quote: e.g. 81 | // rather use "foo"\ than "foo\" 82 | QString endQuote(QLatin1Char('\"')); 83 | int i = tmp.length(); 84 | while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) { 85 | --i; 86 | endQuote += QLatin1Char('\\'); 87 | } 88 | args += QLatin1String(" \"") + tmp.left(i) + endQuote; 89 | } else { 90 | args += QLatin1Char(' ') + tmp; 91 | } 92 | } 93 | return args; 94 | } 95 | 96 | bool AdminAuthorization::hasAdminRights() 97 | { 98 | SID_IDENTIFIER_AUTHORITY authority = { SECURITY_NT_AUTHORITY }; 99 | PSID adminGroup; 100 | // Initialize SID. 101 | if (!AllocateAndInitializeSid(&authority, 102 | 2, 103 | SECURITY_BUILTIN_DOMAIN_RID, 104 | DOMAIN_ALIAS_RID_ADMINS, 105 | 0, 0, 0, 0, 0, 0, 106 | &adminGroup)) 107 | return false; 108 | 109 | BOOL isInAdminGroup = FALSE; 110 | if (!CheckTokenMembership(0, adminGroup, &isInAdminGroup)) 111 | isInAdminGroup = FALSE; 112 | 113 | FreeSid(adminGroup); 114 | return isInAdminGroup; 115 | } 116 | 117 | //copied from qsystemerror.cpp in Qt 118 | static QString windowsErrorString(int errorCode) 119 | { 120 | QString ret; 121 | wchar_t *string = 0; 122 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 123 | NULL, 124 | errorCode, 125 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 126 | (LPWSTR)&string, 127 | 0, 128 | NULL); 129 | ret = QString::fromWCharArray(string); 130 | LocalFree((HLOCAL)string); 131 | 132 | if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND) 133 | ret = QString::fromLatin1("The specified module could not be found."); 134 | 135 | ret.append(QLatin1String(" (0x")); 136 | ret.append(QString::number(uint(errorCode), 16).rightJustified(8, QLatin1Char('0'))); 137 | ret.append(QLatin1String(")")); 138 | 139 | return ret; 140 | } 141 | 142 | 143 | bool AdminAuthorization::execute(QWidget *, const QString &program, const QStringList &arguments) 144 | { 145 | DeCoInitializer _; 146 | 147 | // AdminAuthorization::execute uses UAC to ask for admin privileges. If the user is no 148 | // administrator yet and the computer's policies are set to not use UAC (which is the case 149 | // in some corporate networks), the call to execute() will simply succeed and not at all 150 | // launch the child process. To avoid this, we detect this situation here and return early. 151 | if (!hasAdminRights()) { 152 | QLatin1String key("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\" 153 | "Policies\\System"); 154 | QSettings registry(key, QSettings::NativeFormat); 155 | const QVariant enableLUA = registry.value(QLatin1String("EnableLUA")); 156 | if ((enableLUA.type() == QVariant::Int) && (enableLUA.toInt() == 0)) 157 | return false; 158 | } 159 | 160 | const QString file = QDir::toNativeSeparators(program); 161 | const QString args = qt_create_commandline(QString(), arguments); 162 | 163 | SHELLEXECUTEINFOW shellExecuteInfo = { 0 }; 164 | shellExecuteInfo.nShow = SW_HIDE; 165 | shellExecuteInfo.lpVerb = L"runas"; 166 | shellExecuteInfo.lpFile = (wchar_t *)file.utf16(); 167 | shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOW); 168 | shellExecuteInfo.lpParameters = (wchar_t *)args.utf16(); 169 | shellExecuteInfo.fMask = SEE_MASK_NOASYNC; 170 | 171 | qDebug() << QString::fromLatin1("Starting elevated process %1 with arguments: %2.").arg(file, args); 172 | 173 | if (ShellExecuteExW(&shellExecuteInfo)) { 174 | qDebug() << "Finished starting elevated process."; 175 | return true; 176 | } else { 177 | qWarning() << QString::fromLatin1("Error while starting elevated process: %1, " 178 | "Error: %2").arg(program, windowsErrorString(GetLastError())); 179 | } 180 | return false; 181 | } 182 | 183 | } // QRUNINFO_NAMEPASE_END 184 | -------------------------------------------------------------------------------- /adminauthorization_x11.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #include "adminauthorization.h" 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #ifdef Q_OS_LINUX 50 | #include 51 | #include 52 | #else 53 | #include 54 | #endif 55 | 56 | #include 57 | #include 58 | #include 59 | 60 | #include 61 | 62 | #define SU_COMMAND "/usr/bin/sudo" 63 | //#define SU_COMMAND "/bin/echo" 64 | 65 | namespace QRunInfo { 66 | 67 | static QString getPassword(QWidget *parent) 68 | { 69 | if (qobject_cast (qApp) != 0) { 70 | bool ok = false; 71 | const QString result = QInputDialog::getText(parent, QObject::tr("Authorization required"), 72 | QObject::tr("Enter your password to authorize for sudo:"), 73 | QLineEdit::Password, QString(), &ok); 74 | return ok ? result : QString(); 75 | } else { 76 | std::cout << QObject::tr("Authorization required").toStdString() << std::endl; 77 | std::cout << QObject::tr("Enter your password to authorize for sudo:").toStdString() 78 | << std::endl; 79 | std::string password; 80 | std::cin >> password; 81 | return QString::fromStdString(password); 82 | } 83 | } 84 | 85 | static void printError(QWidget *parent, const QString &value) 86 | { 87 | if (qobject_cast (qApp) != 0) { 88 | QMessageBox::critical(parent, QObject::tr( "Error acquiring admin rights" ), value, 89 | QMessageBox::Ok, QMessageBox::Ok); 90 | } else { 91 | std::cout << value.toStdString() << std::endl; 92 | } 93 | } 94 | 95 | bool AdminAuthorization::execute(QWidget *parent, const QString &program, const QStringList &arguments) 96 | { 97 | const QString fallback = program + QLatin1String(" ") + arguments.join(QLatin1String(" ")); 98 | qDebug() << "Fallback:" << fallback; 99 | 100 | // as we cannot pipe the password to su in QProcess, we need to setup a pseudo-terminal for it 101 | int masterFD = -1; 102 | int slaveFD = -1; 103 | char ptsn[ PATH_MAX ]; 104 | 105 | if (::openpty(&masterFD, &slaveFD, ptsn, 0, 0)) 106 | return false; 107 | 108 | masterFD = ::posix_openpt(O_RDWR | O_NOCTTY); 109 | if (masterFD < 0) 110 | return false; 111 | 112 | const QByteArray ttyName = ::ptsname(masterFD); 113 | 114 | if (::grantpt(masterFD)) { 115 | ::close(masterFD); 116 | return false; 117 | } 118 | 119 | ::revoke(ttyName); 120 | ::unlockpt(masterFD); 121 | 122 | slaveFD = ::open(ttyName, O_RDWR | O_NOCTTY); 123 | if (slaveFD < 0) { 124 | ::close(masterFD); 125 | return false; 126 | } 127 | 128 | ::fcntl(masterFD, F_SETFD, FD_CLOEXEC); 129 | ::fcntl(slaveFD, F_SETFD, FD_CLOEXEC); 130 | int pipedData[2]; 131 | if (pipe(pipedData) != 0) 132 | return false; 133 | 134 | int flags = ::fcntl(pipedData[0], F_GETFD); 135 | if (flags != -1) 136 | ::fcntl(pipedData[0], F_SETFL, flags | O_NONBLOCK); 137 | 138 | pid_t child = fork(); 139 | 140 | if (child < -1) { 141 | ::close(masterFD); 142 | ::close(slaveFD); 143 | ::close(pipedData[0]); 144 | ::close(pipedData[1]); 145 | return false; 146 | } 147 | 148 | // parent process 149 | else if (child > 0) { 150 | ::close(slaveFD); 151 | //close writing end of pipe 152 | ::close(pipedData[1]); 153 | 154 | QRegExp re(QLatin1String("[Pp]assword.*:")); 155 | QByteArray errData; 156 | flags = ::fcntl(masterFD, F_GETFD); 157 | int bytes = 0; 158 | int errBytes = 0; 159 | char buf[1024]; 160 | char errBuf[1024]; 161 | while (bytes >= 0) { 162 | int state; 163 | if (::waitpid(child, &state, WNOHANG) == -1) 164 | break; 165 | bytes = ::read(masterFD, buf, 1023); 166 | errBytes = ::read(pipedData[0], errBuf, 1023); 167 | if (errBytes > 0) 168 | { 169 | errData.append(buf, errBytes); 170 | errBytes=0; 171 | } 172 | if (bytes > 0) { 173 | const QString line = QString::fromLatin1(buf, bytes); 174 | if (re.indexIn(line) != -1) { 175 | const QString password = getPassword(parent); 176 | if (password.isEmpty()) { 177 | QByteArray pwd = password.toLatin1(); 178 | for (int i = 0; i < 3; ++i) { 179 | ::write(masterFD, pwd.data(), pwd.length()); 180 | ::write(masterFD, "\n", 1); 181 | } 182 | return false; 183 | } 184 | QByteArray pwd = password.toLatin1(); 185 | ::write(masterFD, pwd.data(), pwd.length()); 186 | ::write(masterFD, "\n", 1); 187 | ::read(masterFD, buf, pwd.length() + 1); 188 | } 189 | } 190 | if (bytes == 0) 191 | ::usleep(100000); 192 | } 193 | if (!errData.isEmpty()) { 194 | printError(parent, QString::fromLocal8Bit(errData.constData())); 195 | return false; 196 | } 197 | 198 | int status; 199 | child = ::wait(&status); 200 | const int exited = WIFEXITED(status); 201 | const int exitStatus = WEXITSTATUS(status); 202 | ::close(pipedData[1]); 203 | if (exited) 204 | return exitStatus == 0; 205 | 206 | return false; 207 | } 208 | 209 | // child process 210 | else { 211 | ::close(pipedData[0]); 212 | // Reset signal handlers 213 | for (int sig = 1; sig < NSIG; ++sig) 214 | signal(sig, SIG_DFL); 215 | signal(SIGHUP, SIG_IGN); 216 | 217 | ::setsid(); 218 | 219 | ::ioctl(slaveFD, TIOCSCTTY, 1); 220 | int pgrp = ::getpid(); 221 | ::tcsetpgrp(slaveFD, pgrp); 222 | 223 | ::dup2(slaveFD, 0); 224 | ::dup2(slaveFD, 1); 225 | ::dup2(pipedData[1], 2); 226 | 227 | // close all file descriptors 228 | struct rlimit rlp; 229 | getrlimit(RLIMIT_NOFILE, &rlp); 230 | for (int i = 3; i < static_cast(rlp.rlim_cur); ++i) 231 | ::close(i); 232 | 233 | char **argp = (char **) ::malloc(arguments.count() + 4 * sizeof(char *)); 234 | QList args; 235 | args.push_back(SU_COMMAND); 236 | args.push_back("-b"); 237 | args.push_back(program.toLocal8Bit()); 238 | for (QStringList::const_iterator it = arguments.begin(); it != arguments.end(); ++it) 239 | args.push_back(it->toLocal8Bit()); 240 | 241 | int i = 0; 242 | for (QList::iterator it = args.begin(); it != args.end(); ++it, ++i) 243 | argp[i] = it->data(); 244 | argp[i] = 0; 245 | 246 | ::unsetenv("LANG"); 247 | ::unsetenv("LC_ALL"); 248 | 249 | ::execv(SU_COMMAND, argp); 250 | _exit(0); 251 | return false; 252 | } 253 | } 254 | 255 | // has no guarantee to work 256 | bool AdminAuthorization::hasAdminRights() 257 | { 258 | return getuid() == 0; 259 | } 260 | 261 | } // QRUNINFO_NAMEPASE_END 262 | -------------------------------------------------------------------------------- /kdselfrestarter.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "kdselfrestarter.h" 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | namespace QRunInfo { 42 | class KDSelfRestarter::Private 43 | { 44 | public: 45 | Private(int argc, char *argv[]) 46 | : restartOnQuit(false) 47 | { 48 | executable = QString::fromLocal8Bit(argv[0]); 49 | workingPath = QDir::currentPath(); 50 | for (int i = 1; i < argc; ++i) 51 | args << QString::fromLocal8Bit(argv[i]); 52 | } 53 | 54 | Private() 55 | { 56 | executable = qApp->applicationFilePath(); 57 | workingPath = QDir::currentPath(); 58 | args = qApp->arguments().mid(1); 59 | } 60 | 61 | ~Private() 62 | { 63 | if (restartOnQuit) 64 | QProcess::startDetached(executable, args, workingPath); 65 | } 66 | 67 | QString executable; 68 | QStringList args; 69 | bool restartOnQuit; 70 | QString workingPath; 71 | static KDSelfRestarter *instance; 72 | }; 73 | 74 | KDSelfRestarter *KDSelfRestarter::Private::instance = 0; 75 | 76 | KDSelfRestarter::KDSelfRestarter(int argc, char *argv[]) 77 | : d(new Private(argc, argv)) 78 | { 79 | Q_ASSERT_X(!Private::instance, Q_FUNC_INFO, "Cannot create more than one KDSelfRestarter instance"); 80 | Private::instance = this; 81 | } 82 | 83 | KDSelfRestarter::~KDSelfRestarter() 84 | { 85 | Q_ASSERT_X(Private::instance == this, Q_FUNC_INFO, "Cannot create more than one KDSelfRestarter instance"); 86 | delete d; 87 | Private::instance = 0; 88 | } 89 | 90 | void KDSelfRestarter::setRestartOnQuit(bool restart) 91 | { 92 | Q_ASSERT_X(Private::instance, Q_FUNC_INFO, "KDSelfRestarter instance must be created in main()"); 93 | if (Private::instance) 94 | Private::instance->d->restartOnQuit = restart; 95 | } 96 | 97 | bool KDSelfRestarter::restartOnQuit() 98 | { 99 | return Private::instance ? Private::instance->d->restartOnQuit : false; 100 | } 101 | } // QRUNINFO_NAMEPASE_END -------------------------------------------------------------------------------- /kdselfrestarter.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #ifndef KDTOOLS_KDSELFRESTARTER_H 36 | #define KDTOOLS_KDSELFRESTARTER_H 37 | 38 | #include "qruninfo_global.h" 39 | 40 | namespace QRunInfo { 41 | 42 | class QRUNINFOSHARED_EXPORT KDSelfRestarter 43 | { 44 | public: 45 | KDSelfRestarter(int argc, char *argv[]); 46 | ~KDSelfRestarter(); 47 | 48 | static bool restartOnQuit(); 49 | static void setRestartOnQuit(bool restart); 50 | 51 | private: 52 | Q_DISABLE_COPY(KDSelfRestarter) 53 | class Private; 54 | Private *d; 55 | }; 56 | } // QRUNINFO_NAMEPASE_END 57 | #endif // KDTOOLS_KDSELFRESTARTER_H 58 | -------------------------------------------------------------------------------- /kdsysinfo.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "kdsysinfo.h" 36 | 37 | #include 38 | #include 39 | 40 | namespace QRunInfo { 41 | 42 | struct PathLongerThan 43 | { 44 | bool operator()(const VolumeInfo &lhs, const VolumeInfo &rhs) const 45 | { 46 | return lhs.mountPath().length() > rhs.mountPath().length(); 47 | } 48 | }; 49 | 50 | VolumeInfo::VolumeInfo() 51 | : m_size(0) 52 | , m_availableSize(0) 53 | { 54 | } 55 | 56 | VolumeInfo VolumeInfo::fromPath(const QString &path) 57 | { 58 | QDir targetPath(QDir::cleanPath(path)); 59 | QList volumes = RunInfo::mountedVolumes(); 60 | 61 | // sort by length to get the longest mount point (not just "/") first 62 | std::sort(volumes.begin(), volumes.end(), PathLongerThan()); 63 | foreach (const VolumeInfo &volume, volumes) { 64 | const QDir volumePath(volume.mountPath()); 65 | if (targetPath == volumePath) 66 | return volume; 67 | #ifdef Q_OS_WIN 68 | if (QDir::toNativeSeparators(path).toLower().startsWith(volume.mountPath().toLower())) 69 | #else 70 | // we need to take some care here, as canonical path might return an empty string if the target 71 | // does not exist yet 72 | if (targetPath.exists()) { 73 | // the target exist, we can solve the path and if it fits return 74 | if (targetPath.canonicalPath().startsWith(volume.mountPath())) 75 | return volume; 76 | continue; 77 | } 78 | 79 | // the target directory does not exist yet, we need to cd up till we find the first existing dir 80 | QStringList parts = targetPath.absolutePath().split(QDir::separator(),QString::SkipEmptyParts); 81 | while (targetPath.absolutePath() != QDir::rootPath()) { 82 | if (targetPath.exists()) 83 | break; 84 | parts.pop_back(); 85 | if (parts.isEmpty()) 86 | targetPath = QDir(QDir::rootPath()); 87 | else 88 | targetPath = QDir(QLatin1Char('/') + parts.join(QDir::separator())); 89 | } 90 | 91 | if (targetPath.canonicalPath().startsWith(volume.mountPath())) 92 | #endif 93 | return volume; 94 | } 95 | return VolumeInfo(); 96 | } 97 | 98 | QString VolumeInfo::mountPath() const 99 | { 100 | return m_mountPath; 101 | } 102 | 103 | void VolumeInfo::setMountPath(const QString &path) 104 | { 105 | m_mountPath = path; 106 | } 107 | 108 | QString VolumeInfo::fileSystemType() const 109 | { 110 | return m_fileSystemType; 111 | } 112 | 113 | void VolumeInfo::setFileSystemType(const QString &type) 114 | { 115 | m_fileSystemType = type; 116 | } 117 | 118 | QString VolumeInfo::volumeDescriptor() const 119 | { 120 | return m_volumeDescriptor; 121 | } 122 | 123 | void VolumeInfo::setVolumeDescriptor(const QString &descriptor) 124 | { 125 | m_volumeDescriptor = descriptor; 126 | } 127 | 128 | quint64 VolumeInfo::size() const 129 | { 130 | return m_size; 131 | } 132 | 133 | void VolumeInfo::setSize(const quint64 &size) 134 | { 135 | m_size = size; 136 | } 137 | 138 | quint64 VolumeInfo::availableSize() const 139 | { 140 | return m_availableSize; 141 | } 142 | 143 | void VolumeInfo::setAvailableSize(const quint64 &available) 144 | { 145 | m_availableSize = available; 146 | } 147 | 148 | bool VolumeInfo::operator==(const VolumeInfo &other) const 149 | { 150 | return m_volumeDescriptor == other.m_volumeDescriptor; 151 | } 152 | 153 | } // QRUNINFO_NAMEPASE_END 154 | 155 | QDebug operator<<(QDebug dbg, QRunInfo::VolumeInfo volume) 156 | { 157 | return dbg << "QRunInfo::Volume(" << volume.mountPath() << ")"; 158 | } 159 | 160 | QDebug operator<<(QDebug dbg, QRunInfo::ProcessInfo process) 161 | { 162 | return dbg << "QRunInfo::ProcessInfo(" << process.id << ", " << process.name << ")"; 163 | } 164 | -------------------------------------------------------------------------------- /kdsysinfo.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #ifndef KDSYSINFO_H 36 | #define KDSYSINFO_H 37 | 38 | #include "qruninfo_global.h" 39 | 40 | #include 41 | 42 | namespace QRunInfo { 43 | 44 | class QRUNINFOSHARED_EXPORT VolumeInfo 45 | { 46 | public: 47 | VolumeInfo(); 48 | static VolumeInfo fromPath(const QString &path); 49 | 50 | QString mountPath() const; 51 | void setMountPath(const QString &path); 52 | 53 | QString fileSystemType() const; 54 | void setFileSystemType(const QString &type); 55 | 56 | QString volumeDescriptor() const; 57 | void setVolumeDescriptor(const QString &descriptor); 58 | 59 | quint64 size() const; 60 | void setSize(const quint64 &size); 61 | 62 | quint64 availableSize() const; 63 | void setAvailableSize(const quint64 &available); 64 | 65 | bool operator==(const VolumeInfo &other) const; 66 | 67 | private: 68 | QString m_mountPath; 69 | QString m_fileSystemType; 70 | QString m_volumeDescriptor; 71 | 72 | quint64 m_size; 73 | quint64 m_availableSize; 74 | }; 75 | 76 | struct QRUNINFOSHARED_EXPORT ProcessInfo 77 | { 78 | quint32 id; 79 | QString name; 80 | }; 81 | 82 | class QRUNINFOSHARED_EXPORT RunInfo 83 | { 84 | public: 85 | static quint64 installedMemory(); 86 | static QList mountedVolumes(); 87 | static QList runningProcesses(); 88 | static bool killProcess(const ProcessInfo &process, int msecs = 30000); 89 | static bool pathIsOnLocalDevice(const QString &path); 90 | static quint32 currentProcessId(); 91 | static quint32 parentProcessId(); 92 | }; 93 | 94 | } // QRUNINFO_NAMEPASE_END 95 | 96 | 97 | QT_BEGIN_NAMESPACE 98 | class QDebug; 99 | QT_END_NAMESPACE 100 | 101 | QDebug operator<<(QDebug dbg, QRunInfo::VolumeInfo volume); 102 | QDebug operator<<(QDebug dbg, QRunInfo::ProcessInfo process); 103 | 104 | #endif // KDSYSINFO_H 105 | -------------------------------------------------------------------------------- /kdsysinfo_mac.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "kdsysinfo.h" 36 | 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #include 46 | 47 | namespace QRunInfo { 48 | 49 | quint64 RunInfo::installedMemory() 50 | { 51 | SInt32 mb = 0; 52 | Gestalt(gestaltPhysicalRAMSizeInMegabytes, &mb); 53 | return quint64(static_cast(mb) * 1024LL * 1024LL); 54 | } 55 | 56 | QList RunInfo::mountedVolumes() 57 | { 58 | QList result; 59 | FSVolumeRefNum volume; 60 | FSVolumeInfo info; 61 | HFSUniStr255 volName; 62 | FSRef ref; 63 | int i = 0; 64 | 65 | while (FSGetVolumeInfo(kFSInvalidVolumeRefNum, ++i, &volume, kFSVolInfoFSInfo, &info, &volName, &ref) == 0) { 66 | UInt8 path[PATH_MAX + 1]; 67 | if (FSRefMakePath(&ref, path, PATH_MAX) == 0) { 68 | FSGetVolumeInfo(volume, 0, 0, kFSVolInfoSizes, &info, 0, 0); 69 | 70 | VolumeInfo v; 71 | v.setSize(quint64(info.totalBytes)); 72 | v.setAvailableSize(quint64(info.freeBytes)); 73 | v.setMountPath(QString::fromLocal8Bit(reinterpret_cast< char* >(path))); 74 | 75 | struct statfs data; 76 | if (statfs(qPrintable(v.mountPath() + QLatin1String("/.")), &data) == 0) { 77 | v.setFileSystemType(QLatin1String(data.f_fstypename)); 78 | v.setVolumeDescriptor(QLatin1String(data.f_mntfromname)); 79 | } 80 | result.append(v); 81 | } 82 | } 83 | return result; 84 | } 85 | 86 | QList RunInfo::runningProcesses() 87 | { 88 | int mib[4] = { 89 | CTL_KERN, 90 | KERN_ARGMAX, 91 | 0, 92 | 0 93 | }; 94 | 95 | int argMax = 0; 96 | size_t argMaxSize = sizeof(argMax); 97 | // fetch the maximum process arguments size 98 | sysctl(mib, 2, &argMax, &argMaxSize, NULL, 0); 99 | char *processArguments = (char*) malloc(argMax); 100 | 101 | mib[1] = KERN_PROC; 102 | mib[2] = KERN_PROC_ALL; 103 | size_t processTableSize = 0; 104 | // fetch the kernel process table size 105 | sysctl(mib, 4, NULL, &processTableSize, NULL, 0); 106 | struct kinfo_proc *processTable = (kinfo_proc*) malloc(processTableSize); 107 | 108 | // fetch the process table 109 | sysctl(mib, 4, processTable, &processTableSize, NULL, 0); 110 | 111 | QList processes; 112 | for (size_t i = 0; i < (processTableSize / sizeof(struct kinfo_proc)); ++i) { 113 | struct kinfo_proc *process = processTable + i; 114 | 115 | ProcessInfo processInfo; 116 | processInfo.id = process->kp_proc.p_pid; 117 | 118 | mib[1] = KERN_PROCARGS2; 119 | mib[2] = process->kp_proc.p_pid; 120 | mib[3] = 0; 121 | 122 | size_t size = argMax; 123 | // fetch the process arguments 124 | if (sysctl(mib, 3, processArguments, &size, NULL, 0) != -1) { 125 | /* 126 | * |-----------------| <-- data returned by sysctl() 127 | * | argc | 128 | * |-----------------| 129 | * | executable path | 130 | * |-----------------| 131 | * | arguments | 132 | * ~~~~~~~~~~~~~~~~~~~ 133 | * |-----------------| 134 | */ 135 | processInfo.name = QString::fromLocal8Bit(processArguments + sizeof(int)); 136 | } else { 137 | // if we fail, use the name from the process table 138 | processInfo.name = QString::fromLocal8Bit(process->kp_proc.p_comm); 139 | } 140 | processes.append(processInfo); 141 | } 142 | free(processTable); 143 | free(processArguments); 144 | 145 | return processes; 146 | } 147 | 148 | bool RunInfo::pathIsOnLocalDevice(const QString &path) 149 | { 150 | Q_UNUSED(path); 151 | 152 | return true; 153 | } 154 | 155 | bool RunInfo::killProcess(const ProcessInfo &process, int msecs) 156 | { 157 | Q_UNUSED(process); 158 | Q_UNUSED(msecs); 159 | 160 | return true; 161 | } 162 | 163 | quint32 RunInfo::currentProcessId() 164 | { 165 | return getpid(); 166 | } 167 | 168 | quint32 RunInfo::parentProcessId() 169 | { 170 | return getppid(); 171 | } 172 | 173 | } // QRUNINFO_NAMEPASE_END 174 | -------------------------------------------------------------------------------- /kdsysinfo_win.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "kdsysinfo.h" 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | namespace QRunInfo { 46 | 47 | const int KDSYSINFO_PROCESS_QUERY_LIMITED_INFORMATION = 0x1000; 48 | 49 | typedef NTSTATUS ( * NtQueryInformationProcessPtr)(HANDLE ,PROCESSINFOCLASS ,PVOID ,ULONG ,PULONG ); 50 | 51 | quint64 RunInfo::installedMemory() 52 | { 53 | MEMORYSTATUSEX status; 54 | status.dwLength = sizeof(status); 55 | GlobalMemoryStatusEx(&status); 56 | return quint64(status.ullTotalPhys); 57 | } 58 | 59 | struct EnumWindowsProcParam 60 | { 61 | QList processes; 62 | QList seenIDs; 63 | }; 64 | 65 | typedef BOOL (WINAPI *QueryFullProcessImageNamePtr)(HANDLE, DWORD, char *, PDWORD); 66 | typedef DWORD (WINAPI *GetProcessImageFileNamePtr)(HANDLE, char *, DWORD); 67 | 68 | QList RunInfo::runningProcesses() 69 | { 70 | EnumWindowsProcParam param; 71 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 72 | if (!snapshot) 73 | return param.processes; 74 | 75 | QStringList deviceList; 76 | const DWORD bufferSize = 1024; 77 | char buffer[bufferSize + 1] = { 0 }; 78 | if (QSysInfo::windowsVersion() <= QSysInfo::WV_5_2) { 79 | const DWORD size = GetLogicalDriveStringsA(bufferSize, buffer); 80 | deviceList = QString::fromLatin1(buffer, size).split(QLatin1Char(char(0)), QString::SkipEmptyParts); 81 | } 82 | 83 | QLibrary kernel32(QLatin1String("Kernel32.dll")); 84 | kernel32.load(); 85 | QueryFullProcessImageNamePtr pQueryFullProcessImageNamePtr = (QueryFullProcessImageNamePtr) kernel32 86 | .resolve("QueryFullProcessImageNameA"); 87 | 88 | QLibrary psapi(QLatin1String("Psapi.dll")); 89 | psapi.load(); 90 | GetProcessImageFileNamePtr pGetProcessImageFileNamePtr = (GetProcessImageFileNamePtr) psapi 91 | .resolve("GetProcessImageFileNameA"); 92 | 93 | PROCESSENTRY32 processStruct; 94 | processStruct.dwSize = sizeof(PROCESSENTRY32); 95 | bool foundProcess = Process32First(snapshot, &processStruct); 96 | while (foundProcess) { 97 | HANDLE procHandle = OpenProcess(QSysInfo::windowsVersion() > QSysInfo::WV_5_2 98 | ? KDSYSINFO_PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION, false, processStruct 99 | .th32ProcessID); 100 | 101 | bool succ = false; 102 | QString executablePath; 103 | DWORD bufferSize = 1024; 104 | 105 | if (QSysInfo::windowsVersion() > QSysInfo::WV_5_2) { 106 | succ = pQueryFullProcessImageNamePtr(procHandle, 0, buffer, &bufferSize); 107 | executablePath = QString::fromLatin1(buffer); 108 | } else if (pGetProcessImageFileNamePtr) { 109 | succ = pGetProcessImageFileNamePtr(procHandle, buffer, bufferSize); 110 | executablePath = QString::fromLatin1(buffer); 111 | for (int i = 0; i < deviceList.count(); ++i) { 112 | executablePath.replace(QString::fromLatin1( "\\Device\\HarddiskVolume%1\\" ).arg(i + 1), 113 | deviceList.at(i)); 114 | } 115 | } 116 | 117 | if (succ) { 118 | const quint32 pid = processStruct.th32ProcessID; 119 | param.seenIDs.append(pid); 120 | ProcessInfo info; 121 | info.id = pid; 122 | info.name = executablePath; 123 | param.processes.append(info); 124 | } 125 | 126 | CloseHandle(procHandle); 127 | foundProcess = Process32Next(snapshot, &processStruct); 128 | 129 | } 130 | if (snapshot) 131 | CloseHandle(snapshot); 132 | 133 | kernel32.unload(); 134 | return param.processes; 135 | } 136 | 137 | 138 | quint32 RunInfo::currentProcessId() 139 | { 140 | DWORD id = GetCurrentProcessId(); 141 | return id; 142 | } 143 | 144 | quint32 RunInfo::parentProcessId() 145 | { 146 | DWORD id = static_cast(0); 147 | auto lib = LoadLibrary(L"Ntdll.dll"); 148 | 149 | if(lib){ 150 | NtQueryInformationProcessPtr ProcPtr = reinterpret_cast(GetProcAddress(lib, "NtQueryInformationProcess")); 151 | if(ProcPtr){ 152 | HANDLE handle = GetCurrentProcess(); 153 | PROCESS_BASIC_INFORMATION info; 154 | auto status = ProcPtr(handle,ProcessBasicInformation,&info,sizeof (PROCESS_BASIC_INFORMATION),nullptr); 155 | if (!status) 156 | id = info.InheritedFromUniqueProcessId; 157 | } 158 | } 159 | return id; 160 | } 161 | 162 | } // QRUNINFO_NAMEPASE_END 163 | -------------------------------------------------------------------------------- /kdsysinfo_x11.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB) 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | ****************************************************************************/ 34 | 35 | #include "kdsysinfo.h" 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | namespace QRunInfo { 46 | 47 | quint64 RunInfo::installedMemory() 48 | { 49 | #ifdef Q_OS_LINUX 50 | QFile f(QLatin1String("/proc/meminfo")); 51 | f.open(QIODevice::ReadOnly); 52 | QTextStream stream(&f); 53 | while (true) { 54 | const QString s = stream.readLine(); 55 | if( !s.startsWith(QLatin1String("MemTotal:" ))) 56 | continue; 57 | else if (s.isEmpty()) 58 | return quint64(); 59 | 60 | const QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts); 61 | return quint64(parts.at(1).toInt() * 1024LL); 62 | } 63 | #else 64 | quint64 physmem; 65 | size_t len = sizeof physmem; 66 | static int mib[2] = { CTL_HW, HW_MEMSIZE }; 67 | sysctl(mib, 2, &physmem, &len, 0, 0); 68 | return quint64(physmem); 69 | #endif 70 | return 0; 71 | } 72 | 73 | QList RunInfo::mountedVolumes() 74 | { 75 | QList result; 76 | 77 | QFile f(QLatin1String("/etc/mtab")); 78 | if (!f.open(QIODevice::ReadOnly)) { 79 | qCritical("%s: Could not open %s: %s", Q_FUNC_INFO, qPrintable(f.fileName()), qPrintable(f.errorString())); 80 | return result; //better error-handling? 81 | } 82 | 83 | QTextStream stream(&f); 84 | while (true) { 85 | const QString s = stream.readLine(); 86 | if (s.isNull()) 87 | return result; 88 | 89 | if (!s.startsWith(QLatin1Char('/')) && !s.startsWith(QLatin1String("tmpfs ") + QDir::tempPath())) 90 | continue; 91 | 92 | const QStringList parts = s.split(QLatin1Char(' '), QString::SkipEmptyParts); 93 | 94 | VolumeInfo v; 95 | v.setMountPath(parts.at(1)); 96 | v.setVolumeDescriptor(parts.at(0)); 97 | v.setFileSystemType(parts.value(2)); 98 | 99 | struct statvfs data; 100 | if (statvfs(qPrintable(v.mountPath() + QLatin1String("/.")), &data) == 0) { 101 | v.setSize(quint64(static_cast(data.f_blocks) * data.f_bsize)); 102 | v.setAvailableSize(quint64(static_cast(data.f_bavail) * data.f_bsize)); 103 | } 104 | result.append(v); 105 | } 106 | return result; 107 | } 108 | 109 | QList RunInfo::runningProcesses() 110 | { 111 | QList processes; 112 | QDir procDir(QLatin1String("/proc")); 113 | const QFileInfoList procCont = procDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Readable); 114 | QRegExp validator(QLatin1String("[0-9]+")); 115 | Q_FOREACH (const QFileInfo &info, procCont) { 116 | if (validator.exactMatch(info.fileName())) { 117 | const QString linkPath = QDir(info.absoluteFilePath()).absoluteFilePath(QLatin1String("exe")); 118 | const QFileInfo linkInfo(linkPath); 119 | if (linkInfo.exists()) { 120 | ProcessInfo processInfo; 121 | processInfo.name = linkInfo.symLinkTarget(); 122 | processInfo.id = info.fileName().toInt(); 123 | processes.append(processInfo); 124 | } 125 | } 126 | } 127 | return processes; 128 | } 129 | 130 | bool RunInfo::pathIsOnLocalDevice(const QString &path) 131 | { 132 | Q_UNUSED(path); 133 | 134 | return true; 135 | } 136 | 137 | bool RunInfo::killProcess(const ProcessInfo &process, int msecs) 138 | { 139 | Q_UNUSED(process); 140 | Q_UNUSED(msecs); 141 | 142 | return true; 143 | } 144 | 145 | quint32 RunInfo::currentProcessId() 146 | { 147 | return getpid(); 148 | } 149 | 150 | quint32 RunInfo::parentProcessId() 151 | { 152 | return getppid(); 153 | } 154 | 155 | } // QRUNINFO_NAMEPASE_END 156 | -------------------------------------------------------------------------------- /link.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #include "link.h" 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #ifdef Q_OS_UNIX 42 | #include 43 | #endif 44 | 45 | #ifdef Q_OS_WIN 46 | #include 47 | #include 48 | 49 | #ifndef Q_CC_MINGW 50 | # include 51 | #endif 52 | 53 | #if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) 54 | 55 | typedef struct _REPARSE_DATA_BUFFER { 56 | ULONG ReparseTag; 57 | USHORT ReparseDataLength; 58 | USHORT Reserved; 59 | union { 60 | struct { 61 | USHORT SubstituteNameOffset; 62 | USHORT SubstituteNameLength; 63 | USHORT PrintNameOffset; 64 | USHORT PrintNameLength; 65 | ULONG Flags; 66 | WCHAR PathBuffer[1]; 67 | } SymbolicLinkReparseBuffer; 68 | struct { 69 | USHORT SubstituteNameOffset; 70 | USHORT SubstituteNameLength; 71 | USHORT PrintNameOffset; 72 | USHORT PrintNameLength; 73 | WCHAR PathBuffer[1]; 74 | } MountPointReparseBuffer; 75 | struct { 76 | UCHAR DataBuffer[1]; 77 | } GenericReparseBuffer; 78 | }; 79 | } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 80 | #define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) 81 | 82 | #endif 83 | 84 | 85 | namespace QRunInfo { 86 | 87 | class FileHandleWrapper 88 | { 89 | public: 90 | FileHandleWrapper(const QString &path) 91 | : m_dirHandle(INVALID_HANDLE_VALUE) 92 | { 93 | QString normalizedPath = QString(path).replace(QLatin1Char('/'), QLatin1Char('\\')); 94 | m_dirHandle = CreateFile((wchar_t*)normalizedPath.utf16(), GENERIC_READ | GENERIC_WRITE, 0, 0, 95 | OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0); 96 | 97 | if (m_dirHandle == INVALID_HANDLE_VALUE) { 98 | qWarning() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(path).arg(GetLastError()); 99 | } 100 | } 101 | 102 | ~FileHandleWrapper() { 103 | if (m_dirHandle != INVALID_HANDLE_VALUE) 104 | CloseHandle(m_dirHandle); 105 | } 106 | 107 | HANDLE handle() { 108 | return m_dirHandle; 109 | } 110 | 111 | private: 112 | HANDLE m_dirHandle; 113 | }; 114 | 115 | QString readWindowsSymLink(const QString &path) 116 | { 117 | QString result; 118 | FileHandleWrapper dirHandle(path); 119 | if (dirHandle.handle() != INVALID_HANDLE_VALUE) { 120 | REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 121 | DWORD bytesReturned = 0; 122 | if (::DeviceIoControl(dirHandle.handle(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseStructData, 123 | MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, 0)) { 124 | if (reparseStructData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { 125 | int length = reparseStructData->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); 126 | int offset = reparseStructData->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); 127 | const wchar_t* PathBuffer = &reparseStructData->MountPointReparseBuffer.PathBuffer[offset]; 128 | result = QString::fromWCharArray(PathBuffer, length); 129 | } else if (reparseStructData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { 130 | int length = reparseStructData->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); 131 | int offset = reparseStructData->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); 132 | const wchar_t* PathBuffer = &reparseStructData->SymbolicLinkReparseBuffer.PathBuffer[offset]; 133 | result = QString::fromWCharArray(PathBuffer, length); 134 | } 135 | // cut-off "//?/" and "/??/" 136 | if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\')) 137 | result = result.mid(4); 138 | } 139 | free(reparseStructData); 140 | } 141 | return result; 142 | } 143 | 144 | Link createJunction(const QString &linkPath, const QString &targetPath) 145 | { 146 | if (!QDir().mkpath(linkPath)) { 147 | qWarning() << QString::fromLatin1("Could not create the mount directory: %1").arg( 148 | linkPath); 149 | return Link(linkPath); 150 | } 151 | FileHandleWrapper dirHandle(linkPath); 152 | if (dirHandle.handle() == INVALID_HANDLE_VALUE) { 153 | qWarning() << QString::fromLatin1("Could not open: '%1'; error: %2\n").arg(linkPath) 154 | .arg(GetLastError()); 155 | return Link(linkPath); 156 | } 157 | 158 | const QString szDestDir = QString::fromLatin1("\\??\\").arg(targetPath).replace(QLatin1Char('/'), 159 | QLatin1Char('\\')); 160 | 161 | // Allocates a block of memory for an array of num elements(1) and initializes all its bits to zero. 162 | REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, 163 | MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 164 | reparseStructData->Reserved = 0; 165 | reparseStructData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; 166 | reparseStructData->MountPointReparseBuffer.PrintNameLength = 0; 167 | reparseStructData->MountPointReparseBuffer.SubstituteNameOffset = 0; 168 | reparseStructData->MountPointReparseBuffer.SubstituteNameLength = szDestDir.length(); 169 | reparseStructData->MountPointReparseBuffer.PrintNameOffset = szDestDir.length() + sizeof(WCHAR); 170 | 171 | uint spaceAfterGeneralData = sizeof(USHORT) * 5 + sizeof(WCHAR); //should be 12 172 | reparseStructData->ReparseDataLength = szDestDir.length() + spaceAfterGeneralData; 173 | 174 | #ifndef Q_CC_MINGW 175 | StringCchCopy(reparseStructData->MountPointReparseBuffer.PathBuffer, 1024, (wchar_t*)szDestDir.utf16()); 176 | #else 177 | wcsncpy(reparseStructData->MountPointReparseBuffer.PathBuffer, (wchar_t*)szDestDir.utf16(), 1024); 178 | #endif 179 | 180 | DWORD bytesReturned; 181 | if (!::DeviceIoControl(dirHandle.handle(), FSCTL_SET_REPARSE_POINT, reparseStructData, 182 | reparseStructData->ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE, 0, 0, 183 | &bytesReturned, 0)) { 184 | qWarning() << QString::fromLatin1("Could not set the reparse point: for '%1' to %2; error: %3" 185 | ).arg(linkPath, targetPath).arg(GetLastError()); 186 | } 187 | return Link(linkPath); 188 | } 189 | 190 | bool removeJunction(const QString &path) 191 | { 192 | // Allocates a block of memory for an array of num elements(1) and initializes all its bits to zero. 193 | REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, 194 | MAXIMUM_REPARSE_DATA_BUFFER_SIZE); 195 | 196 | reparseStructData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; 197 | 198 | { // extra scope because we need to close the dirHandle before we can remove that directory 199 | FileHandleWrapper dirHandle(path); 200 | 201 | DWORD bytesReturned; 202 | if (!::DeviceIoControl(dirHandle.handle(), FSCTL_DELETE_REPARSE_POINT, reparseStructData, 203 | REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0, 0, 204 | &bytesReturned, 0)) { 205 | 206 | qWarning() << QString::fromLatin1("Could not remove the reparse point: '%1'; error: %3" 207 | ).arg(path).arg(GetLastError()); 208 | return false; 209 | } 210 | } 211 | 212 | return QDir().rmdir(path); 213 | } 214 | #else 215 | 216 | namespace QRunInfo { 217 | 218 | Link createLnSymlink(const QString &linkPath, const QString &targetPath) 219 | { 220 | int linkedError = symlink(QFileInfo(targetPath).absoluteFilePath().toUtf8(), 221 | QFileInfo(linkPath).absoluteFilePath().toUtf8()); 222 | if (linkedError != 0) { 223 | qWarning() << QString::fromLatin1("Could not create a symlink: from '%1' to %2; error: %3" 224 | ).arg(linkPath, targetPath).arg(linkedError); 225 | } 226 | 227 | 228 | return Link(linkPath); 229 | } 230 | 231 | bool removeLnSymlink(const QString &path) 232 | { 233 | return QFile::remove(path); 234 | } 235 | 236 | #endif 237 | 238 | Link::Link(const QString &path) : m_path(path) 239 | { 240 | } 241 | 242 | Link Link::create(const QString &link, const QString &targetPath) 243 | { 244 | QStringList pathParts = QFileInfo(link).absoluteFilePath().split(QLatin1Char('/')); 245 | pathParts.removeLast(); 246 | QString linkPath = pathParts.join(QLatin1String("/")); 247 | bool linkPathExists = QFileInfo(linkPath).exists(); 248 | if (!linkPathExists) 249 | linkPathExists = QDir().mkpath(linkPath); 250 | if (!linkPathExists) { 251 | qWarning() << QString::fromLatin1("Could not create the needed directories: %1").arg( 252 | link); 253 | return Link(link); 254 | } 255 | 256 | #ifdef Q_OS_WIN 257 | if (QFileInfo(targetPath).isDir()) 258 | return createJunction(link, targetPath); 259 | 260 | qWarning() << QString::fromLatin1("At the moment the %1 can not create anything else as "\ 261 | "junctions for directories under windows").arg(QLatin1String(Q_FUNC_INFO)); 262 | return Link(link); 263 | #else 264 | return createLnSymlink(link, targetPath); 265 | #endif 266 | } 267 | 268 | QString Link::targetPath() const 269 | { 270 | #ifdef Q_OS_WIN 271 | return readWindowsSymLink(m_path); 272 | #else 273 | return QFileInfo(m_path).readLink(); 274 | #endif 275 | } 276 | 277 | bool Link::exists() 278 | { 279 | #ifdef Q_OS_WIN 280 | return QFileInfo(m_path).exists(); 281 | #else 282 | return QFileInfo(m_path).isSymLink(); 283 | #endif 284 | } 285 | 286 | bool Link::targetExists() 287 | { 288 | return QFileInfo(targetPath()).exists(); 289 | } 290 | 291 | bool Link::isValid() 292 | { 293 | return targetExists() && QFileInfo(m_path).exists(); 294 | } 295 | 296 | bool Link::remove() 297 | { 298 | if (!exists()) 299 | return false; 300 | #ifdef Q_OS_WIN 301 | return removeJunction(m_path); 302 | #else 303 | return removeLnSymlink(m_path); 304 | #endif 305 | } 306 | } // QRUNINFO_NAMEPASE_END 307 | -------------------------------------------------------------------------------- /link.h: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #ifndef LINK_H 36 | #define LINK_H 37 | 38 | #include "qruninfo_global.h" 39 | #include 40 | 41 | namespace QRunInfo { 42 | 43 | class QRUNINFOSHARED_EXPORT Link 44 | { 45 | public: 46 | explicit Link(const QString &path); 47 | static Link create(const QString &link, const QString &targetPath); 48 | QString targetPath() const; 49 | bool targetExists(); 50 | bool exists(); 51 | bool isValid(); 52 | bool remove(); 53 | 54 | private: 55 | QString m_path; 56 | }; 57 | 58 | } // QRUNINFO_NAMEPASE_END 59 | #endif // LINK_H 60 | -------------------------------------------------------------------------------- /qruninfo_global.h: -------------------------------------------------------------------------------- 1 | #ifndef QRUNINFO_GLOBAL_H 2 | #define QRUNINFO_GLOBAL_H 3 | 4 | #include 5 | 6 | 7 | #if defined(QRUNINFO_LIBRARY) 8 | # define QRUNINFOSHARED_EXPORT Q_DECL_EXPORT 9 | #elif defined(QRUNINFO_NOLIB) 10 | #define QRUNINFOSHARED_EXPORT 11 | #else 12 | # define QRUNINFOSHARED_EXPORT Q_DECL_IMPORT 13 | #endif 14 | 15 | 16 | 17 | #endif // QRUNINFO_GLOBAL_H 18 | -------------------------------------------------------------------------------- /sysinfo_win.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | ** 3 | ** Copyright (C) 2015 The Qt Company Ltd. 4 | ** Contact: http://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the Qt Installer Framework. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see http://qt.io/terms-conditions. For further 15 | ** information use the contact form at http://www.qt.io/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** As a special exception, The Qt Company gives you certain additional 27 | ** rights. These rights are described in The Qt Company LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** 31 | ** $QT_END_LICENSE$ 32 | ** 33 | **************************************************************************/ 34 | 35 | #include "kdsysinfo.h" 36 | #include "link.h" 37 | 38 | #ifdef Q_CC_MINGW 39 | # ifndef _WIN32_WINNT 40 | # define _WIN32_WINNT 0x0501 41 | # endif 42 | #endif 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #ifndef Q_CC_MINGW 51 | #pragma comment(lib, "mpr.lib") 52 | #endif 53 | 54 | #include 55 | #include 56 | #include 57 | 58 | namespace QRunInfo { 59 | 60 | VolumeInfo updateVolumeSizeInformation(const VolumeInfo &info) 61 | { 62 | ULARGE_INTEGER bytesTotal; 63 | ULARGE_INTEGER freeBytesPerUser; 64 | 65 | VolumeInfo update = info; 66 | if (GetDiskFreeSpaceExA(qPrintable(info.volumeDescriptor()), &freeBytesPerUser, &bytesTotal, NULL)) { 67 | update.setSize(bytesTotal.QuadPart); 68 | update.setAvailableSize(freeBytesPerUser.QuadPart); 69 | } 70 | return update; 71 | } 72 | 73 | /*! 74 | Returns a list of volume info objects that are mounted as network drive shares. 75 | */ 76 | QList networkVolumeInfosFromMountPoints() 77 | { 78 | QList volumes; 79 | QFileInfoList drives = QDir::drives(); 80 | foreach (const QFileInfo &drive, drives) { 81 | const QString driveLetter = QDir::toNativeSeparators(drive.canonicalPath()); 82 | const uint driveType = GetDriveTypeA(qPrintable(driveLetter)); 83 | switch (driveType) { 84 | case DRIVE_REMOTE: { 85 | char buffer[1024] = ""; 86 | DWORD bufferLength = 1024; 87 | UNIVERSAL_NAME_INFOA *universalNameInfo = (UNIVERSAL_NAME_INFOA*) &buffer; 88 | if (WNetGetUniversalNameA(qPrintable(driveLetter), UNIVERSAL_NAME_INFO_LEVEL, 89 | LPVOID(universalNameInfo), &bufferLength) == NO_ERROR) { 90 | VolumeInfo info; 91 | info.setMountPath(driveLetter); 92 | info.setVolumeDescriptor(QLatin1String(universalNameInfo->lpUniversalName)); 93 | volumes.append(info); 94 | } 95 | } break; 96 | 97 | default: 98 | break; 99 | } 100 | } 101 | return volumes; 102 | } 103 | 104 | /*! 105 | Returns a list of volume info objects based on the given \a volumeGUID. The function also solves mounted 106 | volume folder paths. It does not return any network drive shares. 107 | */ 108 | QList localVolumeInfosFromMountPoints(PTCHAR volumeGUID) 109 | { 110 | #ifndef UNICODE 111 | #define fromWCharArray fromLatin1 112 | #endif 113 | QList volumes; 114 | DWORD bufferSize; 115 | TCHAR volumeNames[MAX_PATH + 1] = { 0 }; 116 | if (GetVolumePathNamesForVolumeName(volumeGUID, volumeNames, MAX_PATH, &bufferSize)) { 117 | QStringList mountedPaths = QString::fromWCharArray(volumeNames, bufferSize).split(QLatin1Char(char(0)), 118 | QString::SkipEmptyParts); 119 | foreach (const QString &mountedPath, mountedPaths) { 120 | VolumeInfo info; 121 | info.setMountPath(mountedPath); 122 | info.setVolumeDescriptor(QString::fromWCharArray(volumeGUID)); 123 | volumes.append(info); 124 | } 125 | } 126 | return volumes; 127 | #ifndef UNICODE 128 | #undef fromWCharArray 129 | #endif 130 | } 131 | 132 | QList RunInfo::mountedVolumes() 133 | { 134 | // suppress message box shown while accessing possible unmounted devices 135 | const UINT old = SetErrorMode(SEM_FAILCRITICALERRORS); 136 | 137 | QList tmp; 138 | TCHAR volumeGUID[MAX_PATH + 1] = { 0 }; 139 | HANDLE handle = FindFirstVolume(volumeGUID, MAX_PATH); 140 | if (handle != INVALID_HANDLE_VALUE) { 141 | tmp += localVolumeInfosFromMountPoints(volumeGUID); 142 | while (FindNextVolume(handle, volumeGUID, MAX_PATH)) { 143 | tmp += localVolumeInfosFromMountPoints(volumeGUID); 144 | } 145 | FindVolumeClose(handle); 146 | } 147 | tmp += networkVolumeInfosFromMountPoints(); 148 | 149 | QList volumes; 150 | while (!tmp.isEmpty()) // update volume size information 151 | volumes.append(updateVolumeSizeInformation(tmp.takeFirst())); 152 | 153 | SetErrorMode(old); // reset error mode 154 | return volumes; 155 | } 156 | 157 | bool RunInfo::pathIsOnLocalDevice(const QString &path) 158 | { 159 | if (!QFileInfo(path).exists()) 160 | return false; 161 | 162 | if (path.startsWith(QLatin1String("\\\\"))) 163 | return false; 164 | 165 | QDir dir(path); 166 | do { 167 | if (QFileInfo(dir, QString()).isSymLink()) { 168 | QString currentPath = QFileInfo(dir, QString()).absoluteFilePath(); 169 | return pathIsOnLocalDevice(Link(currentPath).targetPath()); 170 | } 171 | } while (dir.cdUp()); 172 | 173 | const UINT DRIVE_REMOTE_TYPE = 4; 174 | if (path.contains(QLatin1Char(':'))) { 175 | const QLatin1Char nullTermination('\0'); 176 | // for example "c:\" 177 | const QString driveSearchString = path.left(3) + nullTermination; 178 | WCHAR wCharDriveSearchArray[4]; 179 | driveSearchString.toWCharArray(wCharDriveSearchArray); 180 | UINT type = GetDriveType(wCharDriveSearchArray); 181 | if (type == DRIVE_REMOTE_TYPE) 182 | return false; 183 | } 184 | 185 | return true; 186 | } 187 | 188 | bool CALLBACK TerminateAppEnum(HWND hwnd, LPARAM lParam) 189 | { 190 | DWORD dwID; 191 | GetWindowThreadProcessId(hwnd, &dwID); 192 | 193 | if (dwID == (DWORD)lParam) 194 | PostMessage(hwnd, WM_CLOSE, 0, 0); 195 | return true; 196 | } 197 | 198 | bool RunInfo::killProcess(const ProcessInfo &process, int msecs) 199 | { 200 | DWORD dwTimeout = msecs; 201 | if (msecs == -1) 202 | dwTimeout = INFINITE; 203 | 204 | // If we can't open the process with PROCESS_TERMINATE rights, then we give up immediately. 205 | HANDLE hProc = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, false, process.id); 206 | if (hProc == 0) 207 | return false; 208 | 209 | // TerminateAppEnum() posts WM_CLOSE to all windows whose PID matches your process's. 210 | EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM)process.id); 211 | 212 | // Wait on the handle. If it signals, great. If it times out, then kill it. 213 | bool returnValue = false; 214 | if (WaitForSingleObject(hProc, dwTimeout) != WAIT_OBJECT_0) 215 | returnValue = TerminateProcess(hProc, 0); 216 | 217 | CloseHandle(hProc); 218 | return returnValue; 219 | } 220 | 221 | } // QRUNINFO_NAMEPASE_END -------------------------------------------------------------------------------- /win32path.cpp: -------------------------------------------------------------------------------- 1 | #include "win32path.h" 2 | #include 3 | #include 4 | 5 | #ifndef PIDLIST_ABSOLUTE 6 | typedef ITEMIDLIST *PIDLIST_ABSOLUTE; 7 | #endif 8 | 9 | namespace QRunInfo { 10 | 11 | bool Win3SysPath::createLink(const QString &fileName, const QString &linkName, 12 | const QString &arguments, const QString &iconPath, 13 | const QString &iconId) 14 | { 15 | bool success = QFile::link(fileName, linkName); 16 | 17 | if (!success) 18 | return success; 19 | // CoInitialize cleanup object 20 | DeCoInitializer _; 21 | _.noWarrning(); 22 | 23 | 24 | QString workingDir = QFileInfo(fileName).absolutePath(); 25 | workingDir = QDir::toNativeSeparators(workingDir); 26 | 27 | IShellLink *psl = NULL; 28 | if (FAILED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl))) 29 | return success; 30 | 31 | psl->SetPath((wchar_t *)QDir::toNativeSeparators(fileName).utf16()); 32 | psl->SetWorkingDirectory((wchar_t *)workingDir.utf16()); 33 | if (!arguments.isNull()) 34 | psl->SetArguments((wchar_t*)arguments.utf16()); 35 | if (!iconPath.isNull()) 36 | psl->SetIconLocation((wchar_t*)(iconPath.utf16()), iconId.toInt()); 37 | 38 | IPersistFile *ppf = NULL; 39 | if (SUCCEEDED(psl->QueryInterface(IID_IPersistFile, (void **)&ppf))) { 40 | ppf->Save((wchar_t*)QDir::toNativeSeparators(linkName).utf16(), true); 41 | ppf->Release(); 42 | } 43 | psl->Release(); 44 | 45 | PIDLIST_ABSOLUTE pidl; 46 | 47 | if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_STARTMENU, 0, 0, &pidl))) { 48 | SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, 0); 49 | CoTaskMemFree(pidl); 50 | } 51 | if (SUCCEEDED(SHGetFolderLocation(0, CSIDL_COMMON_STARTMENU, 0, 0, &pidl))) { 52 | SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, 0); 53 | CoTaskMemFree(pidl); 54 | } 55 | 56 | return success; 57 | } 58 | 59 | QString Win3SysPath::getWinSysDir(SYSTEMPATH path) 60 | { 61 | DeCoInitializer _; 62 | _.noWarrning(); 63 | PIDLIST_ABSOLUTE pidl; // Force start menu cache update 64 | wchar_t MyDir[_MAX_PATH] = {0}; 65 | if (SUCCEEDED(SHGetFolderLocation(0, path, 0, 0, &pidl))) { 66 | SHGetPathFromIDList(pidl,MyDir); 67 | SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, 0); 68 | CoTaskMemFree(pidl); 69 | } 70 | 71 | return QString::fromWCharArray(MyDir).replace("\\","/"); 72 | } 73 | 74 | } // QRUNINFO_NAMEPASE_END 75 | -------------------------------------------------------------------------------- /win32path.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMOM_H 2 | #define COMMOM_H 3 | 4 | #include "qruninfo_global.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace QRunInfo { 12 | 13 | struct DeCoInitializer 14 | { 15 | DeCoInitializer() 16 | : neededCoInit(CoInitialize(NULL) == S_OK) 17 | { 18 | } 19 | ~DeCoInitializer() 20 | { 21 | if (neededCoInit) 22 | CoUninitialize(); 23 | } 24 | bool neededCoInit; 25 | void noWarrning(){} 26 | }; 27 | 28 | class QRUNINFOSHARED_EXPORT Win3SysPath 29 | { 30 | public: 31 | //用户目录和临时目录,请用QDir获取 32 | enum SYSTEMPATH 33 | { 34 | UserDeskTopPath = CSIDL_DESKTOPDIRECTORY,//桌面 35 | UserDocumentsPath = CSIDL_PERSONAL,//我的文档 36 | UserMusicPath = CSIDL_MYMUSIC,//我的音乐 37 | UserVideoPath = CSIDL_MYVIDEO,//我的视频 38 | UserPricturesPath = CSIDL_MYPICTURES,//我的图片 39 | UserFavoritesPath = CSIDL_FAVORITES,//我的收藏 40 | UserAppDataPath = CSIDL_APPDATA,//当前用户的特定的应用程序数据存储文件夹 41 | UserLocalAppDataPath = CSIDL_LOCAL_APPDATA,//表示当前用户的应用程序数据文件夹,例如:C:\Documents and Settings\username\Local Settings\Application Dat 42 | UserNetHoodPath = CSIDL_NETHOOD,//表示当前用户存在的网络连接的文件夹,例如:C:\Documents and Settings\username\NetHood 43 | UserPrintHoodPath = CSIDL_PRINTHOOD,//表示当前用户存在的网络打印机的虚拟文件夹,例如:C:\Documents and Settings\username\PrintHood 44 | 45 | UserStartMenuPath = CSIDL_STARTMENU,//用户开始菜单 46 | UserStartMenuProgramsPath = CSIDL_PROGRAMS,//用户开始程序菜单 47 | UserStartUpPath = CSIDL_STARTUP,//启动目录 48 | UserSentTo = CSIDL_SENDTO,//表示当前用户的“发送到”文件夹,例如:C:\Documents and Settings\username\SendTo 49 | 50 | AdminToolsPath = CSIDL_COMMON_ADMINTOOLS,//表示所有用户的“管理工具”系统文件夹 51 | CommonAppData = CSIDL_COMMON_APPDATA,//表示所有用户的特定的应用程序数据存储文件夹,例如:C:\Documents and Settings\All Users\Application Data 52 | CommonDeskTopPath = CSIDL_COMMON_DESKTOPDIRECTORY,//表示所有用户的“桌面”文件夹,例如:C:\Documents and Settings\All Users\Desktop。 53 | CommonDocumentsPath = CSIDL_COMMON_DOCUMENTS,//表示所有用户的“我的文档”文件夹,例如:C:\Documents and Settings\All Users\Documents 54 | CommonFavoritesPath =CSIDL_COMMON_FAVORITES,//表示所有用户的“我的收藏夹”文件夹。 55 | CommonMusicPath = CSIDL_COMMON_MUSIC,// 公共音乐 0x0035 56 | CommonPricturesPath = CSIDL_COMMON_PICTURES,// 公共图片0x0036 57 | CommonVideoPath = CSIDL_COMMON_VIDEO,//公共视频 0x0037 58 | CommonStartMenuProgramsPath = CSIDL_COMMON_PROGRAMS,//表示所有用户的“程序”文件夹,例如:C:\Documents and Settings\All Users\Start Menu\Programs 59 | CommonStartMenuPath = CSIDL_COMMON_STARTMENU,//表示所有用户的“开始菜单”文件夹,例如:C:\Documents and Settings\All Users\Start Menu 60 | CommonStartUpPath = CSIDL_COMMON_STARTUP,//表示所有用户的“启动”文件夹,例如:C:\Documents and Settings\All Users\Start Menu\Programs\Startup 61 | CommonTemplantesPath = CSIDL_COMMON_TEMPLATES,//表示所有用户的“模块”文件夹,例如:C:\Documents and Settings\All Users\Templates 62 | 63 | IECookiesPath = CSIDL_COOKIES,//表示当前用户Internet Explorer的cookie 文件夹,例如:C:\Documents and Settings\username\Cookies 64 | IEHistoryPath = CSIDL_HISTORY,//表示Inernet Explorer的“历史记录”文件夹 65 | IECachePath = CSIDL_INTERNET_CACHE,//表示当前用户的Internet Explorer的"Cache"文件夹,例如:C:\Documents and Settings\username\Temporary Internet Files 66 | 67 | TemplantesPath = CSIDL_TEMPLATES,//模板目录 68 | FontsPath = CSIDL_FONTS,//字体目录 69 | ProgramFilesPath = CSIDL_PROGRAM_FILES,//表示程序文件的文件夹,例如:C:\Program Files 70 | ProgramFilesCommonPath =CSIDL_PROGRAM_FILES_COMMON,//表示系统程序共用组件文件夹,例如:C:\Program Files\Common 71 | SystemPath = CSIDL_SYSTEM,//表示WINDOWS系统的系统文件夹,例如:C:\WINNT\SYSTEM32 72 | WindowsPath = CSIDL_WINDOWS//表示的是系统中Windows目录的文件珍,例如:C:\WINNT 73 | }; 74 | static bool createLink(const QString &fileName, const QString &linkName, 75 | const QString &arguments = QString(), const QString &iconPath = QString(), 76 | const QString &iconId = QString());//创建快捷方式:源文件,创建到的完整path 77 | 78 | static QString getWinSysDir(SYSTEMPATH path);//获取系统的路径 79 | 80 | private: 81 | Win3SysPath(){} 82 | }; 83 | 84 | } // QRUNINFO_NAMEPASE_END 85 | 86 | #endif // COMMOM_H 87 | --------------------------------------------------------------------------------