… | |
… | |
627 | This concludes the syntax overview for device elements, but probably |
627 | This concludes the syntax overview for device elements, but probably |
628 | leaves many questions open. I can't help with most of them, as I also ave |
628 | leaves many questions open. I can't help with most of them, as I also ave |
629 | many questions, but I can walk you through some actual examples using more |
629 | many questions, but I can walk you through some actual examples using more |
630 | complex aspects. |
630 | complex aspects. |
631 | |
631 | |
632 | =item locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path |
632 | =item C<< locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path >> |
633 | |
633 | |
634 | Just like with C declarations, you best treat device descriptors as |
634 | Just like with C declarations, you best treat device descriptors as |
635 | instructions to find your device and work your way from the inside out: |
635 | instructions to find your device and work your way from the inside out: |
636 | |
636 | |
637 | locate=<null>,path,\disk.vhdx |
637 | locate=<null>,path,\disk.vhdx |
638 | |
638 | |
639 | First, the innermost device descriptor searches all partitions on the |
639 | First, the innermost device descriptor searches all partitions on the |
640 | system for a file called F<\disk.vhdx>: |
640 | system for a file called F<\disk.vhdx>: |
641 | |
641 | |
642 | block=file,<see above>,\disk.vhdx |
642 | block=file,<I<see above>>,\disk.vhdx |
643 | |
643 | |
644 | Next, this takes the device locate has found and finds a file called |
644 | Next, this takes the device locate has found and finds a file called |
645 | F<\disk.vhdx> on it. This is the same file locate was using, but that is |
645 | F<\disk.vhdx> on it. This is the same file locate was using, but that is |
646 | only because we find the device using the same path as finding the disk |
646 | only because we find the device using the same path as finding the disk |
647 | image, so this is purely incidental, although quite common. |
647 | image, so this is purely incidental, although quite common. |
648 | |
648 | |
649 | Bext, this file will be opened as a virtual disk: |
649 | Next, this file will be opened as a virtual disk: |
650 | |
650 | |
651 | block=vhd,<see above> |
651 | block=vhd,<I<see above>> |
652 | |
652 | |
653 | And finally, inside this disk, another C<locate> will look for a partition |
653 | And finally, inside this disk, another C<locate> will look for a partition |
654 | with a path as specified in the C<path> element, which most likely will be |
654 | with a path as specified in the C<path> element, which most likely will be |
655 | F<\Windows\system32\winload.exe>: |
655 | F<\Windows\system32\winload.exe>: |
656 | |
656 | |
657 | locate=<see above>,element,path |
657 | locate=<I<see above>>,element,path |
658 | |
658 | |
659 | As a result, this will boot the first Windows it finds on the first |
659 | As a result, this will boot the first Windows it finds on the first |
660 | F<disk.vhdx> disk image it can find anywhere. |
660 | F<disk.vhdx> disk image it can find anywhere. |
661 | |
661 | |
662 | =item locate=<block=vhd,<block=file,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,\win10.vhdx>>,element,path |
662 | =item C<< locate=<block=vhd,<block=file,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,\win10.vhdx>>,element,path >> |
663 | |
663 | |
664 | Pretty much the same as the previous case, but witzh a bit of variance. First, look for a specific partition on |
664 | Pretty much the same as the previous case, but with a bit of |
665 | an MBR-partitioned disk: |
665 | variance. First, look for a specific partition on an MBR-partitioned disk: |
666 | |
666 | |
667 | partition=<null>,harddisk,mbr,47cbc08a,242643632128 |
667 | partition=<null>,harddisk,mbr,47cbc08a,242643632128 |
668 | |
668 | |
669 | Then open the file F<\win10.vhdx> on that partition: |
669 | Then open the file F<\win10.vhdx> on that partition: |
670 | |
670 | |
671 | block=file,<see above>,\win10.vhdx |
671 | block=file,<I<see above>>,\win10.vhdx |
672 | |
672 | |
673 | Then, again, the file is opened as a virtual disk image: |
673 | Then, again, the file is opened as a virtual disk image: |
674 | |
674 | |
675 | block=vhd,<see above> |
675 | block=vhd,<I<see above>> |
676 | |
676 | |
677 | And again the windows loader (or whatever is in C<path>) will be searched: |
677 | And again the windows loader (or whatever is in C<path>) will be searched: |
678 | |
678 | |
679 | locate=<see above>,element,path |
679 | locate=<I<see above>>,element,path |
680 | |
680 | |
681 | =item {b097d2b2-bc00-11e9-8a9a-525400123456}block<1>=ramdisk,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,0,0,0,\boot.wim |
681 | =item C<< {b097d2b2-bc00-11e9-8a9a-525400123456}block<1>=ramdisk,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,0,0,0,\boot.wim >> |
682 | |
682 | |
683 | This is quite different. First, it starts with a GUID. This GUID belongs |
683 | This is quite different. First, it starts with a GUID. This GUID belongs |
684 | to a BCD object of type C<device>, which has additional parameters: |
684 | to a BCD object of type C<device>, which has additional parameters: |
685 | |
685 | |
686 | "{b097d2b2-bc00-11e9-8a9a-525400123456}" : { |
686 | "{b097d2b2-bc00-11e9-8a9a-525400123456}" : { |
… | |
… | |
689 | "ramdisksdidevice" : "partition=<null>,harddisk,mbr,47cbc08a,1048576", |
689 | "ramdisksdidevice" : "partition=<null>,harddisk,mbr,47cbc08a,1048576", |
690 | "ramdisksdipath" : "\boot.sdi" |
690 | "ramdisksdipath" : "\boot.sdi" |
691 | }, |
691 | }, |
692 | |
692 | |
693 | I will not go into many details, but this specifies a (presumably empty) |
693 | I will not go into many details, but this specifies a (presumably empty) |
694 | template ramdisk image (F<\boot.sdi>) that is used to initiaolize the |
694 | template ramdisk image (F<\boot.sdi>) that is used to initialize the |
695 | ramdisk. The F<\boot.wim> file is then extracted into it. As you cna also |
695 | ramdisk. The F<\boot.wim> file is then extracted into it. As you can also |
696 | see, this F<.sdi> file resides on a different C<partition>. |
696 | see, this F<.sdi> file resides on a different C<partition>. |
697 | |
697 | |
698 | Continuitn, as always, form the inside out, first this device descriptor |
698 | Continuing, as always, from the inside out, first this device descriptor |
699 | finds a specific partition: |
699 | finds a specific partition: |
700 | |
700 | |
701 | partition=<null>,harddisk,mbr,47cbc08a,242643632128 |
701 | partition=<null>,harddisk,mbr,47cbc08a,242643632128 |
702 | |
702 | |
703 | And then specifies a C<ramdisk> image on this partition: |
703 | And then specifies a C<ramdisk> image on this partition: |
704 | |
704 | |
705 | block<1>=ramdisk,<see above>,0,0,0,\boot.wim |
705 | block<1>=ramdisk,<I<see above>>,0,0,0,\boot.wim |
706 | |
706 | |
707 | I don't know what the purpose of the C<< <1> >> flag value is, but it |
707 | I don't know what the purpose of the C<< <1> >> flag value is, but it |
708 | seems to be always there on this kind of entry. |
708 | seems to be always there on this kind of entry. |
709 | |
709 | |
710 | If you have some good examples to add here, feel free to mail me. |
710 | If you have some good examples to add here, feel free to mail me. |
711 | |
711 | |
712 | |
712 | |
713 | =head1 EDITING BCD DATA STORES |
713 | =head1 EDITING BCD DATA STORES |
714 | |
714 | |
715 | The C<edit> and C<parse> subcommands allow you to read a BCD data store |
715 | The C<edit> and C<parse> subcommands allow you to read a BCD data store |
716 | and modify it or extract data from it. This is done by exyecuting a series |
716 | and modify it or extract data from it. This is done by executing a series |
717 | of "editing instructions" which are explained here. |
717 | of "editing instructions" which are explained here. |
718 | |
718 | |
719 | =over |
719 | =over |
720 | |
720 | |
721 | =item get I<object> I<element> |
721 | =item get I<object> I<element> |
… | |
… | |
731 | |
731 | |
732 | =item set I<object> I<element> I<value> |
732 | =item set I<object> I<element> I<value> |
733 | |
733 | |
734 | Similar to C<get>, but sets the element to the given I<value> instead. |
734 | Similar to C<get>, but sets the element to the given I<value> instead. |
735 | |
735 | |
736 | Example: change bootmgr default too |
736 | Example: change the bootmgr default too |
737 | C<{b097d2ad-bc00-11e9-8a9a-525400123456}>: |
737 | C<{b097d2ad-bc00-11e9-8a9a-525400123456}>: |
738 | |
738 | |
739 | pbcdedit edit BCD set "{bootmgr}" resumeobject "{b097d2ad-bc00-11e9-8a9a-525400123456}" |
739 | pbcdedit edit BCD set "{bootmgr}" resumeobject "{b097d2ad-bc00-11e9-8a9a-525400123456}" |
740 | |
740 | |
741 | =item eval I<perlcode> |
741 | =item eval I<perlcode> |
… | |
… | |
765 | The example given for C<get>, above, could be expressed like this with |
765 | The example given for C<get>, above, could be expressed like this with |
766 | C<eval>: |
766 | C<eval>: |
767 | |
767 | |
768 | pbcdedit edit BCD eval 'say $BCD->{$DEFAULT}{description}' |
768 | pbcdedit edit BCD eval 'say $BCD->{$DEFAULT}{description}' |
769 | |
769 | |
770 | The example given for C<set> could be expresed like this: |
770 | The example given for C<set> could be expressed like this: |
771 | |
771 | |
772 | pbcdedit edit BCD eval '$BCD->{$DEFAULT}{resumeobject} = "{b097d2ad-bc00-11e9-8a9a-525400123456}"' |
772 | pbcdedit edit BCD eval '$BCD->{$DEFAULT}{resumeobject} = "{b097d2ad-bc00-11e9-8a9a-525400123456}"' |
773 | |
773 | |
774 | =item do I<path> |
774 | =item do I<path> |
775 | |
775 | |
… | |
… | |
802 | Registry code should preserve classname and security descriptor data, and |
802 | Registry code should preserve classname and security descriptor data, and |
803 | whatever else is necessary to read and write any registry hive file. |
803 | whatever else is necessary to read and write any registry hive file. |
804 | |
804 | |
805 | I am also not happy with device descriptors being strings rather than a |
805 | I am also not happy with device descriptors being strings rather than a |
806 | data structure, but strings are probably better for command line usage. In |
806 | data structure, but strings are probably better for command line usage. In |
807 | any case,. device descriptors could be converted by simply "splitting" at |
807 | any case, device descriptors could be converted by simply "splitting" at |
808 | "=" and "," into an array reference, recursively. |
808 | "=" and "," into an array reference, recursively. |
809 | |
809 | |
810 | =head1 HOMEPAGE |
810 | =head1 HOMEPAGE |
811 | |
811 | |
812 | Original versions of this program can be found at |
812 | Original versions of this program can be found at |
… | |
… | |
2270 | |
2270 | |
2271 | if ($insn eq "get") { |
2271 | if ($insn eq "get") { |
2272 | my $object = shift @insns; |
2272 | my $object = shift @insns; |
2273 | my $elem = shift @insns; |
2273 | my $elem = shift @insns; |
2274 | |
2274 | |
2275 | $object = $default if $object eq "{default}"; |
2275 | $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object; |
2276 | |
2276 | |
2277 | print $bcd->{$object}{$elem}, "\n"; |
2277 | print $bcd->{$object}{$elem}, "\n"; |
2278 | |
2278 | |
2279 | } elsif ($insn eq "set") { |
2279 | } elsif ($insn eq "set") { |
2280 | my $object = shift @insns; |
2280 | my $object = shift @insns; |
2281 | my $elem = shift @insns; |
2281 | my $elem = shift @insns; |
2282 | my $value = shift @insns; |
2282 | my $value = shift @insns; |
2283 | |
2283 | |
2284 | $object = $default if $object eq "{default}"; |
2284 | $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object; |
2285 | |
2285 | |
2286 | $bcd->{$object}{$elem} = $value; |
2286 | $bcd->{$object}{$elem} = $value; |
2287 | |
2287 | |
2288 | } elsif ($insn eq "eval") { |
2288 | } elsif ($insn eq "eval") { |
2289 | bcd_edit_eval shift @insns; |
2289 | bcd_edit_eval shift @insns; |