… | |
… | |
19 | # along with this program. If not, see <https://www.gnu.org/licenses/>. |
19 | # along with this program. If not, see <https://www.gnu.org/licenses/>. |
20 | # |
20 | # |
21 | |
21 | |
22 | use 5.016; # numerous features need 5.14, __SUB__ needs 5.16 |
22 | use 5.016; # numerous features need 5.14, __SUB__ needs 5.16 |
23 | |
23 | |
24 | our $VERSION = '1.2'; |
24 | our $VERSION = '1.5'; |
25 | our $JSON_VERSION = 2; # the version of the json objects generated by this program |
25 | our $JSON_VERSION = 3; # the version of the json objects generated by this program |
26 | |
26 | |
27 | our $CHANGELOG = <<EOF; |
27 | our $CHANGELOG = <<EOF; |
|
|
28 | |
|
|
29 | 1.5 Mon Nov 25 15:54:34 CET 2019 |
|
|
30 | - add "del" edit instruction. |
|
|
31 | - work around lsblk bug sometimes giving "dos" pttype for gpt partitions. |
|
|
32 | - bootmenupolicy in synopsis must be set to 0 to get the text menu. |
|
|
33 | - minor doc fxes. |
|
|
34 | - disable use of perldoc for help, doesn't work well. |
|
|
35 | |
|
|
36 | 1.4 Thu Aug 22 10:48:22 CEST 2019 |
|
|
37 | - new "create" subcommand. |
|
|
38 | - "create" and "edit" try to save and restore ownership/permissions |
|
|
39 | of bcd hives when writing the new file. |
|
|
40 | - editorial fixes to the documentation. |
|
|
41 | - add mininmal hive creation example. |
|
|
42 | |
|
|
43 | 1.3 Sat Aug 17 07:04:15 CEST 2019 |
|
|
44 | - output of pbcdedit elements --json has changed, as it didn't |
|
|
45 | take the reorganisation by classes fully into account. |
|
|
46 | - json schema bumped to 3. |
|
|
47 | - new "bcd-device" and "bcd-legacy-device" subcommands. |
|
|
48 | - implement --json option for lsblk. |
|
|
49 | |
28 | 1.2 Fri Aug 16 00:20:41 CEST 2019 |
50 | 1.2 Fri Aug 16 00:20:41 CEST 2019 |
29 | - bcde element names now depend on the bcd object type they are in, |
51 | - bcd element names now depend on the bcd object type they are in, |
30 | also affects "elements" output. |
52 | also affects "elements" output. |
31 | - json schema bumped to 2. |
53 | - json schema bumped to 2. |
32 | - new version command. |
54 | - new version command. |
33 | - numerous minor bugfixes. |
55 | - numerous minor bugfixes. |
34 | |
56 | |
… | |
… | |
48 | pbcdedit edit path/to/BCD edit-instructions... |
70 | pbcdedit edit path/to/BCD edit-instructions... |
49 | |
71 | |
50 | pbcdedit objects # list all supported object aliases and types |
72 | pbcdedit objects # list all supported object aliases and types |
51 | pbcdedit elements # list all supported bcd element aliases |
73 | pbcdedit elements # list all supported bcd element aliases |
52 | |
74 | |
|
|
75 | # Example: enable text-based boot menu. |
|
|
76 | pbcdedit edit /my/BCD set '{default}' bootmenupolicy 0 |
|
|
77 | |
|
|
78 | # Example change system device to first partition containing winload. |
|
|
79 | pbcdedit edit /my/BCD \ |
|
|
80 | set '{default}' device 'locate=<null>,element,path' \ |
|
|
81 | set '{default}' osdevice 'locate=<null>,element,path' |
|
|
82 | |
|
|
83 | |
53 | =head1 DESCRIPTION |
84 | =head1 DESCRIPTION |
54 | |
85 | |
55 | This program allows you to create, read and modify Boot Configuration Data |
86 | This program allows you to create, read and modify Boot Configuration Data |
56 | (BCD) stores used by Windows Vista and newer versions of Windows. |
87 | (BCD) stores used by Windows Vista and newer versions of Windows. |
57 | |
88 | |
… | |
… | |
136 | =item C<parse> F<path> I<instructions...> |
167 | =item C<parse> F<path> I<instructions...> |
137 | |
168 | |
138 | Same as C<edit>, above, except it doesn't save the data store again. Can |
169 | Same as C<edit>, above, except it doesn't save the data store again. Can |
139 | be useful to extract some data from it. |
170 | be useful to extract some data from it. |
140 | |
171 | |
141 | =item C<lsblk> |
172 | =item C<create> F<path> I<instructions...> |
|
|
173 | |
|
|
174 | Same as C<edit>, above, except it creates a new data store from scratch if |
|
|
175 | needed. An existing store will be emptied completely. |
|
|
176 | |
|
|
177 | =item C<lsblk> [C<--json>] |
142 | |
178 | |
143 | On a GNU/Linux system, you can get a list of partition device descriptors |
179 | On a GNU/Linux system, you can get a list of partition device descriptors |
144 | using this command - the external C<lsblk> command is required, as well as |
180 | using this command - the external C<lsblk> command is required, as well as |
145 | a mounted C</sys> file system. |
181 | a mounted C</sys> file system. |
146 | |
182 | |
147 | The output will be a list of all partitions in the system and C<partition> |
183 | The output will be a list of all partitions in the system and C<partition> |
148 | descriptors for GPT and both C<legacypartition> and C<partition> |
184 | descriptors for GPT and both C<legacypartition> and C<partition> |
149 | descriptors for MBR partitions. |
185 | descriptors for MBR partitions. |
|
|
186 | |
|
|
187 | With C<--json> it will print similar information as C<lsblk --json>, but |
|
|
188 | with extra C<bcd_device> and C<bcd_legacy_device> attributes. |
|
|
189 | |
|
|
190 | =item C<bcd-device> F<path> |
|
|
191 | |
|
|
192 | Tries to find the BCD device element for the given device, which currently |
|
|
193 | must be a a partition of some kind. Prints the C<partition=> descriptor as |
|
|
194 | a result, or nothing. Exit status will be true on success, and false on |
|
|
195 | failure. |
|
|
196 | |
|
|
197 | Like C<lsblk>, above, this likely only works on GNU/Linux systems. |
|
|
198 | |
|
|
199 | Example: print the partition descriptor of tghe partition with label DATA. |
|
|
200 | |
|
|
201 | $ pbcdedit bcd-device /dev/disk/by-label/DATA |
|
|
202 | partition=<null>,harddisk,mbr,47cbc08a,213579202560 |
|
|
203 | |
|
|
204 | =item C<bcd-legacy-device> F<path> |
|
|
205 | |
|
|
206 | Like above, but uses a C<legacypartition> descriptor instead. |
150 | |
207 | |
151 | =item C<objects> [C<--json>] |
208 | =item C<objects> [C<--json>] |
152 | |
209 | |
153 | Outputs two tables: a table listing all type aliases with their hex BCD |
210 | Outputs two tables: a table listing all type aliases with their hex BCD |
154 | element ID, and all object name aliases with their GUID and default type |
211 | element ID, and all object name aliases with their GUID and default type |
… | |
… | |
233 | } |
290 | } |
234 | |
291 | |
235 | =head2 Minimal BCD to boot windows |
292 | =head2 Minimal BCD to boot windows |
236 | |
293 | |
237 | Experimentally I found the following BCD is the minimum required to |
294 | Experimentally I found the following BCD is the minimum required to |
238 | successfully boot any post-XP version of Windows (suitable C<device> and |
295 | successfully boot any post-XP version of Windows (assuming suitable |
239 | C<osdevice> values, of course): |
296 | C<device> and C<osdevice> values, of course, and assuming a BIOS boot - |
|
|
297 | for UEFI, you should use F<winload.efi> instead of F<winload.exe>): |
240 | |
298 | |
241 | { |
299 | { |
242 | "{bootmgr}" : { |
300 | "{bootmgr}" : { |
243 | "default" : "{45b547a7-8ca6-4417-9eb0-a257b61f35b4}" |
301 | "default" : "{45b547a7-8ca6-4417-9eb0-a257b61f35b4}" |
244 | }, |
302 | }, |
… | |
… | |
255 | |
313 | |
256 | Note that minimal doesn't mean recommended - Windows itself will add stuff |
314 | Note that minimal doesn't mean recommended - Windows itself will add stuff |
257 | to this during or after boot, and you might or might not run into issues |
315 | to this during or after boot, and you might or might not run into issues |
258 | when installing updates as it might not be able to find the F<bootmgr>. |
316 | when installing updates as it might not be able to find the F<bootmgr>. |
259 | |
317 | |
|
|
318 | This is how you would create a minimal hive with PBCDEDIT from within |
|
|
319 | GNU/Linux, assuming F</dev/sdc3> is the windows partition, using |
|
|
320 | a random GUID for the osloader and using C<partition> instead of |
|
|
321 | C<legacypartition>: |
|
|
322 | |
|
|
323 | osldr="{$(uuidgen)}" |
|
|
324 | part=$(pbcdedit bcd-device /dev/sdc3) |
|
|
325 | pbcdedit create minimal.bcd \ |
|
|
326 | set '{bootmgr}' default "$osldr" \ |
|
|
327 | set "$osldr" type application::osloader \ |
|
|
328 | set "$osldr" description 'Windows Boot' \ |
|
|
329 | set "$osldr" device "$part" \ |
|
|
330 | set "$osldr" osdevice "$part" \ |
|
|
331 | set "$osldr" path '\Windows\system32\winload.exe' \ |
|
|
332 | set "$osldr" systemroot '\Windows' |
|
|
333 | |
260 | =head2 The C<meta> key |
334 | =head2 The C<meta> key |
261 | |
335 | |
262 | The C<meta> key is not stored in the BCD data store but is used only |
336 | The C<meta> key is not stored in the BCD data store but is used only |
263 | by PBCDEDIT. It is always generated when exporting, and importing will |
337 | by PBCDEDIT. It is always generated when exporting, and importing will |
264 | be refused when it exists and the version stored inside doesn't store |
338 | be refused when it exists and the version stored inside doesn't match |
265 | the JSON schema version of PBCDEDIT. This ensures that different and |
339 | the JSON schema version of PBCDEDIT. This ensures that different and |
266 | incompatible versions of PBCDEDIT will not read and misinterpret each |
340 | incompatible versions of PBCDEDIT will not read and misinterpret each |
267 | others data. |
341 | others data. |
268 | |
342 | |
269 | =head2 The object keys |
343 | =head2 The object keys |
… | |
… | |
278 | |
352 | |
279 | Some of these GUIDs are fixed well known GUIDs which PBCDEDIT will decode |
353 | Some of these GUIDs are fixed well known GUIDs which PBCDEDIT will decode |
280 | into human-readable strings such as C<{globalsettings}>, which is the same |
354 | into human-readable strings such as C<{globalsettings}>, which is the same |
281 | as C<{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}>. |
355 | as C<{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}>. |
282 | |
356 | |
283 | Each BCD, object has an associated type. For example, |
357 | Each BCD object has an associated type. For example, |
284 | C<application::osloader> for objects loading Windows via F<winload.exe>, |
358 | C<application::osloader> for objects loading Windows via F<winload.exe>, |
285 | C<application::bootsector> for real mode applications and so on. |
359 | C<application::bootsector> for real mode applications and so on. |
286 | |
360 | |
287 | The type of a object is stored in the pseudo BCD element C<type> (see next |
361 | The type of a object is stored in the pseudo BCD element C<type> (see next |
288 | section). |
362 | section). |
… | |
… | |
351 | |
425 | |
352 | "displaybootmenu" : 0, |
426 | "displaybootmenu" : 0, |
353 | |
427 | |
354 | =item integer |
428 | =item integer |
355 | |
429 | |
356 | Again, very simple, this is a 64 bit integer. IT can be either specified |
430 | Again, very simple, this is a 64 bit integer. It can be either specified |
357 | as a decimal number, as a hex number (by prefixing it with C<0x>) or as a |
431 | as a decimal number, as a hex number (by prefixing it with C<0x>) or as a |
358 | binary number (prefix C<0b>). |
432 | binary number (prefix C<0b>). |
359 | |
433 | |
360 | For example, the boot C<timeout> is an integer, specifying the automatic |
434 | For example, the boot C<timeout> is an integer, specifying the automatic |
361 | boot delay in seconds: |
435 | boot delay in seconds: |
… | |
… | |
363 | "timeout" : 30, |
437 | "timeout" : 30, |
364 | |
438 | |
365 | =item integer list |
439 | =item integer list |
366 | |
440 | |
367 | This is a list of 64 bit integers separated by whitespace. It is not used |
441 | This is a list of 64 bit integers separated by whitespace. It is not used |
368 | much, so here is a somewhat artificial an untested example of using |
442 | much, so here is a somewhat artificial and untested example of using |
369 | C<customactions> to specify a certain custom, eh, action to be executed |
443 | C<customactions> to specify a certain custom, eh, action to be executed |
370 | when pressing C<F10> at boot: |
444 | when pressing C<F10> at boot: |
371 | |
445 | |
372 | "customactions" : "0x1000044000001 0x54000001", |
446 | "customactions" : "0x1000044000001 0x54000001", |
373 | |
447 | |
… | |
… | |
401 | This type is why I write I<most> are easy to explain earlier: This type |
475 | This type is why I write I<most> are easy to explain earlier: This type |
402 | is the pinnacle of Microsoft-typical hacks layered on top of other |
476 | is the pinnacle of Microsoft-typical hacks layered on top of other |
403 | hacks. Understanding this type took more time than writing all the rest of |
477 | hacks. Understanding this type took more time than writing all the rest of |
404 | PBCDEDIT, and because it is so complex, this type has its own subsection |
478 | PBCDEDIT, and because it is so complex, this type has its own subsection |
405 | below. |
479 | below. |
|
|
480 | |
406 | =back |
481 | =back |
407 | |
482 | |
408 | =head4 The BCD "device" element type |
483 | =head3 The BCD "device" element type |
409 | |
484 | |
410 | Device elements specify, well, devices. They are used for such diverse |
485 | Device elements specify, well, devices. They are used for such diverse |
411 | purposes such as finding a TFTP network boot image, serial ports or VMBUS |
486 | purposes such as finding a TFTP network boot image, serial ports or VMBUS |
412 | devices, but most commonly they are used to specify the disk (harddisk, |
487 | devices, but most commonly they are used to specify the disk (harddisk, |
413 | cdrom, ramdisk, vhd...) to boot from. |
488 | cdrom, ramdisk, vhd...) to boot from. |
… | |
… | |
421 | element, so almost everything known about it had to be researched first |
496 | element, so almost everything known about it had to be researched first |
422 | in the process of writing this script, and consequently, support for BCD |
497 | in the process of writing this script, and consequently, support for BCD |
423 | device elements is partial only. |
498 | device elements is partial only. |
424 | |
499 | |
425 | On the other hand, the expressive power of PBCDEDIT in specifying devices |
500 | On the other hand, the expressive power of PBCDEDIT in specifying devices |
426 | is much bigger than BCDEDIT and therefore more can be done with it. The |
501 | is much greater than BCDEDIT and therefore more can be done with it. The |
427 | downside is that BCD device elements are much more complicated than what |
502 | downside is that BCD device elements are much more complicated than what |
428 | you might think from reading the BCDEDIT documentation. |
503 | you might think from reading the BCDEDIT documentation. |
429 | |
504 | |
430 | In other words, simple things are complicated, and complicated things are |
505 | In other words, simple things are complicated, and complicated things are |
431 | possible. |
506 | possible. |
… | |
… | |
438 | [{GUID}]type[<flags>][=arg,arg...] |
513 | [{GUID}]type[<flags>][=arg,arg...] |
439 | |
514 | |
440 | Here are some examples: |
515 | Here are some examples: |
441 | |
516 | |
442 | boot |
517 | boot |
443 | {b097d29f-bc00-11e9-8a9a-525400123456}block=file,<boot>,\\EFI" |
518 | {b097d29f-bc00-11e9-8a9a-525400123456}block=file,<boot>,\EFI |
444 | locate=<null>,element,systemroot |
519 | locate=<null>,element,systemroot |
445 | partition=<null>,harddisk,mbr,47cbc08a,1048576 |
520 | partition=<null>,harddisk,mbr,47cbc08a,1048576 |
446 | partition=<null>,harddisk,gpt,9742e468-9206-48a0-b4e4-c4e9745a356a,76d39e5f-ad1b-407e-9c05-c81eb83b57dd |
521 | partition=<null>,harddisk,gpt,9742e468-9206-48a0-b4e4-c4e9745a356a,76d39e5f-ad1b-407e-9c05-c81eb83b57dd |
447 | block<1>=ramdisk,<partition=<null>,harddisk,mbr,47cbc08a,68720525312>,0,0,0,\Recovery\b097d29e-bc00-11e9-8a9a-525400123456\Winre.wim |
522 | block<1>=ramdisk,<partition=<null>,harddisk,mbr,47cbc08a,68720525312>,0,0,0,\Recovery\b097d29e-bc00-11e9-8a9a-525400123456\Winre.wim |
448 | block=file,<partition=<null>,harddisk,gpt,9742e468-9206-48a0-b4e4-c4e9745a356a,ee3a393a-f0de-4057-9946-88584245ed48>,\ |
523 | block=file,<partition=<null>,harddisk,gpt,9742e468-9206-48a0-b4e4-c4e9745a356a,ee3a393a-f0de-4057-9946-88584245ed48>,\ |
… | |
… | |
474 | the leading GUID, which it can always decode). In such cases, it will |
549 | the leading GUID, which it can always decode). In such cases, it will |
475 | convert the device into this type with a hexdump of the element data. |
550 | convert the device into this type with a hexdump of the element data. |
476 | |
551 | |
477 | =item C<null> |
552 | =item C<null> |
478 | |
553 | |
479 | This is another special type - sometimes, a device all zero-filled, which |
554 | This is another special type - sometimes, a device is all zero-filled, |
480 | is not valid. This can mark the absence of a device or something PBCDEDIT |
555 | which is not valid. This can mark the absence of a device or something |
481 | does not understand, so it decodes it into this special "all zero" type |
556 | PBCDEDIT does not understand, so it decodes it into this special "all |
482 | called C<null>. |
557 | zero" type called C<null>. |
483 | |
558 | |
484 | It's most commonly found in devices that can use an optional parent |
559 | It's most commonly found in devices that can use an optional parent |
485 | device, when no parent device is used. |
560 | device, when no parent device is used. |
486 | |
561 | |
487 | =item C<boot> |
562 | =item C<boot> |
… | |
… | |
598 | |
673 | |
599 | Last not least, the most complex type, C<block>, which... specifies block |
674 | Last not least, the most complex type, C<block>, which... specifies block |
600 | devices (which could be inside a F<vhdx> file for example). |
675 | devices (which could be inside a F<vhdx> file for example). |
601 | |
676 | |
602 | I<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>, |
677 | I<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>, |
603 | C<file> or C<vhd> - the same as for C<partiion=>. |
678 | C<file> or C<vhd> - the same as for C<partition=>. |
604 | |
679 | |
605 | The remaining arguments change depending on the I<devicetype>: |
680 | The remaining arguments change depending on the I<devicetype>: |
606 | |
681 | |
607 | =over |
682 | =over |
608 | |
683 | |
… | |
… | |
638 | |
713 | |
639 | Probably not yet implemented. Tell me of your needs... |
714 | Probably not yet implemented. Tell me of your needs... |
640 | |
715 | |
641 | =back |
716 | =back |
642 | |
717 | |
643 | =back5 Examples |
718 | =back |
|
|
719 | |
|
|
720 | =head4 Examples |
644 | |
721 | |
645 | This concludes the syntax overview for device elements, but probably |
722 | This concludes the syntax overview for device elements, but probably |
646 | leaves many questions open. I can't help with most of them, as I also ave |
723 | leaves many questions open. I can't help with most of them, as I also have |
647 | many questions, but I can walk you through some actual examples using more |
724 | many questions, but I can walk you through some actual examples using more |
648 | complex aspects. |
725 | complex aspects. |
|
|
726 | |
|
|
727 | =over |
649 | |
728 | |
650 | =item C<< locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path >> |
729 | =item C<< locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path >> |
651 | |
730 | |
652 | Just like with C declarations, you best treat device descriptors as |
731 | Just like with C declarations, you best treat device descriptors as |
653 | instructions to find your device and work your way from the inside out: |
732 | instructions to find your device and work your way from the inside out: |
… | |
… | |
725 | I don't know what the purpose of the C<< <1> >> flag value is, but it |
804 | I don't know what the purpose of the C<< <1> >> flag value is, but it |
726 | seems to be always there on this kind of entry. |
805 | seems to be always there on this kind of entry. |
727 | |
806 | |
728 | If you have some good examples to add here, feel free to mail me. |
807 | If you have some good examples to add here, feel free to mail me. |
729 | |
808 | |
|
|
809 | =back |
|
|
810 | |
730 | |
811 | |
731 | =head1 EDITING BCD STORES |
812 | =head1 EDITING BCD STORES |
732 | |
813 | |
733 | The C<edit> and C<parse> subcommands allow you to read a BCD data store |
814 | The C<edit> and C<parse> subcommands allow you to read a BCD data store |
734 | and modify it or extract data from it. This is done by executing a series |
815 | and modify it or extract data from it. This is done by executing a series |
… | |
… | |
754 | Example: change the bootmgr default too |
835 | Example: change the bootmgr default too |
755 | C<{b097d2ad-bc00-11e9-8a9a-525400123456}>: |
836 | C<{b097d2ad-bc00-11e9-8a9a-525400123456}>: |
756 | |
837 | |
757 | pbcdedit edit BCD set "{bootmgr}" default "{b097d2ad-bc00-11e9-8a9a-525400123456}" |
838 | pbcdedit edit BCD set "{bootmgr}" default "{b097d2ad-bc00-11e9-8a9a-525400123456}" |
758 | |
839 | |
|
|
840 | =item C<del> I<object> I<element> |
|
|
841 | |
|
|
842 | Similar to C<get>, but removed the BCD element from the specified BCD object. |
|
|
843 | |
759 | =item C<eval> I<perlcode> |
844 | =item C<eval> I<perlcode> |
760 | |
845 | |
761 | This takes the next argument, interprets it as Perl code and |
846 | This takes the next argument, interprets it as Perl code and |
762 | evaluates it. This allows you to do more complicated modifications or |
847 | evaluates it. This allows you to do more complicated modifications or |
763 | extractions. |
848 | extractions. |
… | |
… | |
863 | |
948 | |
864 | # hack used for debugging |
949 | # hack used for debugging |
865 | sub xxd($$) { |
950 | sub xxd($$) { |
866 | open my $xxd, "| xxd | sed -e 's/^/\Q$_[0]\E: /'"; |
951 | open my $xxd, "| xxd | sed -e 's/^/\Q$_[0]\E: /'"; |
867 | syswrite $xxd, $_[1]; |
952 | syswrite $xxd, $_[1]; |
|
|
953 | } |
|
|
954 | |
|
|
955 | # get some meta info on a file (uid, gid, perms) |
|
|
956 | sub stat_get($) { |
|
|
957 | [(stat shift)[4, 5, 2]] |
|
|
958 | } |
|
|
959 | |
|
|
960 | # set stat info on a file |
|
|
961 | sub stat_set($$) { |
|
|
962 | my ($fh_or_path, $stat) = @_; |
|
|
963 | |
|
|
964 | return unless $stat; |
|
|
965 | chown $stat->[0], $stat->[1], $fh_or_path; |
|
|
966 | chmod +($stat->[2] & 07777), $fh_or_path; |
868 | } |
967 | } |
869 | |
968 | |
870 | sub file_load($) { |
969 | sub file_load($) { |
871 | my ($path) = @_; |
970 | my ($path) = @_; |
872 | |
971 | |
… | |
… | |
875 | my $size = -s $fh; |
974 | my $size = -s $fh; |
876 | $size = read $fh, my $buf, $size |
975 | $size = read $fh, my $buf, $size |
877 | or die "$path: short read\n"; |
976 | or die "$path: short read\n"; |
878 | |
977 | |
879 | $buf |
978 | $buf |
|
|
979 | } |
|
|
980 | |
|
|
981 | sub file_save($$;$) { |
|
|
982 | my ($path, $data, $stat) = @_; |
|
|
983 | |
|
|
984 | open my $fh, ">:raw", "$path~" |
|
|
985 | or die "$path~: $!\n"; |
|
|
986 | print $fh $data |
|
|
987 | or die "$path~: short write\n"; |
|
|
988 | stat_set $fh, $stat; |
|
|
989 | $fh->sync; |
|
|
990 | close $fh; |
|
|
991 | |
|
|
992 | rename "$path~", $path; |
880 | } |
993 | } |
881 | |
994 | |
882 | # sources and resources used for writing pbcdedit |
995 | # sources and resources used for writing pbcdedit |
883 | # |
996 | # |
884 | # registry: |
997 | # registry: |
… | |
… | |
1070 | my ($rname, $root) = $decode_key->($rootcell); |
1183 | my ($rname, $root) = $decode_key->($rootcell); |
1071 | |
1184 | |
1072 | [$rname, $root] |
1185 | [$rname, $root] |
1073 | } |
1186 | } |
1074 | |
1187 | |
1075 | # return a binary windows fILETIME struct |
1188 | # return a binary windows FILETIME struct |
1076 | sub filetime_now { |
1189 | sub filetime_now { |
1077 | my ($s, $ms) = Time::HiRes::gettimeofday; |
1190 | my ($s, $ms) = Time::HiRes::gettimeofday; |
1078 | |
1191 | |
1079 | pack "Q<", $s = ($s * 1_000_000 + $ms) * 10 + 116_444_736_000_000_000 |
1192 | pack "Q<", ($s * 1_000_000 + $ms) * 10 |
|
|
1193 | + 116_444_736_000_000_000 # 1970-01-01 00:00:00 |
1080 | } |
1194 | } |
1081 | |
1195 | |
1082 | # encode a registry hive |
1196 | # encode a registry hive |
1083 | sub regf_encode($) { |
1197 | sub regf_encode($) { |
1084 | my ($hive) = @_; |
1198 | my ($hive) = @_; |
… | |
… | |
1087 | |
1201 | |
1088 | # the filetime is apparently used to verify log file validity, |
1202 | # the filetime is apparently used to verify log file validity, |
1089 | # so by generating a new timestamp the log files *should* automatically |
1203 | # so by generating a new timestamp the log files *should* automatically |
1090 | # become invalidated and windows would "self-heal" them. |
1204 | # become invalidated and windows would "self-heal" them. |
1091 | # (update: has been verified by reverse engineering) |
1205 | # (update: has been verified by reverse engineering) |
1092 | # possibly the fact that the two sequence numbes match might also |
1206 | # possibly the fact that the two sequence numbers match might also |
1093 | # make windows think that the hive is not dirty and ignore logs. |
1207 | # make windows think that the hive is not dirty and ignore logs. |
1094 | # (update: has been verified by reverse engineering) |
1208 | # (update: has been verified by reverse engineering) |
1095 | |
1209 | |
1096 | my $now = filetime_now; |
1210 | my $now = filetime_now; |
1097 | |
1211 | |
… | |
… | |
1241 | |
1355 | |
1242 | regf_decode file_load $path |
1356 | regf_decode file_load $path |
1243 | } |
1357 | } |
1244 | |
1358 | |
1245 | # encode and save registry to file |
1359 | # encode and save registry to file |
1246 | sub regf_save { |
1360 | sub regf_save($$;$) { |
1247 | my ($path, $hive) = @_; |
1361 | my ($path, $hive, $stat) = @_; |
1248 | |
1362 | |
1249 | $hive = regf_encode $hive; |
1363 | $hive = regf_encode $hive; |
1250 | |
1364 | |
1251 | open my $regf, ">:raw", "$path~" |
1365 | file_save $path, $hive, $stat; |
1252 | or die "$path~: $!\n"; |
|
|
1253 | print $regf $hive |
|
|
1254 | or die "$path~: short write\n"; |
|
|
1255 | $regf->sync; |
|
|
1256 | close $regf; |
|
|
1257 | |
|
|
1258 | rename "$path~", $path; |
|
|
1259 | } |
1366 | } |
1260 | |
1367 | |
1261 | ############################################################################# |
1368 | ############################################################################# |
1262 | # bcd stuff |
1369 | # bcd stuff |
1263 | |
1370 | |
1264 | # human-readable alises for GUID object identifiers |
1371 | # human-readable aliases for GUID object identifiers |
1265 | our %bcd_objects = ( |
1372 | our %bcd_objects = ( |
1266 | '{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}' => '{emssettings}', |
1373 | '{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}' => '{emssettings}', |
1267 | '{1afa9c49-16ab-4a5c-4a90-212802da9460}' => '{resumeloadersettings}', |
1374 | '{1afa9c49-16ab-4a5c-4a90-212802da9460}' => '{resumeloadersettings}', |
1268 | '{1cae1eb7-a0df-4d4d-9851-4860e34ef535}' => '{default}', |
1375 | '{1cae1eb7-a0df-4d4d-9851-4860e34ef535}' => '{default}', |
1269 | '{313e8eed-7098-4586-a9bf-309c61f8d449}' => '{kerneldbgsettings}', |
1376 | '{313e8eed-7098-4586-a9bf-309c61f8d449}' => '{kerneldbgsettings}', |
… | |
… | |
1399 | BCDE_FORMAT_STRING , sub { shift }, |
1506 | BCDE_FORMAT_STRING , sub { shift }, |
1400 | BCDE_FORMAT_GUID , sub { dec_wguid enc_wguid shift }, |
1507 | BCDE_FORMAT_GUID , sub { dec_wguid enc_wguid shift }, |
1401 | BCDE_FORMAT_GUID_LIST , sub { join " ", map dec_wguid enc_wguid $_, @{+shift} }, |
1508 | BCDE_FORMAT_GUID_LIST , sub { join " ", map dec_wguid enc_wguid $_, @{+shift} }, |
1402 | BCDE_FORMAT_INTEGER , sub { unpack "Q", pack "a8", pack "H*", shift }, # integer might be 4 or 8 bytes - caused by ms coding bugs |
1509 | BCDE_FORMAT_INTEGER , sub { unpack "Q", pack "a8", pack "H*", shift }, # integer might be 4 or 8 bytes - caused by ms coding bugs |
1403 | BCDE_FORMAT_BOOLEAN , sub { shift eq "00" ? 0 : 1 }, |
1510 | BCDE_FORMAT_BOOLEAN , sub { shift eq "00" ? 0 : 1 }, |
1404 | BCDE_FORMAT_INTEGER_LIST, sub { join " ", unpack "Q*", pack "H*", shift }, # not sure if this cna be 4 bytes |
1511 | BCDE_FORMAT_INTEGER_LIST, sub { join " ", unpack "Q*", pack "H*", shift }, # not sure if this can be 4 bytes |
1405 | ); |
1512 | ); |
1406 | |
1513 | |
1407 | our %bcde_enc = ( |
1514 | our %bcde_enc = ( |
1408 | BCDE_FORMAT_DEVICE , sub { binary => enc_device $_[0], $_[1] }, |
1515 | BCDE_FORMAT_DEVICE , sub { binary => enc_device $_[0], $_[1] }, |
1409 | BCDE_FORMAT_STRING , sub { sz => shift }, |
1516 | BCDE_FORMAT_STRING , sub { sz => shift }, |
… | |
… | |
1415 | ); |
1522 | ); |
1416 | |
1523 | |
1417 | # BCD Elements |
1524 | # BCD Elements |
1418 | our %bcde_byclass = ( |
1525 | our %bcde_byclass = ( |
1419 | any => { |
1526 | any => { |
1420 | 0x11000001 => 'device', |
1527 | 0x11000001 => 'device', |
1421 | 0x12000002 => 'path', |
1528 | 0x12000002 => 'path', |
1422 | 0x12000004 => 'description', |
1529 | 0x12000004 => 'description', |
1423 | 0x12000005 => 'locale', |
1530 | 0x12000005 => 'locale', |
1424 | 0x14000006 => 'inherit', |
1531 | 0x14000006 => 'inherit', |
1425 | 0x15000007 => 'truncatememory', |
1532 | 0x15000007 => 'truncatememory', |
1426 | 0x14000008 => 'recoverysequence', |
1533 | 0x14000008 => 'recoverysequence', |
1427 | 0x16000009 => 'recoveryenabled', |
1534 | 0x16000009 => 'recoveryenabled', |
1428 | 0x1700000a => 'badmemorylist', |
1535 | 0x1700000a => 'badmemorylist', |
1429 | 0x1600000b => 'badmemoryaccess', |
1536 | 0x1600000b => 'badmemoryaccess', |
1430 | 0x1500000c => 'firstmegabytepolicy', |
1537 | 0x1500000c => 'firstmegabytepolicy', |
1431 | 0x1500000d => 'relocatephysical', |
1538 | 0x1500000d => 'relocatephysical', |
1432 | 0x1500000e => 'avoidlowmemory', |
1539 | 0x1500000e => 'avoidlowmemory', |
1433 | 0x1600000f => 'traditionalkseg', |
1540 | 0x1600000f => 'traditionalkseg', |
1434 | 0x16000010 => 'bootdebug', |
1541 | 0x16000010 => 'bootdebug', |
1435 | 0x15000011 => 'debugtype', |
1542 | 0x15000011 => 'debugtype', |
1436 | 0x15000012 => 'debugaddress', |
1543 | 0x15000012 => 'debugaddress', |
1437 | 0x15000013 => 'debugport', |
1544 | 0x15000013 => 'debugport', |
1438 | 0x15000014 => 'baudrate', |
1545 | 0x15000014 => 'baudrate', |
1439 | 0x15000015 => 'channel', |
1546 | 0x15000015 => 'channel', |
1440 | 0x12000016 => 'targetname', |
1547 | 0x12000016 => 'targetname', |
1441 | 0x16000017 => 'noumex', |
1548 | 0x16000017 => 'noumex', |
1442 | 0x15000018 => 'debugstart', |
1549 | 0x15000018 => 'debugstart', |
1443 | 0x12000019 => 'busparams', |
1550 | 0x12000019 => 'busparams', |
1444 | 0x1500001a => 'hostip', |
1551 | 0x1500001a => 'hostip', |
1445 | 0x1500001b => 'port', |
1552 | 0x1500001b => 'port', |
1446 | 0x1600001c => 'dhcp', |
1553 | 0x1600001c => 'dhcp', |
1447 | 0x1200001d => 'key', |
1554 | 0x1200001d => 'key', |
1448 | 0x1600001e => 'vm', |
1555 | 0x1600001e => 'vm', |
1449 | 0x16000020 => 'bootems', |
1556 | 0x16000020 => 'bootems', |
1450 | 0x15000022 => 'emsport', |
1557 | 0x15000022 => 'emsport', |
1451 | 0x15000023 => 'emsbaudrate', |
1558 | 0x15000023 => 'emsbaudrate', |
1452 | 0x12000030 => 'loadoptions', |
1559 | 0x12000030 => 'loadoptions', |
1453 | 0x16000040 => 'advancedoptions', |
1560 | 0x16000040 => 'advancedoptions', |
1454 | 0x16000041 => 'optionsedit', |
1561 | 0x16000041 => 'optionsedit', |
1455 | 0x15000042 => 'keyringaddress', |
1562 | 0x15000042 => 'keyringaddress', |
1456 | 0x11000043 => 'bootstatdevice', |
1563 | 0x11000043 => 'bootstatdevice', |
1457 | 0x12000044 => 'bootstatfilepath', |
1564 | 0x12000044 => 'bootstatfilepath', |
1458 | 0x16000045 => 'preservebootstat', |
1565 | 0x16000045 => 'preservebootstat', |
1459 | 0x16000046 => 'graphicsmodedisabled', |
1566 | 0x16000046 => 'graphicsmodedisabled', |
1460 | 0x15000047 => 'configaccesspolicy', |
1567 | 0x15000047 => 'configaccesspolicy', |
1461 | 0x16000048 => 'nointegritychecks', |
1568 | 0x16000048 => 'nointegritychecks', |
1462 | 0x16000049 => 'testsigning', |
1569 | 0x16000049 => 'testsigning', |
1463 | 0x1200004a => 'fontpath', |
1570 | 0x1200004a => 'fontpath', |
1464 | 0x1500004b => 'integrityservices', |
1571 | 0x1500004b => 'integrityservices', |
1465 | 0x1500004c => 'volumebandid', |
1572 | 0x1500004c => 'volumebandid', |
1466 | 0x16000050 => 'extendedinput', |
1573 | 0x16000050 => 'extendedinput', |
1467 | 0x15000051 => 'initialconsoleinput', |
1574 | 0x15000051 => 'initialconsoleinput', |
1468 | 0x15000052 => 'graphicsresolution', |
1575 | 0x15000052 => 'graphicsresolution', |
1469 | 0x16000053 => 'restartonfailure', |
1576 | 0x16000053 => 'restartonfailure', |
1470 | 0x16000054 => 'highestmode', |
1577 | 0x16000054 => 'highestmode', |
1471 | 0x16000060 => 'isolatedcontext', |
1578 | 0x16000060 => 'isolatedcontext', |
1472 | 0x15000065 => 'displaymessage', |
1579 | 0x15000065 => 'displaymessage', |
1473 | 0x15000066 => 'displaymessageoverride', |
1580 | 0x15000066 => 'displaymessageoverride', |
1474 | 0x16000068 => 'nobootuxtext', |
1581 | 0x16000068 => 'nobootuxtext', |
1475 | 0x16000069 => 'nobootuxprogress', |
1582 | 0x16000069 => 'nobootuxprogress', |
1476 | 0x1600006a => 'nobootuxfade', |
1583 | 0x1600006a => 'nobootuxfade', |
1477 | 0x1600006b => 'bootuxreservepooldebug', |
1584 | 0x1600006b => 'bootuxreservepooldebug', |
1478 | 0x1600006c => 'bootuxdisabled', |
1585 | 0x1600006c => 'bootuxdisabled', |
1479 | 0x1500006d => 'bootuxfadeframes', |
1586 | 0x1500006d => 'bootuxfadeframes', |
1480 | 0x1600006e => 'bootuxdumpstats', |
1587 | 0x1600006e => 'bootuxdumpstats', |
1481 | 0x1600006f => 'bootuxshowstats', |
1588 | 0x1600006f => 'bootuxshowstats', |
1482 | 0x16000071 => 'multibootsystem', |
1589 | 0x16000071 => 'multibootsystem', |
1483 | 0x16000072 => 'nokeyboard', |
1590 | 0x16000072 => 'nokeyboard', |
1484 | 0x15000073 => 'aliaswindowskey', |
1591 | 0x15000073 => 'aliaswindowskey', |
1485 | 0x16000074 => 'bootshutdowndisabled', |
1592 | 0x16000074 => 'bootshutdowndisabled', |
1486 | 0x15000075 => 'performancefrequency', |
1593 | 0x15000075 => 'performancefrequency', |
1487 | 0x15000076 => 'securebootrawpolicy', |
1594 | 0x15000076 => 'securebootrawpolicy', |
1488 | 0x17000077 => 'allowedinmemorysettings', |
1595 | 0x17000077 => 'allowedinmemorysettings', |
1489 | 0x15000079 => 'bootuxtransitiontime', |
1596 | 0x15000079 => 'bootuxtransitiontime', |
1490 | 0x1600007a => 'mobilegraphics', |
1597 | 0x1600007a => 'mobilegraphics', |
1491 | 0x1600007b => 'forcefipscrypto', |
1598 | 0x1600007b => 'forcefipscrypto', |
1492 | 0x1500007d => 'booterrorux', |
1599 | 0x1500007d => 'booterrorux', |
1493 | 0x1600007e => 'flightsigning', |
1600 | 0x1600007e => 'flightsigning', |
1494 | 0x1500007f => 'measuredbootlogformat', |
1601 | 0x1500007f => 'measuredbootlogformat', |
1495 | 0x15000080 => 'displayrotation', |
1602 | 0x15000080 => 'displayrotation', |
1496 | 0x15000081 => 'logcontrol', |
1603 | 0x15000081 => 'logcontrol', |
1497 | 0x16000082 => 'nofirmwaresync', |
1604 | 0x16000082 => 'nofirmwaresync', |
1498 | 0x11000084 => 'windowssyspart', |
1605 | 0x11000084 => 'windowssyspart', |
1499 | 0x16000087 => 'numlock', |
1606 | 0x16000087 => 'numlock', |
1500 | 0x26000202 => 'skipffumode', |
1607 | 0x26000202 => 'skipffumode', |
1501 | 0x26000203 => 'forceffumode', |
1608 | 0x26000203 => 'forceffumode', |
1502 | 0x25000510 => 'chargethreshold', |
1609 | 0x25000510 => 'chargethreshold', |
1503 | 0x26000512 => 'offmodecharging', |
1610 | 0x26000512 => 'offmodecharging', |
1504 | 0x25000aaa => 'bootflow', |
1611 | 0x25000aaa => 'bootflow', |
1505 | 0x45000001 => 'devicetype', |
1612 | 0x45000001 => 'devicetype', |
1506 | 0x42000002 => 'applicationrelativepath', |
1613 | 0x42000002 => 'applicationrelativepath', |
1507 | 0x42000003 => 'ramdiskdevicerelativepath', |
1614 | 0x42000003 => 'ramdiskdevicerelativepath', |
1508 | 0x46000004 => 'omitosloaderelements', |
1615 | 0x46000004 => 'omitosloaderelements', |
1509 | 0x47000006 => 'elementstomigrate', |
1616 | 0x47000006 => 'elementstomigrate', |
1510 | 0x46000010 => 'recoveryos', |
1617 | 0x46000010 => 'recoveryos', |
1511 | }, |
1618 | }, |
1512 | bootapp => { |
1619 | bootapp => { |
1513 | 0x26000145 => 'enablebootdebugpolicy', |
1620 | 0x26000145 => 'enablebootdebugpolicy', |
1514 | 0x26000146 => 'enablebootorderclean', |
1621 | 0x26000146 => 'enablebootorderclean', |
1515 | 0x26000147 => 'enabledeviceid', |
1622 | 0x26000147 => 'enabledeviceid', |
1516 | 0x26000148 => 'enableffuloader', |
1623 | 0x26000148 => 'enableffuloader', |
1517 | 0x26000149 => 'enableiuloader', |
1624 | 0x26000149 => 'enableiuloader', |
1518 | 0x2600014a => 'enablemassstorage', |
1625 | 0x2600014a => 'enablemassstorage', |
1519 | 0x2600014b => 'enablerpmbprovisioning', |
1626 | 0x2600014b => 'enablerpmbprovisioning', |
1520 | 0x2600014c => 'enablesecurebootpolicy', |
1627 | 0x2600014c => 'enablesecurebootpolicy', |
1521 | 0x2600014d => 'enablestartcharge', |
1628 | 0x2600014d => 'enablestartcharge', |
1522 | 0x2600014e => 'enableresettpm', |
1629 | 0x2600014e => 'enableresettpm', |
1523 | }, |
1630 | }, |
1524 | bootmgr => { |
1631 | bootmgr => { |
1525 | 0x24000001 => 'displayorder', |
1632 | 0x24000001 => 'displayorder', |
1526 | 0x24000002 => 'bootsequence', |
1633 | 0x24000002 => 'bootsequence', |
1527 | 0x23000003 => 'default', |
1634 | 0x23000003 => 'default', |
1528 | 0x25000004 => 'timeout', |
1635 | 0x25000004 => 'timeout', |
1529 | 0x26000005 => 'resume', |
1636 | 0x26000005 => 'resume', |
1530 | 0x23000006 => 'resumeobject', |
1637 | 0x23000006 => 'resumeobject', |
1531 | 0x24000007 => 'startupsequence', |
1638 | 0x24000007 => 'startupsequence', |
1532 | 0x24000010 => 'toolsdisplayorder', |
1639 | 0x24000010 => 'toolsdisplayorder', |
1533 | 0x26000020 => 'displaybootmenu', |
1640 | 0x26000020 => 'displaybootmenu', |
1534 | 0x26000021 => 'noerrordisplay', |
1641 | 0x26000021 => 'noerrordisplay', |
1535 | 0x21000022 => 'bcddevice', |
1642 | 0x21000022 => 'bcddevice', |
1536 | 0x22000023 => 'bcdfilepath', |
1643 | 0x22000023 => 'bcdfilepath', |
1537 | 0x26000024 => 'hormenabled', |
1644 | 0x26000024 => 'hormenabled', |
1538 | 0x26000025 => 'hiberboot', |
1645 | 0x26000025 => 'hiberboot', |
1539 | 0x22000026 => 'passwordoverride', |
1646 | 0x22000026 => 'passwordoverride', |
1540 | 0x22000027 => 'pinpassphraseoverride', |
1647 | 0x22000027 => 'pinpassphraseoverride', |
1541 | 0x26000028 => 'processcustomactionsfirst', |
1648 | 0x26000028 => 'processcustomactionsfirst', |
1542 | 0x27000030 => 'customactions', |
1649 | 0x27000030 => 'customactions', |
1543 | 0x26000031 => 'persistbootsequence', |
1650 | 0x26000031 => 'persistbootsequence', |
1544 | 0x26000032 => 'skipstartupsequence', |
1651 | 0x26000032 => 'skipstartupsequence', |
1545 | 0x22000040 => 'fverecoveryurl', |
1652 | 0x22000040 => 'fverecoveryurl', |
1546 | 0x22000041 => 'fverecoverymessage', |
1653 | 0x22000041 => 'fverecoverymessage', |
1547 | }, |
1654 | }, |
1548 | device => { |
1655 | device => { |
1549 | 0x35000001 => 'ramdiskimageoffset', |
1656 | 0x35000001 => 'ramdiskimageoffset', |
1550 | 0x35000002 => 'ramdisktftpclientport', |
1657 | 0x35000002 => 'ramdisktftpclientport', |
1551 | 0x31000003 => 'ramdisksdidevice', |
1658 | 0x31000003 => 'ramdisksdidevice', |
1552 | 0x32000004 => 'ramdisksdipath', |
1659 | 0x32000004 => 'ramdisksdipath', |
1553 | 0x35000005 => 'ramdiskimagelength', |
1660 | 0x35000005 => 'ramdiskimagelength', |
1554 | 0x36000006 => 'exportascd', |
1661 | 0x36000006 => 'exportascd', |
1555 | 0x35000007 => 'ramdisktftpblocksize', |
1662 | 0x35000007 => 'ramdisktftpblocksize', |
1556 | 0x35000008 => 'ramdisktftpwindowsize', |
1663 | 0x35000008 => 'ramdisktftpwindowsize', |
1557 | 0x36000009 => 'ramdiskmcenabled', |
1664 | 0x36000009 => 'ramdiskmcenabled', |
1558 | 0x3600000a => 'ramdiskmctftpfallback', |
1665 | 0x3600000a => 'ramdiskmctftpfallback', |
1559 | 0x3600000b => 'ramdisktftpvarwindow', |
1666 | 0x3600000b => 'ramdisktftpvarwindow', |
1560 | }, |
1667 | }, |
1561 | memdiag => { |
1668 | memdiag => { |
1562 | 0x25000001 => 'passcount', |
1669 | 0x25000001 => 'passcount', |
1563 | 0x25000002 => 'testmix', |
1670 | 0x25000002 => 'testmix', |
1564 | 0x25000003 => 'failurecount', |
1671 | 0x25000003 => 'failurecount', |
1565 | 0x26000003 => 'cacheenable', |
1672 | 0x26000003 => 'cacheenable', |
1566 | 0x25000004 => 'testtofail', |
1673 | 0x25000004 => 'testtofail', |
1567 | 0x26000004 => 'failuresenabled', |
1674 | 0x26000004 => 'failuresenabled', |
1568 | 0x25000005 => 'stridefailcount', |
1675 | 0x25000005 => 'stridefailcount', |
1569 | 0x26000005 => 'cacheenable', |
1676 | 0x26000005 => 'cacheenable', |
1570 | 0x25000006 => 'invcfailcount', |
1677 | 0x25000006 => 'invcfailcount', |
1571 | 0x25000007 => 'matsfailcount', |
1678 | 0x25000007 => 'matsfailcount', |
1572 | 0x25000008 => 'randfailcount', |
1679 | 0x25000008 => 'randfailcount', |
1573 | 0x25000009 => 'chckrfailcount', |
1680 | 0x25000009 => 'chckrfailcount', |
1574 | }, |
1681 | }, |
1575 | ntldr => { |
1682 | ntldr => { |
1576 | 0x22000001 => 'bpbstring', |
1683 | 0x22000001 => 'bpbstring', |
1577 | }, |
1684 | }, |
1578 | osloader => { |
1685 | osloader => { |
1579 | 0x21000001 => 'osdevice', |
1686 | 0x21000001 => 'osdevice', |
1580 | 0x22000002 => 'systemroot', |
1687 | 0x22000002 => 'systemroot', |
1581 | 0x23000003 => 'resumeobject', |
1688 | 0x23000003 => 'resumeobject', |
1582 | 0x26000004 => 'stampdisks', |
1689 | 0x26000004 => 'stampdisks', |
1583 | 0x26000010 => 'detecthal', |
1690 | 0x26000010 => 'detecthal', |
1584 | 0x22000011 => 'kernel', |
1691 | 0x22000011 => 'kernel', |
1585 | 0x22000012 => 'hal', |
1692 | 0x22000012 => 'hal', |
1586 | 0x22000013 => 'dbgtransport', |
1693 | 0x22000013 => 'dbgtransport', |
1587 | 0x25000020 => 'nx', |
1694 | 0x25000020 => 'nx', |
1588 | 0x25000021 => 'pae', |
1695 | 0x25000021 => 'pae', |
1589 | 0x26000022 => 'winpe', |
1696 | 0x26000022 => 'winpe', |
1590 | 0x26000024 => 'nocrashautoreboot', |
1697 | 0x26000024 => 'nocrashautoreboot', |
1591 | 0x26000025 => 'lastknowngood', |
1698 | 0x26000025 => 'lastknowngood', |
1592 | 0x26000026 => 'oslnointegritychecks', |
1699 | 0x26000026 => 'oslnointegritychecks', |
1593 | 0x26000027 => 'osltestsigning', |
1700 | 0x26000027 => 'osltestsigning', |
1594 | 0x26000030 => 'nolowmem', |
1701 | 0x26000030 => 'nolowmem', |
1595 | 0x25000031 => 'removememory', |
1702 | 0x25000031 => 'removememory', |
1596 | 0x25000032 => 'increaseuserva', |
1703 | 0x25000032 => 'increaseuserva', |
1597 | 0x25000033 => 'perfmem', |
1704 | 0x25000033 => 'perfmem', |
1598 | 0x26000040 => 'vga', |
1705 | 0x26000040 => 'vga', |
1599 | 0x26000041 => 'quietboot', |
1706 | 0x26000041 => 'quietboot', |
1600 | 0x26000042 => 'novesa', |
1707 | 0x26000042 => 'novesa', |
1601 | 0x26000043 => 'novga', |
1708 | 0x26000043 => 'novga', |
1602 | 0x25000050 => 'clustermodeaddressing', |
1709 | 0x25000050 => 'clustermodeaddressing', |
1603 | 0x26000051 => 'usephysicaldestination', |
1710 | 0x26000051 => 'usephysicaldestination', |
1604 | 0x25000052 => 'restrictapiccluster', |
1711 | 0x25000052 => 'restrictapiccluster', |
1605 | 0x22000053 => 'evstore', |
1712 | 0x22000053 => 'evstore', |
1606 | 0x26000054 => 'uselegacyapicmode', |
1713 | 0x26000054 => 'uselegacyapicmode', |
1607 | 0x26000060 => 'onecpu', |
1714 | 0x26000060 => 'onecpu', |
1608 | 0x25000061 => 'numproc', |
1715 | 0x25000061 => 'numproc', |
1609 | 0x26000062 => 'maxproc', |
1716 | 0x26000062 => 'maxproc', |
1610 | 0x25000063 => 'configflags', |
1717 | 0x25000063 => 'configflags', |
1611 | 0x26000064 => 'maxgroup', |
1718 | 0x26000064 => 'maxgroup', |
1612 | 0x26000065 => 'groupaware', |
1719 | 0x26000065 => 'groupaware', |
1613 | 0x25000066 => 'groupsize', |
1720 | 0x25000066 => 'groupsize', |
1614 | 0x26000070 => 'usefirmwarepcisettings', |
1721 | 0x26000070 => 'usefirmwarepcisettings', |
1615 | 0x25000071 => 'msi', |
1722 | 0x25000071 => 'msi', |
1616 | 0x25000072 => 'pciexpress', |
1723 | 0x25000072 => 'pciexpress', |
1617 | 0x25000080 => 'safeboot', |
1724 | 0x25000080 => 'safeboot', |
1618 | 0x26000081 => 'safebootalternateshell', |
1725 | 0x26000081 => 'safebootalternateshell', |
1619 | 0x26000090 => 'bootlog', |
1726 | 0x26000090 => 'bootlog', |
1620 | 0x26000091 => 'sos', |
1727 | 0x26000091 => 'sos', |
1621 | 0x260000a0 => 'debug', |
1728 | 0x260000a0 => 'debug', |
1622 | 0x260000a1 => 'halbreakpoint', |
1729 | 0x260000a1 => 'halbreakpoint', |
1623 | 0x260000a2 => 'useplatformclock', |
1730 | 0x260000a2 => 'useplatformclock', |
1624 | 0x260000a3 => 'forcelegacyplatform', |
1731 | 0x260000a3 => 'forcelegacyplatform', |
1625 | 0x260000a4 => 'useplatformtick', |
1732 | 0x260000a4 => 'useplatformtick', |
1626 | 0x260000a5 => 'disabledynamictick', |
1733 | 0x260000a5 => 'disabledynamictick', |
1627 | 0x250000a6 => 'tscsyncpolicy', |
1734 | 0x250000a6 => 'tscsyncpolicy', |
1628 | 0x260000b0 => 'ems', |
1735 | 0x260000b0 => 'ems', |
1629 | 0x250000c0 => 'forcefailure', |
1736 | 0x250000c0 => 'forcefailure', |
1630 | 0x250000c1 => 'driverloadfailurepolicy', |
1737 | 0x250000c1 => 'driverloadfailurepolicy', |
1631 | 0x250000c2 => 'bootmenupolicy', |
1738 | 0x250000c2 => 'bootmenupolicy', |
1632 | 0x260000c3 => 'onetimeadvancedoptions', |
1739 | 0x260000c3 => 'onetimeadvancedoptions', |
1633 | 0x260000c4 => 'onetimeoptionsedit', |
1740 | 0x260000c4 => 'onetimeoptionsedit', |
1634 | 0x250000e0 => 'bootstatuspolicy', |
1741 | 0x250000e0 => 'bootstatuspolicy', |
1635 | 0x260000e1 => 'disableelamdrivers', |
1742 | 0x260000e1 => 'disableelamdrivers', |
1636 | 0x250000f0 => 'hypervisorlaunchtype', |
1743 | 0x250000f0 => 'hypervisorlaunchtype', |
1637 | 0x220000f1 => 'hypervisorpath', |
1744 | 0x220000f1 => 'hypervisorpath', |
1638 | 0x260000f2 => 'hypervisordebug', |
1745 | 0x260000f2 => 'hypervisordebug', |
1639 | 0x250000f3 => 'hypervisordebugtype', |
1746 | 0x250000f3 => 'hypervisordebugtype', |
1640 | 0x250000f4 => 'hypervisordebugport', |
1747 | 0x250000f4 => 'hypervisordebugport', |
1641 | 0x250000f5 => 'hypervisorbaudrate', |
1748 | 0x250000f5 => 'hypervisorbaudrate', |
1642 | 0x250000f6 => 'hypervisorchannel', |
1749 | 0x250000f6 => 'hypervisorchannel', |
1643 | 0x250000f7 => 'bootux', |
1750 | 0x250000f7 => 'bootux', |
1644 | 0x260000f8 => 'hypervisordisableslat', |
1751 | 0x260000f8 => 'hypervisordisableslat', |
1645 | 0x220000f9 => 'hypervisorbusparams', |
1752 | 0x220000f9 => 'hypervisorbusparams', |
1646 | 0x250000fa => 'hypervisornumproc', |
1753 | 0x250000fa => 'hypervisornumproc', |
1647 | 0x250000fb => 'hypervisorrootprocpernode', |
1754 | 0x250000fb => 'hypervisorrootprocpernode', |
1648 | 0x260000fc => 'hypervisoruselargevtlb', |
1755 | 0x260000fc => 'hypervisoruselargevtlb', |
1649 | 0x250000fd => 'hypervisorhostip', |
1756 | 0x250000fd => 'hypervisorhostip', |
1650 | 0x250000fe => 'hypervisorhostport', |
1757 | 0x250000fe => 'hypervisorhostport', |
1651 | 0x250000ff => 'hypervisordebugpages', |
1758 | 0x250000ff => 'hypervisordebugpages', |
1652 | 0x25000100 => 'tpmbootentropy', |
1759 | 0x25000100 => 'tpmbootentropy', |
1653 | 0x22000110 => 'hypervisorusekey', |
1760 | 0x22000110 => 'hypervisorusekey', |
1654 | 0x22000112 => 'hypervisorproductskutype', |
1761 | 0x22000112 => 'hypervisorproductskutype', |
1655 | 0x25000113 => 'hypervisorrootproc', |
1762 | 0x25000113 => 'hypervisorrootproc', |
1656 | 0x26000114 => 'hypervisordhcp', |
1763 | 0x26000114 => 'hypervisordhcp', |
1657 | 0x25000115 => 'hypervisoriommupolicy', |
1764 | 0x25000115 => 'hypervisoriommupolicy', |
1658 | 0x26000116 => 'hypervisorusevapic', |
1765 | 0x26000116 => 'hypervisorusevapic', |
1659 | 0x22000117 => 'hypervisorloadoptions', |
1766 | 0x22000117 => 'hypervisorloadoptions', |
1660 | 0x25000118 => 'hypervisormsrfilterpolicy', |
1767 | 0x25000118 => 'hypervisormsrfilterpolicy', |
1661 | 0x25000119 => 'hypervisormmionxpolicy', |
1768 | 0x25000119 => 'hypervisormmionxpolicy', |
1662 | 0x2500011a => 'hypervisorschedulertype', |
1769 | 0x2500011a => 'hypervisorschedulertype', |
1663 | 0x25000120 => 'xsavepolicy', |
1770 | 0x25000120 => 'xsavepolicy', |
1664 | 0x25000121 => 'xsaveaddfeature0', |
1771 | 0x25000121 => 'xsaveaddfeature0', |
1665 | 0x25000122 => 'xsaveaddfeature1', |
1772 | 0x25000122 => 'xsaveaddfeature1', |
1666 | 0x25000123 => 'xsaveaddfeature2', |
1773 | 0x25000123 => 'xsaveaddfeature2', |
1667 | 0x25000124 => 'xsaveaddfeature3', |
1774 | 0x25000124 => 'xsaveaddfeature3', |
1668 | 0x25000125 => 'xsaveaddfeature4', |
1775 | 0x25000125 => 'xsaveaddfeature4', |
1669 | 0x25000126 => 'xsaveaddfeature5', |
1776 | 0x25000126 => 'xsaveaddfeature5', |
1670 | 0x25000127 => 'xsaveaddfeature6', |
1777 | 0x25000127 => 'xsaveaddfeature6', |
1671 | 0x25000128 => 'xsaveaddfeature7', |
1778 | 0x25000128 => 'xsaveaddfeature7', |
1672 | 0x25000129 => 'xsaveremovefeature', |
1779 | 0x25000129 => 'xsaveremovefeature', |
1673 | 0x2500012a => 'xsaveprocessorsmask', |
1780 | 0x2500012a => 'xsaveprocessorsmask', |
1674 | 0x2500012b => 'xsavedisable', |
1781 | 0x2500012b => 'xsavedisable', |
1675 | 0x2500012c => 'kerneldebugtype', |
1782 | 0x2500012c => 'kerneldebugtype', |
1676 | 0x2200012d => 'kernelbusparams', |
1783 | 0x2200012d => 'kernelbusparams', |
1677 | 0x2500012e => 'kerneldebugaddress', |
1784 | 0x2500012e => 'kerneldebugaddress', |
1678 | 0x2500012f => 'kerneldebugport', |
1785 | 0x2500012f => 'kerneldebugport', |
1679 | 0x25000130 => 'claimedtpmcounter', |
1786 | 0x25000130 => 'claimedtpmcounter', |
1680 | 0x25000131 => 'kernelchannel', |
1787 | 0x25000131 => 'kernelchannel', |
1681 | 0x22000132 => 'kerneltargetname', |
1788 | 0x22000132 => 'kerneltargetname', |
1682 | 0x25000133 => 'kernelhostip', |
1789 | 0x25000133 => 'kernelhostip', |
1683 | 0x25000134 => 'kernelport', |
1790 | 0x25000134 => 'kernelport', |
1684 | 0x26000135 => 'kerneldhcp', |
1791 | 0x26000135 => 'kerneldhcp', |
1685 | 0x22000136 => 'kernelkey', |
1792 | 0x22000136 => 'kernelkey', |
1686 | 0x22000137 => 'imchivename', |
1793 | 0x22000137 => 'imchivename', |
1687 | 0x21000138 => 'imcdevice', |
1794 | 0x21000138 => 'imcdevice', |
1688 | 0x25000139 => 'kernelbaudrate', |
1795 | 0x25000139 => 'kernelbaudrate', |
1689 | 0x22000140 => 'mfgmode', |
1796 | 0x22000140 => 'mfgmode', |
1690 | 0x26000141 => 'event', |
1797 | 0x26000141 => 'event', |
1691 | 0x25000142 => 'vsmlaunchtype', |
1798 | 0x25000142 => 'vsmlaunchtype', |
1692 | 0x25000144 => 'hypervisorenforcedcodeintegrity', |
1799 | 0x25000144 => 'hypervisorenforcedcodeintegrity', |
1693 | 0x21000150 => 'systemdatadevice', |
1800 | 0x21000150 => 'systemdatadevice', |
1694 | 0x21000151 => 'osarcdevice', |
1801 | 0x21000151 => 'osarcdevice', |
1695 | 0x21000153 => 'osdatadevice', |
1802 | 0x21000153 => 'osdatadevice', |
1696 | 0x21000154 => 'bspdevice', |
1803 | 0x21000154 => 'bspdevice', |
1697 | 0x21000155 => 'bspfilepath', |
1804 | 0x21000155 => 'bspfilepath', |
1698 | }, |
1805 | }, |
1699 | resume => { |
1806 | resume => { |
1700 | 0x21000001 => 'filedevice', |
1807 | 0x21000001 => 'filedevice', |
1701 | 0x22000002 => 'filepath', |
1808 | 0x22000002 => 'filepath', |
1702 | 0x26000003 => 'customsettings', |
1809 | 0x26000003 => 'customsettings', |
1703 | 0x26000004 => 'pae', |
1810 | 0x26000004 => 'pae', |
1704 | 0x21000005 => 'associatedosdevice', |
1811 | 0x21000005 => 'associatedosdevice', |
1705 | 0x26000006 => 'debugoptionenabled', |
1812 | 0x26000006 => 'debugoptionenabled', |
1706 | 0x25000007 => 'bootux', |
1813 | 0x25000007 => 'bootux', |
1707 | 0x25000008 => 'bootmenupolicy', |
1814 | 0x25000008 => 'bootmenupolicy', |
1708 | 0x26000024 => 'hormenabled', |
1815 | 0x26000024 => 'hormenabled', |
1709 | }, |
1816 | }, |
1710 | startup => { |
1817 | startup => { |
1711 | 0x26000001 => 'pxesoftreboot', |
1818 | 0x26000001 => 'pxesoftreboot', |
1712 | 0x22000002 => 'applicationname', |
1819 | 0x22000002 => 'applicationname', |
1713 | }, |
1820 | }, |
1714 | ); |
1821 | ); |
1715 | |
1822 | |
1716 | # mask, value => class |
1823 | # mask, value => class |
1717 | our @bcde_typeclass = ( |
1824 | our @bcde_typeclass = ( |
… | |
… | |
1781 | our @part_type = qw(gpt mbr raw); |
1888 | our @part_type = qw(gpt mbr raw); |
1782 | |
1889 | |
1783 | our $NULL_DEVICE = "\x00" x 16; |
1890 | our $NULL_DEVICE = "\x00" x 16; |
1784 | |
1891 | |
1785 | # biggest bitch to decode, ever |
1892 | # biggest bitch to decode, ever |
1786 | # this decoded a device portion after the GUID |
1893 | # this decodes a device portion after the GUID |
1787 | sub dec_device_($$); |
1894 | sub dec_device_($$); |
1788 | sub dec_device_($$) { |
1895 | sub dec_device_($$) { |
1789 | my ($device, $type) = @_; |
1896 | my ($device, $type) = @_; |
1790 | |
1897 | |
1791 | my $res; |
1898 | my $res; |
… | |
… | |
2198 | or die "$_: malformed or missing vmbus interface instance guid\n"; |
2305 | or die "$_: malformed or missing vmbus interface instance guid\n"; |
2199 | my $instance = enc_guid $1; |
2306 | my $instance = enc_guid $1; |
2200 | |
2307 | |
2201 | $payload = pack "a16a16x24", $type, $instance; |
2308 | $payload = pack "a16a16x24", $type, $instance; |
2202 | |
2309 | |
|
|
2310 | # } elsif ($type eq "udp") { |
|
|
2311 | # $payload = pack "Va16", 1, "12345678"; |
|
|
2312 | |
2203 | } else { |
2313 | } else { |
2204 | die "$type: not a supported device type (binary, null, boot, legacypartition, partition, block, locate)\n"; |
2314 | die "$type: not a supported device type (binary, null, boot, legacypartition, partition, block, locate)\n"; |
2205 | } |
2315 | } |
2206 | |
2316 | |
2207 | return ( |
2317 | return ( |
… | |
… | |
2372 | |
2482 | |
2373 | $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object; |
2483 | $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object; |
2374 | |
2484 | |
2375 | $bcd->{$object}{$elem} = $value; |
2485 | $bcd->{$object}{$elem} = $value; |
2376 | |
2486 | |
|
|
2487 | } elsif ($insn eq "del") { |
|
|
2488 | my $object = shift @insns; |
|
|
2489 | my $elem = shift @insns; |
|
|
2490 | |
|
|
2491 | $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object; |
|
|
2492 | |
|
|
2493 | delete $bcd->{$object}{$elem}; |
|
|
2494 | |
2377 | } elsif ($insn eq "eval") { |
2495 | } elsif ($insn eq "eval") { |
2378 | my $perl = shift @insns; |
2496 | my $perl = shift @insns; |
2379 | bcd_edit_eval "#line 1 'eval'\n$perl"; |
2497 | bcd_edit_eval "#line 1 'eval'\n$perl"; |
2380 | |
2498 | |
2381 | } elsif ($insn eq "do") { |
2499 | } elsif ($insn eq "do") { |
2382 | my $path = shift @insns; |
2500 | my $path = shift @insns; |
2383 | my $file = file_load $path; |
2501 | my $file = file_load $path; |
2384 | bcd_edit_eval "#line 1 '$path'\n$file"; |
2502 | bcd_edit_eval "#line 1 '$path'\n$file"; |
2385 | |
2503 | |
2386 | } else { |
2504 | } else { |
2387 | die "$insn: not a recognized instruction for edit/parse\n"; |
2505 | die "$insn: not a recognized instruction for create/edit/parse\n"; |
2388 | } |
2506 | } |
2389 | } |
2507 | } |
2390 | |
2508 | |
2391 | } |
2509 | } |
2392 | |
2510 | |
2393 | ############################################################################# |
2511 | ############################################################################# |
2394 | # command line parser |
2512 | # other utilities |
2395 | |
2513 | |
2396 | # json to stdout |
2514 | # json to stdout |
2397 | sub prjson($) { |
2515 | sub prjson($) { |
2398 | print $json_coder->encode ($_[0]); |
2516 | print $json_coder->encode ($_[0]); |
2399 | } |
2517 | } |
… | |
… | |
2403 | my $json; |
2521 | my $json; |
2404 | 1 while read STDIN, $json, 65536, length $json; |
2522 | 1 while read STDIN, $json, 65536, length $json; |
2405 | $json_coder->decode ($json) |
2523 | $json_coder->decode ($json) |
2406 | } |
2524 | } |
2407 | |
2525 | |
2408 | # all subcommands |
2526 | sub lsblk() { |
|
|
2527 | my $lsblk = $json_coder->decode (scalar qx<lsblk --json -o PATH,KNAME,MAJ:MIN,TYPE,PTTYPE,PTUUID,PARTUUID,LABEL,FSTYPE>); |
|
|
2528 | |
|
|
2529 | for my $dev (@{ $lsblk->{blockdevices} }) { |
|
|
2530 | if ($dev->{type} eq "part") { |
|
|
2531 | |
|
|
2532 | # lsblk sometimes gives a bogus pttype, so we recreate it here |
|
|
2533 | $dev->{pttype} = $dev->{ptuuid} =~ /^$RE_GUID\z/ |
|
|
2534 | ? "gpt" : "dos"; |
|
|
2535 | |
|
|
2536 | if ($dev->{pttype} eq "gpt") { |
|
|
2537 | $dev->{bcd_device} = "partition=<null>,harddisk,gpt,$dev->{ptuuid},$dev->{partuuid}"; |
|
|
2538 | } elsif ($dev->{pttype} eq "dos") { # why not "mbr" :( |
|
|
2539 | if ($dev->{partuuid} =~ /^([0-9a-f]{8})-([0-9a-f]{2})\z/i) { |
|
|
2540 | my ($diskid, $partno) = ($1, hex $2); |
|
|
2541 | $dev->{bcd_legacy_device} = "legacypartition=<null>,harddisk,mbr,$diskid,$partno"; |
|
|
2542 | if (open my $fh, "/sys/class/block/$dev->{kname}/start") { |
|
|
2543 | my $start = 512 * readline $fh; |
|
|
2544 | $dev->{bcd_device} = "partition=<null>,harddisk,mbr,$diskid,$start"; |
|
|
2545 | } |
|
|
2546 | } |
|
|
2547 | } |
|
|
2548 | } |
|
|
2549 | } |
|
|
2550 | |
|
|
2551 | $lsblk->{blockdevices} |
|
|
2552 | } |
|
|
2553 | |
|
|
2554 | sub prdev($$) { |
|
|
2555 | my ($path, $attribute) = @_; |
|
|
2556 | |
|
|
2557 | # rather than stat'ing and guessing how devices are encoded, we use lsblk for this |
|
|
2558 | my $mm = $json_coder->decode (scalar qx<lsblk -d -o MAJ:MIN -J \Q$path\E>)->{blockdevices}[0]{"maj:min"}; |
|
|
2559 | |
|
|
2560 | my $lsblk = lsblk; |
|
|
2561 | |
|
|
2562 | for my $dev (@$lsblk) { |
|
|
2563 | if ($dev->{"maj:min"} eq $mm && $dev->{$attribute}) { |
|
|
2564 | say $dev->{$attribute}; |
|
|
2565 | exit 0; |
|
|
2566 | } |
|
|
2567 | } |
|
|
2568 | |
|
|
2569 | exit 1; |
|
|
2570 | } |
|
|
2571 | |
|
|
2572 | ############################################################################# |
|
|
2573 | # command line parser |
|
|
2574 | |
2409 | our %CMD = ( |
2575 | our %CMD = ( |
2410 | help => sub { |
2576 | help => sub { |
2411 | require Pod::Usage; |
2577 | require Pod::Usage; |
2412 | Pod::Usage::pod2usage (-verbose => 2); |
2578 | Pod::Usage::pod2usage (-verbose => 2, -quotes => "none", -noperldoc => 1); |
2413 | }, |
2579 | }, |
2414 | |
2580 | |
2415 | objects => sub { |
2581 | objects => sub { |
2416 | my %rbcd_types = reverse %bcd_types; |
2582 | my %rbcd_types = reverse %bcd_types; |
2417 | $_ = sprintf "%08x", $_ for values %rbcd_types; |
2583 | $_ = sprintf "%08x", $_ for values %rbcd_types; |
… | |
… | |
2464 | BCDE_FORMAT_INTEGER , "integer", |
2630 | BCDE_FORMAT_INTEGER , "integer", |
2465 | BCDE_FORMAT_BOOLEAN , "boolean", |
2631 | BCDE_FORMAT_BOOLEAN , "boolean", |
2466 | BCDE_FORMAT_INTEGER_LIST, "integer list", |
2632 | BCDE_FORMAT_INTEGER_LIST, "integer list", |
2467 | ); |
2633 | ); |
2468 | |
2634 | |
2469 | my %element; |
2635 | my @element; |
2470 | |
2636 | |
2471 | for my $class (sort keys %rbcde_byclass) { |
2637 | for my $class (sort keys %rbcde_byclass) { |
2472 | my $rbcde = $rbcde_byclass{$class}; |
2638 | my $rbcde = $rbcde_byclass{$class}; |
2473 | |
2639 | |
2474 | unless ($json) { |
2640 | unless ($json) { |
… | |
… | |
2477 | printf "%-9s %-12s %s\n", "Element", "Format", "Name Alias"; |
2643 | printf "%-9s %-12s %s\n", "Element", "Format", "Name Alias"; |
2478 | } |
2644 | } |
2479 | for my $name (sort keys %$rbcde) { |
2645 | for my $name (sort keys %$rbcde) { |
2480 | my $id = $rbcde->{$name}; |
2646 | my $id = $rbcde->{$name}; |
2481 | my $format = $format_name{$id & BCDE_FORMAT}; |
2647 | my $format = $format_name{$id & BCDE_FORMAT}; |
2482 | $id = sprintf "%08x", $id; |
|
|
2483 | |
2648 | |
2484 | if ($json) { |
2649 | if ($json) { |
2485 | $element{$id} = [$class, $format, $name]; |
2650 | push @element, [$class, $id * 1, $format, $name]; |
2486 | } else { |
2651 | } else { |
|
|
2652 | $id = sprintf "%08x", $id; |
2487 | printf "%-9s %-12s %s\n", $id, $format, $name; |
2653 | printf "%-9s %-12s %s\n", $id, $format, $name; |
2488 | } |
2654 | } |
2489 | } |
2655 | } |
2490 | } |
2656 | } |
2491 | print "\n" unless $json; |
2657 | print "\n" unless $json; |
2492 | |
2658 | |
2493 | prjson { |
2659 | prjson { |
2494 | version => $JSON_VERSION, |
2660 | version => $JSON_VERSION, |
2495 | element => \%element, |
2661 | element => \@element, |
2496 | class => \@bcde_typeclass, |
2662 | class => \@bcde_typeclass, |
2497 | } if $json; |
2663 | } if $json; |
2498 | |
2664 | |
2499 | }, |
2665 | }, |
2500 | |
2666 | |
… | |
… | |
2504 | |
2670 | |
2505 | import => sub { |
2671 | import => sub { |
2506 | regf_save shift, bcd_encode rdjson; |
2672 | regf_save shift, bcd_encode rdjson; |
2507 | }, |
2673 | }, |
2508 | |
2674 | |
|
|
2675 | create => sub { |
|
|
2676 | my $path = shift; |
|
|
2677 | my $stat = stat_get $path; # should actually be done at file load time |
|
|
2678 | my $bcd = { }; |
|
|
2679 | bcd_edit $path, $bcd, @_; |
|
|
2680 | regf_save $path, bcd_encode $bcd; |
|
|
2681 | stat_set $path, $stat; |
|
|
2682 | }, |
|
|
2683 | |
2509 | edit => sub { |
2684 | edit => sub { |
2510 | my $path = shift; |
2685 | my $path = shift; |
|
|
2686 | my $stat = stat_get $path; # should actually be done at file load time |
2511 | my $bcd = bcd_decode regf_load $path; |
2687 | my $bcd = bcd_decode regf_load $path; |
2512 | bcd_edit $path, $bcd, @_; |
2688 | bcd_edit $path, $bcd, @_; |
2513 | regf_save $path, bcd_encode $bcd; |
2689 | regf_save $path, bcd_encode $bcd; |
|
|
2690 | stat_set $path, $stat; |
2514 | }, |
2691 | }, |
2515 | |
2692 | |
2516 | parse => sub { |
2693 | parse => sub { |
2517 | my $path = shift; |
2694 | my $path = shift; |
2518 | my $bcd = bcd_decode regf_load $path; |
2695 | my $bcd = bcd_decode regf_load $path; |
… | |
… | |
2527 | "import-regf" => sub { |
2704 | "import-regf" => sub { |
2528 | regf_save shift, rdjson; |
2705 | regf_save shift, rdjson; |
2529 | }, |
2706 | }, |
2530 | |
2707 | |
2531 | lsblk => sub { |
2708 | lsblk => sub { |
|
|
2709 | my $json = $_[0] eq "--json"; |
|
|
2710 | |
|
|
2711 | my $lsblk = lsblk; |
|
|
2712 | |
|
|
2713 | if ($json) { |
|
|
2714 | prjson $lsblk; |
|
|
2715 | } else { |
2532 | printf "%-10s %-8.8s %-6.6s %-3s %s\n", "DEVICE", "LABEL", "FSTYPE", "PT", "DEVICE DESCRIPTOR"; |
2716 | printf "%-10s %-8.8s %-6.6s %-3s %s\n", "DEVICE", "LABEL", "FSTYPE", "PT", "DEVICE DESCRIPTOR"; |
2533 | |
2717 | for my $dev (@$lsblk) { |
2534 | my $lsblk = $json_coder->decode (scalar qx<lsblk --json -o PATH,KNAME,TYPE,PTTYPE,PTUUID,PARTUUID,LABEL,FSTYPE>); |
2718 | for my $bcd ($dev->{bcd_device}, $dev->{bcd_legacy_device}) { |
2535 | |
|
|
2536 | for my $dev (@{ $lsblk->{blockdevices} }) { |
|
|
2537 | my $pr = sub { |
|
|
2538 | printf "%-10s %-8.8s %-6.6s %-3s %s\n", |
2719 | printf "%-10s %-8.8s %-6.6s %-3s %s\n", |
2539 | $dev->{path}, $dev->{label}, $dev->{fstype}, $dev->{pttype}, $_[0]; |
2720 | $dev->{path}, $dev->{label}, $dev->{fstype}, $dev->{pttype}, $bcd |
2540 | }; |
|
|
2541 | |
|
|
2542 | if ($dev->{type} eq "part") { |
|
|
2543 | if ($dev->{pttype} eq "gpt") { |
|
|
2544 | $pr->("partition=<null>,harddisk,gpt,$dev->{ptuuid},$dev->{partuuid}"); |
|
|
2545 | } elsif ($dev->{pttype} eq "dos") { # why not "mbr" :( |
|
|
2546 | if ($dev->{partuuid} =~ /^([0-9a-f]{8})-([0-9a-f]{2})\z/i) { |
|
|
2547 | my ($diskid, $partno) = ($1, hex $2); |
|
|
2548 | $pr->("legacypartition=<null>,harddisk,mbr,$diskid,$partno"); |
|
|
2549 | if (open my $fh, "/sys/class/block/$dev->{kname}/start") { |
|
|
2550 | my $start = 512 * readline $fh; |
|
|
2551 | $pr->("partition=<null>,harddisk,mbr,$diskid,$start"); |
|
|
2552 | } |
2721 | if $bcd; |
2553 | } |
|
|
2554 | } |
2722 | } |
2555 | } |
2723 | } |
2556 | } |
2724 | } |
|
|
2725 | }, |
|
|
2726 | |
|
|
2727 | "bcd-device" => sub { |
|
|
2728 | prdev shift, "bcd_device"; |
|
|
2729 | }, |
|
|
2730 | |
|
|
2731 | "bcd-legacy-device" => sub { |
|
|
2732 | prdev shift, "bcd_legacy_device"; |
2557 | }, |
2733 | }, |
2558 | |
2734 | |
2559 | version => sub { |
2735 | version => sub { |
2560 | print "\n", |
2736 | print "\n", |
2561 | "PBCDEDIT version $VERSION, copyright 2019 Marc A. Lehmann <pbcdedit\@schmorp.de>.\n", |
2737 | "PBCDEDIT version $VERSION, copyright 2019 Marc A. Lehmann <pbcdedit\@schmorp.de>.\n", |