ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/pbcdedit/pbcdedit
(Generate patch)

Comparing pbcdedit/pbcdedit (file contents):
Revision 1.9 by root, Wed Aug 14 22:54:28 2019 UTC vs.
Revision 1.34 by root, Thu Aug 15 08:42:02 2019 UTC

17# 17#
18# You should have received a copy of the GNU General Public License 18# You should have received a copy of the GNU General Public License
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
22use 5.014; # numerous features needed 22use 5.016; # numerous features need 5.14, __SUB__ needs 5.16
23 23
24our $VERSION = '1.0'; 24our $VERSION = '1.0';
25our $JSON_VERSION = 1; # the versiobn of the json objects generated by this program 25our $JSON_VERSION = 1; # the versiobn of the json objects generated by this program
26 26
27=head1 NAME 27=head1 NAME
29 pbcdedit - portable boot configuration data (BCD) store editor 29 pbcdedit - portable boot configuration data (BCD) store editor
30 30
31=head1 SYNOPSIS 31=head1 SYNOPSIS
32 32
33 pbcdedit help # output manual page 33 pbcdedit help # output manual page
34
34 pbcdedit export path/to/BCD # output BCD hive as JSON 35 pbcdedit export path/to/BCD # output BCD hive as JSON
35 pbcdedit import path/to/bcd # convert standard input to BCD hive 36 pbcdedit import path/to/BCD # convert standard input to BCD hive
36 pbcdedit edit path/to/BCD edit-instructions... 37 pbcdedit edit path/to/BCD edit-instructions...
37 38
38 pbcdedit objects # list all supported object aliases and types 39 pbcdedit objects # list all supported object aliases and types
39 pbcdedit elements # list all supported bcd element aliases 40 pbcdedit elements # list all supported bcd element aliases
40 41
58 59
59=item Does not rely on Windows 60=item Does not rely on Windows
60 61
61As the "portable" in the name implies, this program does not rely on 62As the "portable" in the name implies, this program does not rely on
62C<bcdedit> or other windows programs or libraries, it works on any system 63C<bcdedit> or other windows programs or libraries, it works on any system
63that supports at least perl version 5.14. 64that supports at least perl version 5.16.
64 65
65=item Decodes and encodes BCD device elements 66=item Decodes and encodes BCD device elements
66 67
67PBCDEDIT can concisely decode and encode BCD device element contents. This 68PBCDEDIT can concisely decode and encode BCD device element contents. This
68is pretty unique, and offers a lot of potential that can't be realised 69is pretty unique, and offers a lot of potential that can't be realised
75sensitive data. 76sensitive data.
76 77
77=back 78=back
78 79
79The target audience for this program is professionals and tinkerers who 80The target audience for this program is professionals and tinkerers who
80are rewady to invest time into learning how it works. It is not an easy 81are ready to invest time into learning how it works. It is not an easy
81program to use and requires patience and a good understanding of BCD data 82program to use and requires patience and a good understanding of BCD
82stores. 83stores.
83 84
84 85
85=head1 SUBCOMMANDS 86=head1 SUBCOMMANDS
86 87
87PCBEDIT expects a subcommand as first argument that tells it what to 88PBCDEDIT expects a subcommand as first argument that tells it what to
88do. The following subcommands exist: 89do. The following subcommands exist:
89 90
90=over 91=over
91 92
92=item help 93=item C<help>
93 94
94Displays the whole manuale page (this document). 95Displays the whole manual page (this document).
95 96
96=item export F<path> 97=item C<export> F<path>
97 98
98Reads a BCD data store and writes a JSON representation of it to standard 99Reads a BCD data store and writes a JSON representation of it to standard
99output. 100output.
100 101
101The format of the data is explained later in this document. 102The format of the data is explained later in this document.
102 103
103Example: read a BCD store, modify it wiht an extenral program, write it again. 104Example: read a BCD store, modify it with an external program, write it
105again.
104 106
105 pbcdedit export BCD | modify-json-somehow | pbcdedit import BCD 107 pbcdedit export BCD | modify-json-somehow | pbcdedit import BCD
106 108
107=item import F<path> 109=item C<import> F<path>
108 110
109The reverse of C<export>: Reads a JSON representation of a BCD data store 111The reverse of C<export>: Reads a JSON representation of a BCD data store
110from standard input, and creates or replaces the given BCD data store. 112from standard input, and creates or replaces the given BCD data store.
111 113
112=item edit F<path> instructions... 114=item C<edit> F<path> I<instructions...>
113 115
114Load a BCD data store, apply some instructions to it, and save it again. 116Load a BCD data store, apply some instructions to it, and save it again.
115 117
116See the section L<EDITING BCD DATA STORES>, below, for more info. 118See the section L<EDITING BCD STORES>, below, for more info.
117 119
118=item parse F<path> instructions... 120=item C<parse> F<path> I<instructions...>
119 121
120Same as C<edit>, above, except it doesn't save the data store again. Can 122Same as C<edit>, above, except it doesn't save the data store again. Can
121be useful to extract some data from it. 123be useful to extract some data from it.
122 124
123=item lsblk 125=item C<lsblk>
124 126
125On a GNU/Linux system, you can get a list of partition device descriptors 127On a GNU/Linux system, you can get a list of partition device descriptors
126using this command - the external C<lsblk> command is required, as well as 128using this command - the external C<lsblk> command is required, as well as
127a mounted C</sys> file system. 129a mounted C</sys> file system.
128 130
129The output will be a list of all partitions in the system and C<partition> 131The output will be a list of all partitions in the system and C<partition>
130descriptors for GPT and both C<legacypartition> and C<partition> 132descriptors for GPT and both C<legacypartition> and C<partition>
131descritpors for MBR partitions. 133descriptors for MBR partitions.
132 134
133=item objects [--json] 135=item C<objects> [C<--json>]
134 136
135Outputs two tables: a table listing all type aliases with their hex bcd 137Outputs two tables: a table listing all type aliases with their hex BCD
136element ID, and all object name aliases with their GUID and default type 138element ID, and all object name aliases with their GUID and default type
137(if any). 139(if any).
138 140
139With C<--json> it prints similar information as a JSON object, for easier parsing. 141With C<--json> it prints similar information as a JSON object, for easier parsing.
140 142
141=item elements [--json] 143=item C<elements> [C<--json>]
142 144
143Outputs a table of known element aliases with their hex ID and the format 145Outputs a table of known element aliases with their hex ID and the format
144type. 146type.
145 147
146With C<--json> it prints similar information as a JSON object, for easier parsing. 148With C<--json> it prints similar information as a JSON object, for easier parsing.
147 149
148=item export-regf F<path> 150=item C<export-regf> F<path>
149 151
150This has nothing to do with BCD data stores - it takes a registry hive 152This has nothing to do with BCD stores, but simply exposes PCBEDIT's
153internal registry hive reader - it takes a registry hive file as argument
151file as argument and outputs a JSON representation of it to standard 154and outputs a JSON representation of it to standard output.
152output.
153 155
154Hive versions 1.2 till 1.6 are supported. 156Hive versions 1.2 till 1.6 are supported.
155 157
156=item import-regf F<path> 158=item C<import-regf> F<path>
157 159
158The reverse of C<export-regf>: reads a JSON representation of a registry 160The reverse of C<export-regf>: reads a JSON representation of a registry
159hive from standard input and creates or replaces the registry hive file given as 161hive from standard input and creates or replaces the registry hive file
160argument. 162given as argument.
161 163
162The written hive will always be in a slightly modified version 1.3 164The written hive will always be in a slightly modified version 1.3
163format. It's not the format windows would generate, but it should be 165format. It's not the format windows would generate, but it should be
164understood by any conformant hive reader. 166understood by any conformant hive reader.
165 167
166Note that the representation chosen by PBCDEDIT currently throws away 168Note that the representation chosen by PBCDEDIT currently throws away
167clasname data (often used for feeble attemtps at hiding stuff by 169classname data (often used for feeble attempts at hiding stuff by
168Microsoft) and security descriptors, so if you write anything other than 170Microsoft) and security descriptors, so if you write anything other than
169a BCD hive you will most likely destroy it. 171a BCD hive you will most likely destroy it.
170 172
171=back 173=back
172 174
173 175
174=head1 BCD DATA STORE REPRESENTATION FORMAT 176=head1 BCD STORE REPRESENTATION FORMAT
175 177
176A BCD data store is represented as a JSON object with one special key, 178A BCD data store is represented as a JSON object with one special key,
177C<meta>, and one key per BCD object. That is, each BCD object becomes 179C<meta>, and one key per BCD object. That is, each BCD object becomes
178one key-value pair in the object, and an additional key called C<meta> 180one key-value pair in the object, and an additional key called C<meta>
179contains meta information. 181contains meta information.
242=head2 The C<meta> key 244=head2 The C<meta> key
243 245
244The C<meta> key is not stored in the BCD data store but is used only 246The C<meta> key is not stored in the BCD data store but is used only
245by PBCDEDIT. It is always generated when exporting, and importing will 247by PBCDEDIT. It is always generated when exporting, and importing will
246be refused when it exists and the version stored inside doesn't store 248be refused when it exists and the version stored inside doesn't store
247the JSON schema version of PBCDEDIT. This ensures that differemt and 249the JSON schema version of PBCDEDIT. This ensures that different and
248incompatible versions of PBCDEDIT will not read and misinterΓΌret each 250incompatible versions of PBCDEDIT will not read and misinterpret each
249others data. 251others data.
250 252
251=head2 The object keys 253=head2 The object keys
252 254
253Every other key is a BCD object. There is usually a BCD object for the 255Every other key is a BCD object. There is usually a BCD object for the
254boot manager, one for every boot option and a few others that store common 256boot manager, one for every boot option and a few others that store common
255settings inherited by these. 257settings inherited by these.
256 258
257Each BCD object is represented by a GUID wrapped in curly braces. These 259Each BCD object is represented by a GUID wrapped in curly braces. These
258are usually random GUIDs used only to distinguish bCD objects from each 260are usually random GUIDs used only to distinguish BCD objects from each
259other. When adding a new boot option, you can simply generate a new GUID. 261other. When adding a new boot option, you can simply generate a new GUID.
260 262
261Some of these GUIDs are fixed well known GUIDs which PBCDEDIT will decode 263Some of these GUIDs are fixed well known GUIDs which PBCDEDIT will decode
262into human-readable strings such as C<{globalsettings}>, which is the same 264into human-readable strings such as C<{globalsettings}>, which is the same
263as C<{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}>. 265as C<{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}>.
297get a list of all BCD elements known to PBCDEDIT by running F<pbcdedit 299get a list of all BCD elements known to PBCDEDIT by running F<pbcdedit
298elements>. 300elements>.
299 301
300What was said about duplicate keys mapping to the same object is true for 302What was said about duplicate keys mapping to the same object is true for
301elements as well, so, again, you should always use the canonical name, 303elements as well, so, again, you should always use the canonical name,
302whcih is the human radable alias, if known. 304which is the human readable alias, if known.
303 305
304=head3 BCD element types 306=head3 BCD element types
305 307
306Each BCD element has a type such as I<string> or I<boolean>. This type 308Each BCD element has a type such as I<string> or I<boolean>. This type
307determines how the value is interpreted, and most of them are pretty easy 309determines how the value is interpreted, and most of them are pretty easy
319 "description" : "Windows 10", 321 "description" : "Windows 10",
320 "systemroot" : "\\Windows", 322 "systemroot" : "\\Windows",
321 323
322=item boolean 324=item boolean
323 325
324Almost as simnple are booleans, which represent I<true>/I<false>, 326Almost as simple are booleans, which represent I<true>/I<false>,
325I<on>/I<off> and similar values. In the JSON form, true is represented 327I<on>/I<off> and similar values. In the JSON form, true is represented
326by the number C<1>, and false is represented by the number C<0>. Other 328by the number C<1>, and false is represented by the number C<0>. Other
327values will be accepted, but PBCDEDIT doesn't guarantee how these are 329values will be accepted, but PBCDEDIT doesn't guarantee how these are
328interpreted. 330interpreted.
329 331
335 337
336=item integer 338=item integer
337 339
338Again, very simple, this is a 64 bit integer. IT can be either specified 340Again, very simple, this is a 64 bit integer. IT can be either specified
339as a decimal number, as a hex number (by prefixing it with C<0x>) or as a 341as a decimal number, as a hex number (by prefixing it with C<0x>) or as a
340binatry number (prefix C<0b>). 342binary number (prefix C<0b>).
341 343
342For example, the boot C<timeout> is an integer, specifying the automatic 344For example, the boot C<timeout> is an integer, specifying the automatic
343boot delay in seconds: 345boot delay in seconds:
344 346
345 "timeout" : 30, 347 "timeout" : 30,
346 348
347=item integer list 349=item integer list
348 350
349This is a list of 64 bit integers separated by whitespace. It is not used 351This is a list of 64 bit integers separated by whitespace. It is not used
350much, so here is a somewhat artificial an untested exanmple of using 352much, so here is a somewhat artificial an untested example of using
351C<customactions> to specify a certain custom, eh, action to be executed 353C<customactions> to specify a certain custom, eh, action to be executed
352when pressing C<F10> at boot: 354when pressing C<F10> at boot:
353 355
354 "customactions" : "0x1000044000001 0x54000001", 356 "customactions" : "0x1000044000001 0x54000001",
355 357
356=item guid 358=item guid
357 359
358This represents a single GUID value wrqapped in curly braces. It is used a 360This represents a single GUID value wrapped in curly braces. It is used a
359lot to refer from one BCD object to other one. 361lot to refer from one BCD object to other one.
360 362
361For example, The C<{bootmgr}> object might refer to a resume boot option 363For example, The C<{bootmgr}> object might refer to a resume boot option
362using C<resumeobject>: 364using C<resumeobject>:
363 365
365 367
366Human readable aliases are used and allowed. 368Human readable aliases are used and allowed.
367 369
368=item guid list 370=item guid list
369 371
370Similar to te guid type, this represents a list of such GUIDs, separated 372Similar to the GUID type, this represents a list of such GUIDs, separated
371by whitespace from each other. 373by whitespace from each other.
372 374
373For example, many BCD objects can I<inherit> elements from other BCD 375For example, many BCD objects can I<inherit> elements from other BCD
374objects by specifying the GUIDs of those other objects ina GUID list 376objects by specifying the GUIDs of those other objects in a GUID list
375called surprisingly called C<inherit>: 377called surprisingly called C<inherit>:
376 378
377 "inherit" : "{dbgsettings} {emssettings} {badmemory}", 379 "inherit" : "{dbgsettings} {emssettings} {badmemory}",
378 380
379This example also shows how human readable aliases can be used. 381This example also shows how human readable aliases can be used.
388=back 390=back
389 391
390=head4 The BCD "device" element type 392=head4 The BCD "device" element type
391 393
392Device elements specify, well, devices. They are used for such diverse 394Device elements specify, well, devices. They are used for such diverse
393purposes such as finding a TFTP network boot imagem serial ports or VMBUS 395purposes such as finding a TFTP network boot image, serial ports or VMBUS
394devices, but most commonly they are used to specify the disk (harddisk, 396devices, but most commonly they are used to specify the disk (harddisk,
395cdrom ramdisk, vhd...) to boot from. 397cdrom, ramdisk, vhd...) to boot from.
396 398
397The device element is kind of a mini-language in its own which is much 399The device element is kind of a mini-language in its own which is much
398more versatile then the limited windows interface to it - BCDEDIT - 400more versatile then the limited windows interface to it - BCDEDIT -
399reveals. 401reveals.
400 402
403element, so almost everything known about it had to be researched first 405element, so almost everything known about it had to be researched first
404in the process of writing this script, and consequently, support for BCD 406in the process of writing this script, and consequently, support for BCD
405device elements is partial only. 407device elements is partial only.
406 408
407On the other hand, the expressive power of PBCDEDIT in specifying devices 409On the other hand, the expressive power of PBCDEDIT in specifying devices
408is much bigger than BCDEDIT and therefore more cna be don with it. The 410is much bigger than BCDEDIT and therefore more can be done with it. The
409downside is that BCD device elements are much more complicated than what 411downside is that BCD device elements are much more complicated than what
410you might think from reading the BCDEDIT documentation. 412you might think from reading the BCDEDIT documentation.
411 413
412In other words, simple things are complicated, and complicated things are 414In other words, simple things are complicated, and complicated things are
413possible. 415possible.
414 416
415Anyway, the general syntax of device elements is an optional GUID, 417Anyway, the general syntax of device elements is an optional GUID,
416followed by a device type, optionally followed by hexdecimal flags in 418followed by a device type, optionally followed by hexadecimal flags in
417angle brackets, optionally followed by C<=> and a comma-separated list of 419angle brackets, optionally followed by C<=> and a comma-separated list of
418arguments, some of which can be (and often are) in turn devices again. 420arguments, some of which can be (and often are) in turn devices again.
419 421
420 [{GUID}]type[<flags>][=arg,arg...] 422 [{GUID}]type[<flags>][=arg,arg...]
421 423
447The types understood and used by PBCDEDIT are as follows (keep in mind 449The types understood and used by PBCDEDIT are as follows (keep in mind
448that not of all the following is necessarily supported in PBCDEDIT): 450that not of all the following is necessarily supported in PBCDEDIT):
449 451
450=over 452=over
451 453
452=item binary=hex... 454=item C<binary=>I<hex...>
453 455
454This type isn't actually a real BCD element type, but a fallback for those 456This type isn't actually a real BCD element type, but a fallback for those
455cases where PBCDEDIT can't perfectly decode a device element (except for 457cases where PBCDEDIT can't perfectly decode a device element (except for
456the leading GUID, which it can always decode). In such cases, it will 458the leading GUID, which it can always decode). In such cases, it will
457convert the device into this type with a hexdump of the element data. 459convert the device into this type with a hexdump of the element data.
458 460
459=item null 461=item C<null>
460 462
461This is another special type - sometimes, a device all zero-filled, which 463This is another special type - sometimes, a device all zero-filled, which
462is not valid. This can mark the absence of a device or something PBCDEDIT 464is not valid. This can mark the absence of a device or something PBCDEDIT
463does not understand, so it decodes it into this special "all zero" type 465does not understand, so it decodes it into this special "all zero" type
464called C<null>. 466called C<null>.
465 467
466It's most commonly found in devices that can use an optional parent 468It's most commonly found in devices that can use an optional parent
467device, when no parent device is used. 469device, when no parent device is used.
468 470
469=item boot 471=item C<boot>
470 472
471Another type without parameters, this refers to the device that was booted 473Another type without parameters, this refers to the device that was booted
472from (nowadays typically the EFI system partition). 474from (nowadays typically the EFI system partition).
473 475
474=item vmbus=interfacetype,interfaceinstance 476=item C<vmbus=>I<interfacetype>,I<interfaceinstance>
475 477
476This specifies a VMBUS device with the given interface type and interface 478This specifies a VMBUS device with the given interface type and interface
477instance, both of which are "naked" (no curly braces) GUIDs. 479instance, both of which are "naked" (no curly braces) GUIDs.
478 480
479Made-up example (couldn't find a single example on the web): 481Made-up example (couldn't find a single example on the web):
480 482
481 vmbus=c376c1c3-d276-48d2-90a9-c04748072c60,12345678-a234-b234-c234-d2345678abcd 483 vmbus=c376c1c3-d276-48d2-90a9-c04748072c60,12345678-a234-b234-c234-d2345678abcd
482 484
483=item partition=<parent>,devicetype,partitiontype,diskid,partitionid 485=item C<partition=><I<parent>>,I<devicetype>,I<partitiontype>,I<diskid>,I<partitionid>
484 486
485This designates a specific partition on a block device. C<< <parent> 487This designates a specific partition on a block device. I<parent> is an
486>> is an optional parent device on which to search on, and is often 488optional parent device on which to search on, and is often C<null>. Note
487C<null>. Note that the anfgle brackets are part of the syntax. 489that the angle brackets around I<parent> are part of the syntax.
488 490
489C<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>, 491I<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>,
490C<file> or C<vhd>, where the first three should be self-explaining, 492C<file> or C<vhd>, where the first three should be self-explaining,
491C<file> is usually used to locate a device by finding a magic file, and 493C<file> is usually used to locate a file to be used as a disk image,
492C<vhd> is used for virtual harddisks - F<.vhd> and F<-vhdx> files. 494and C<vhd> is used to treat files as virtual harddisks, i.e. F<vhd> and
495F<vhdx> files.
493 496
494The C<partitiontype> is either C<mbr>, C<gpt> or C<raw>, the latter being 497The I<partitiontype> is either C<mbr>, C<gpt> or C<raw>, the latter being
495used for devices without partitions, such as cdroms, where the "partition" 498used for devices without partitions, such as cdroms, where the "partition"
496is usually the whole device. 499is usually the whole device.
497 500
498The C<diskid> identifies the disk or device using a unique signature, and 501The I<diskid> identifies the disk or device using a unique signature, and
499the same is true for the C<partitionid>. How these are interpreted depends 502the same is true for the I<partitionid>. How these are interpreted depends
500on the C<partitiontype>: 503on the I<partitiontype>:
501 504
502=over 505=over
503 506
504=item mbr 507=item C<mbr>
505 508
506The C<diskid> is the 32 bit disk signature stored at offset 0x1b8 in the 509The C<diskid> is the 32 bit disk signature stored at offset 0x1b8 in the
507MBR, interpreted as a 32 bit unsigned little endian integer and written as 510MBR, interpreted as a 32 bit unsigned little endian integer and written as
508hex number. That is, the bytes C<01 02 03 04> would become C<04030201>. 511hex number. That is, the bytes C<01 02 03 04> would become C<04030201>.
509 512
510Diskpart (using the C<DETAIL> command) and the C<lsblk> comamnd typically 513Diskpart (using the C<DETAIL> command) and the C<lsblk> command typically
511found on GNU/Linux systems (using e.g. C<lsblk -o NAME,PARTUUID>) can 514found on GNU/Linux systems (using e.g. C<lsblk -o NAME,PARTUUID>) can
512display the disk id. 515display the I<diskid>.
513 516
514The C<partitionid> is the byte offset(!) of the partition counting from 517The I<partitionid> is the byte offset(!) of the partition counting from
515the beginning of the MBR. 518the beginning of the MBR.
516 519
517Example, use the partition on the harddisk with C<diskid> C<47cbc08a> 520Example, use the partition on the harddisk with I<diskid> C<47cbc08a>
518starting at sector C<2048> (= 1048576 / 512). 521starting at sector C<2048> (= 1048576 / 512).
519 522
520 partition=<null>,harddisk,mbr,47cbc08a,1048576 523 partition=<null>,harddisk,mbr,47cbc08a,1048576
521 524
522=item gpt 525=item C<gpt>
523 526
524The C<diskid> is the disk UUID/disk identifier GUID from the partition 527The I<diskid> is the disk GUID/disk identifier GUID from the partition
525table (as displayed e.g. by C<gdisk>), and the C<partitionid> is the 528table (as displayed e.g. by F<gdisk>), and the I<partitionid> is the
526partition unique GUID (displayed using e.g. the C<gdisk> C<i> command). 529partition unique GUID (displayed using e.g. the F<gdisk> F<i> command).
527 530
528Example: use the partition C<76d39e5f-ad1b-407e-9c05-c81eb83b57dd> on GPT 531Example: use the partition C<76d39e5f-ad1b-407e-9c05-c81eb83b57dd> on GPT
529disk C<9742e468-9206-48a0-b4e4-c4e9745a356a>. 532disk C<9742e468-9206-48a0-b4e4-c4e9745a356a>.
530 533
531 partition=<null>,harddisk,gpt,9742e468-9206-48a0-b4e4-c4e9745a356a,76d39e5f-ad1b-407e-9c05-c81eb83b57dd 534 partition=<null>,harddisk,gpt,9742e468-9206-48a0-b4e4-c4e9745a356a,76d39e5f-ad1b-407e-9c05-c81eb83b57dd
532 535
533=item raw 536=item C<raw>
534 537
535Instead of diskid and partitionid, this type only accepts a decimal disk 538Instead of I<diskid> and I<partitionid>, this type only accepts a decimal
536number and signifies the whole disk. BCDEDIT cannot display the resulting 539disk number and signifies the whole disk. BCDEDIT cannot display the
537device, and I am doubtful whether it has a useful effect. 540resulting device, and I am doubtful whether it has a useful effect.
538 541
539=back 542=back
540 543
541=item legacypartition=<parent>,devicetype,partitiontype,diskid,partitionid 544=item C<legacypartition=><I<parent>>,I<devicetype>,I<partitiontype>,I<diskid>,I<partitionid>
542 545
543This is exactly the same as the C<partition> type, except for a tiny 546This is exactly the same as the C<partition> type, except for a tiny
544detail: instead of using the partition start offset, this type uses the 547detail: instead of using the partition start offset, this type uses the
545partition number for MBR disks. Behaviour other partition types should be 548partition number for MBR disks. Behaviour other partition types should be
546the same. 549the same.
547 550
548The partition number starts at C<1> and skips unused partition, so if 551The partition number starts at C<1> and skips unused partition, so if
549there are two primary partitions and another partition inside the extended 552there are two primary partitions and another partition inside the extended
550partition, the primary partitions are number C<1> and C<2> and the 553partition, the primary partitions are number C<1> and C<2> and the
551partition inside the extended partition is number C<3>, rwegardless of any 554partition inside the extended partition is number C<3>, regardless of any
552gaps. 555gaps.
553 556
554=item locate=<parent>,locatetype,locatearg 557=item C<locate=><I<parent>>,I<locatetype>,I<locatearg>
555 558
556This device description will make the bootloader search for a partition 559This device description will make the bootloader search for a partition
557with a given path. 560with a given path.
558 561
559The C<< <parent> >> device is the device to search on (angle brackets are 562The I<parent> device is the device to search on (angle brackets are
560still part of the syntax!) If it is C<< <null> >>, then C<locate> will 563still part of the syntax!) If it is C<null>, then C<locate> will
561search all disks it can find. 564search all disks it can find.
562 565
563C<locatetype> is either C<element> or C<path>, and merely distinguishes 566I<locatetype> is either C<element> or C<path>, and merely distinguishes
564between two different ways to specify the path to search for: C<element> 567between two different ways to specify the path to search for: C<element>
565uses an element ID (either as hex or as name) as C<locatearg> and C<path> 568uses an element ID (either as hex or as name) as I<locatearg> and C<path>
566uses a relative path as C<locatearg>. 569uses a relative path as I<locatearg>.
567 570
568Example: find any partition which has the C<magicfile.xxx> path in the 571Example: find any partition which has the F<magicfile.xxx> path in the
569root. 572root.
570 573
571 locate=<null>,path,\magicfile.xxx 574 locate=<null>,path,\magicfile.xxx
572 575
573Example: find any partition which has the path specified in the 576Example: find any partition which has the path specified in the
574C<systemroot> element (typically C<\Windows>). 577C<systemroot> element (typically F<\Windows>).
575 578
576 locate=<null>,element,systemroot 579 locate=<null>,element,systemroot
577 580
578=item block=devicetype,args... 581=item C<block=>I<devicetype>,I<args...>
579 582
580Last not least, the most complex type, C<block>, which... specifies block 583Last not least, the most complex type, C<block>, which... specifies block
581devices (which could be inside a F<vhdx> file for example). 584devices (which could be inside a F<vhdx> file for example).
582 585
583C<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>, 586I<devicetypes> is one of C<harddisk>, C<floppy>, C<cdrom>, C<ramdisk>,
584C<file> or C<vhd> - the same as for C<partiion=>. 587C<file> or C<vhd> - the same as for C<partiion=>.
585 588
586The remaining arguments change depending on the C<devicetype>: 589The remaining arguments change depending on the I<devicetype>:
587 590
588=over 591=over
589 592
590=item block=file,<parent>,path 593=item C<block=file>,<I<parent>>,I<path>
591 594
592Interprets the C<< <parent> >> device (typically a partition) as a 595Interprets the I<parent> device (typically a partition) as a
593filesystem and specifies a file path inside. 596filesystem and specifies a file path inside.
594 597
595=item block=vhd,<parent> 598=item C<block=vhd>,<I<parent>>
596 599
597Pretty much just changes the interpretation of C<< <parent> >>, which is 600Pretty much just changes the interpretation of I<parent>, which is
598usually a disk image (C<block=file,...)>) to be a F<vhd> or F<vhdx> file. 601usually a disk image (C<block=file,...)>) to be a F<vhd> or F<vhdx> file.
599 602
600=item block=ramdisk,<parent>,base,size,offset,path 603=item C<block=ramdisk>,<I<parent>>,I<base>,I<size>,I<offset>,I<path>
601 604
602Interprets the C<< <parent> >> device as RAM disk, using the (decimal) 605Interprets the I<parent> device as RAM disk, using the (decimal)
603base address, byte size and byte offset inside a file specified by 606base address, byte size and byte offset inside a file specified by
604C<path>. The numbers are usually all C<0> because they cna be extracted 607I<path>. The numbers are usually all C<0> because they can be extracted
605from the RAM disk image or other parameters. 608from the RAM disk image or other parameters.
606 609
607This is most commonly used to boot C<wim> images. 610This is most commonly used to boot C<wim> images.
608 611
609=item block=floppy,drivenum 612=item C<block=floppy>,I<drivenum>
610 613
611Refers to a removable drive identified by a number. BCDEDIT cannot display 614Refers to a removable drive identified by a number. BCDEDIT cannot display
612the resultinfg device, and it is not clear what effect it will have. 615the resulting device, and it is not clear what effect it will have.
613 616
614=item block=cdrom,drivenum 617=item C<block=cdrom>,I<drivenum>
615 618
616Pretty much the same as C<floppy> but for CD-ROMs. 619Pretty much the same as C<floppy> but for CD-ROMs.
617 620
618=item anything else 621=item anything else
619 622
623 626
624=back5 Examples 627=back5 Examples
625 628
626This concludes the syntax overview for device elements, but probably 629This concludes the syntax overview for device elements, but probably
627leaves many questions open. I can't help with most of them, as I also ave 630leaves many questions open. I can't help with most of them, as I also ave
628many questions, but I can walk you through some actual examples using mroe 631many questions, but I can walk you through some actual examples using more
629complex aspects. 632complex aspects.
630 633
631=item locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path 634=item C<< locate=<block=vhd,<block=file,<locate=<null>,path,\disk.vhdx>,\disk.vhdx>>,element,path >>
632 635
633Just like with C declarations, you best treat device descriptors as 636Just like with C declarations, you best treat device descriptors as
634instructions to find your device and work your way from the inside out: 637instructions to find your device and work your way from the inside out:
635 638
636 locate=<null>,path,\disk.vhdx 639 locate=<null>,path,\disk.vhdx
643Next, this takes the device locate has found and finds a file called 646Next, this takes the device locate has found and finds a file called
644F<\disk.vhdx> on it. This is the same file locate was using, but that is 647F<\disk.vhdx> on it. This is the same file locate was using, but that is
645only because we find the device using the same path as finding the disk 648only because we find the device using the same path as finding the disk
646image, so this is purely incidental, although quite common. 649image, so this is purely incidental, although quite common.
647 650
648Bext, this file will be opened as a virtual disk: 651Next, this file will be opened as a virtual disk:
649 652
650 block=vhd,<see above> 653 block=vhd,<see above>
651 654
652And finally, inside this disk, another C<locate> will look for a partition 655And finally, inside this disk, another C<locate> will look for a partition
653with a path as specified in the C<path> element, which most likely will be 656with a path as specified in the C<path> element, which most likely will be
656 locate=<see above>,element,path 659 locate=<see above>,element,path
657 660
658As a result, this will boot the first Windows it finds on the first 661As a result, this will boot the first Windows it finds on the first
659F<disk.vhdx> disk image it can find anywhere. 662F<disk.vhdx> disk image it can find anywhere.
660 663
661=item locate=<block=vhd,<block=file,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,\win10.vhdx>>,element,path 664=item C<< locate=<block=vhd,<block=file,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,\win10.vhdx>>,element,path >>
662 665
663Pretty much the same as the previous case, but witzh a bit of variance. First, look for a specific partition on 666Pretty much the same as the previous case, but with a bit of
664an MBR-partitioned disk: 667variance. First, look for a specific partition on an MBR-partitioned disk:
665 668
666 partition=<null>,harddisk,mbr,47cbc08a,242643632128 669 partition=<null>,harddisk,mbr,47cbc08a,242643632128
667 670
668Then open the file F<\win10.vhdx> on that partition: 671Then open the file F<\win10.vhdx> on that partition:
669 672
675 678
676And again the windows loader (or whatever is in C<path>) will be searched: 679And again the windows loader (or whatever is in C<path>) will be searched:
677 680
678 locate=<see above>,element,path 681 locate=<see above>,element,path
679 682
680=item {b097d2b2-bc00-11e9-8a9a-525400123456}block<1>=ramdisk,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,0,0,0,\boot.wim 683=item C<< {b097d2b2-bc00-11e9-8a9a-525400123456}block<1>=ramdisk,<partition=<null>,harddisk,mbr,47cbc08a,242643632128>,0,0,0,\boot.wim >>
681 684
682This is quite different. First, it starts with a GUID. This GUID belongs 685This is quite different. First, it starts with a GUID. This GUID belongs
683to a BCD object of type C<device>, which has additional parameters: 686to a BCD object of type C<device>, which has additional parameters:
684 687
685 "{b097d2b2-bc00-11e9-8a9a-525400123456}" : { 688 "{b097d2b2-bc00-11e9-8a9a-525400123456}" : {
688 "ramdisksdidevice" : "partition=<null>,harddisk,mbr,47cbc08a,1048576", 691 "ramdisksdidevice" : "partition=<null>,harddisk,mbr,47cbc08a,1048576",
689 "ramdisksdipath" : "\boot.sdi" 692 "ramdisksdipath" : "\boot.sdi"
690 }, 693 },
691 694
692I will not go into many details, but this specifies a (presumably empty) 695I will not go into many details, but this specifies a (presumably empty)
693template ramdisk image (F<\boot.sdi>) that is used to initiaolize the 696template ramdisk image (F<\boot.sdi>) that is used to initialize the
694ramdisk. The F<\boot.wim> file is then extracted into it. As you cna also 697ramdisk. The F<\boot.wim> file is then extracted into it. As you can also
695see, this F<.sdi> file resides on a different C<partition>. 698see, this F<.sdi> file resides on a different C<partition>.
696 699
697Continuitn, as always, form the inside out, first this device descriptor 700Continuing, as always, from the inside out, first this device descriptor
698finds a specific partition: 701finds a specific partition:
699 702
700 partition=<null>,harddisk,mbr,47cbc08a,242643632128 703 partition=<null>,harddisk,mbr,47cbc08a,242643632128
701 704
702And then specifies a C<ramdisk> image on this partition: 705And then specifies a C<ramdisk> image on this partition:
707seems to be always there on this kind of entry. 710seems to be always there on this kind of entry.
708 711
709If you have some good examples to add here, feel free to mail me. 712If you have some good examples to add here, feel free to mail me.
710 713
711 714
712=head1 EDITING BCD DATA STORES 715=head1 EDITING BCD STORES
713 716
714The C<edit> and C<parse> subcommands allow you to read a BCD data store 717The C<edit> and C<parse> subcommands allow you to read a BCD data store
715and modify it or extract data from it. This is done by exyecuting a series 718and modify it or extract data from it. This is done by executing a series
716of "editing instructions" which are explained here. 719of "editing instructions" which are explained here.
717 720
718=over 721=over
719 722
720=item get I<object> I<element> 723=item C<get> I<object> I<element>
721 724
722Reads the BCD element I<element> from the BCD object I<object> and writes 725Reads the BCD element I<element> from the BCD object I<object> and writes
723it to standard output, followed by a newline. The I<object> can be a GUID 726it to standard output, followed by a newline. The I<object> can be a GUID
724or a human-readable alias, or the special string C<{default}>, which will 727or a human-readable alias, or the special string C<{default}>, which will
725refer to the default BCD object. 728refer to the default BCD object.
726 729
727Example: find description of the default BCD object. 730Example: find description of the default BCD object.
728 731
729 pbcdedit parse BCD get "{default}" description 732 pbcdedit parse BCD get "{default}" description
730 733
731=item set I<object> I<element> I<value> 734=item C<set> I<object> I<element> I<value>
732 735
733Similar to C<get>, but sets the element to the given I<value> instead. 736Similar to C<get>, but sets the element to the given I<value> instead.
734 737
735Example: change bootmgr default too 738Example: change the bootmgr default too
736C<{b097d2ad-bc00-11e9-8a9a-525400123456}>: 739C<{b097d2ad-bc00-11e9-8a9a-525400123456}>:
737 740
738 pbcdedit edit BCD set "{bootmgr}" resumeobject "{b097d2ad-bc00-11e9-8a9a-525400123456}" 741 pbcdedit edit BCD set "{bootmgr}" resumeobject "{b097d2ad-bc00-11e9-8a9a-525400123456}"
739 742
740=item eval I<perlcode> 743=item C<eval> I<perlcode>
741 744
742This takes the next argument, interprets it as Perl code and 745This takes the next argument, interprets it as Perl code and
743evaluates it. This allows you to do more complicated modifications or 746evaluates it. This allows you to do more complicated modifications or
744extractions. 747extractions.
745 748
764The example given for C<get>, above, could be expressed like this with 767The example given for C<get>, above, could be expressed like this with
765C<eval>: 768C<eval>:
766 769
767 pbcdedit edit BCD eval 'say $BCD->{$DEFAULT}{description}' 770 pbcdedit edit BCD eval 'say $BCD->{$DEFAULT}{description}'
768 771
769The example given for C<set> could be expresed like this: 772The example given for C<set> could be expressed like this:
770 773
771 pbcdedit edit BCD eval '$BCD->{$DEFAULT}{resumeobject} = "{b097d2ad-bc00-11e9-8a9a-525400123456}"' 774 pbcdedit edit BCD eval '$BCD->{$DEFAULT}{resumeobject} = "{b097d2ad-bc00-11e9-8a9a-525400123456}"'
772 775
773=item do I<path> 776=item C<do> I<path>
774 777
775Similar to C<eval>, above, but instead of using the argument as perl code, 778Similar to C<eval>, above, but instead of using the argument as perl code,
776it loads the perl code from the given file and executes it. This makes it 779it loads the perl code from the given file and executes it. This makes it
777easier to write more complicated or larger programs. 780easier to write more complicated or larger programs.
778 781
779=back 782=back
780 783
784
781=head1 SEE ALSO 785=head1 SEE ALSO
782 786
783For ideas on what you can do, and some introductory material, try 787For ideas on what you can do with BCD stores in
788general, and some introductory material, try
784L<http://www.mistyprojects.co.uk/documents/BCDEdit/index.html>. 789L<http://www.mistyprojects.co.uk/documents/BCDEdit/index.html>.
785 790
786For good reference on BCD objects and elements, see Geoff Chappels pages 791For good reference on which BCD objects and
792elements exist, see Geoff Chappell's pages at
787at L<http://www.geoffchappell.com/notes/windows/boot/bcd/index.htm>. 793L<http://www.geoffchappell.com/notes/windows/boot/bcd/index.htm>.
788 794
789=head1 AUTHOR 795=head1 AUTHOR
790 796
791Written by Marc A. Lehmann <pbcdedit@schmorp.de>. 797Written by Marc A. Lehmann L<pbcdedit@schmorp.de>.
792 798
793=head1 REPORTING BUGS 799=head1 REPORTING BUGS
794 800
795Bugs can be reported dorectly tt he author at L<pcbedit@schmorp.de>. 801Bugs can be reported directly the author at L<pcbedit@schmorp.de>.
796 802
797=head1 BUGS AND SHORTCOMINGS 803=head1 BUGS AND SHORTCOMINGS
798 804
799This should be a module. Of a series of modules, even. 805This should be a module. Of a series of modules, even.
800 806
801Registry code should preserve classname and security descriptor data, and 807Registry code should preserve classname and security descriptor data, and
802whatever else is necessary to read and write any registry hive file. 808whatever else is necessary to read and write any registry hive file.
803 809
804I am also not happy with device descriptors being strings rather than a 810I am also not happy with device descriptors being strings rather than a
805data structure, but strings are probably better for command line usage. In 811data structure, but strings are probably better for command line usage. In
806any case,. device descriptors could be converted by simply "splitting" at 812any case, device descriptors could be converted by simply "splitting" at
807"=" and "," into an array reference, recursively. 813"=" and "," into an array reference, recursively.
808 814
809=head1 HOMEPAGE 815=head1 HOMEPAGE
810 816
811Original versions of this program can be found at 817Original versions of this program can be found at
818free to change and redistribute it. There is NO WARRANTY, to the extent 824free to change and redistribute it. There is NO WARRANTY, to the extent
819permitted by law. 825permitted by law.
820 826
821=cut 827=cut
822 828
823BEGIN { require "common/sense.pm"; common::sense->import } # common sense is optional, but recommended 829# common sense is optional, but recommended
830BEGIN { eval { require "common/sense.pm"; } && common::sense->import }
824 831
825use Data::Dump;
826use Encode (); 832use Encode ();
827use List::Util (); 833use List::Util ();
828use IO::Handle (); 834use IO::Handle ();
829use Time::HiRes (); 835use Time::HiRes ();
830 836
853 or die "$path: short read\n"; 859 or die "$path: short read\n";
854 860
855 $buf 861 $buf
856} 862}
857 863
858# sources and resources used for this: 864# sources and resources used for writing pbcdedit
865#
859# registry: 866# registry:
860# https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md 867# https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md
861# http://amnesia.gtisc.gatech.edu/~moyix/suzibandit.ltd.uk/MSc/ 868# http://amnesia.gtisc.gatech.edu/~moyix/suzibandit.ltd.uk/MSc/
862# bcd: 869# bcd:
863# http://www.geoffchappell.com/notes/windows/boot/bcd/index.htm 870# http://www.geoffchappell.com/notes/windows/boot/bcd/index.htm
2242 Objects => [undef, \%objects], 2249 Objects => [undef, \%objects],
2243 }]] 2250 }]]
2244} 2251}
2245 2252
2246############################################################################# 2253#############################################################################
2254# edit instructions
2247 2255
2248sub bcd_edit_eval { 2256sub bcd_edit_eval {
2249 package pbcdedit; 2257 package pbcdedit;
2250 2258
2251 our ($PATH, $BCD, $DEFAULT); 2259 our ($PATH, $BCD, $DEFAULT);
2269 2277
2270 if ($insn eq "get") { 2278 if ($insn eq "get") {
2271 my $object = shift @insns; 2279 my $object = shift @insns;
2272 my $elem = shift @insns; 2280 my $elem = shift @insns;
2273 2281
2274 $object = $default if $object eq "{default}"; 2282 $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object;
2275 2283
2276 print $bcd->{$object}{$elem}, "\n"; 2284 print $bcd->{$object}{$elem}, "\n";
2277 2285
2278 } elsif ($insn eq "set") { 2286 } elsif ($insn eq "set") {
2279 my $object = shift @insns; 2287 my $object = shift @insns;
2280 my $elem = shift @insns; 2288 my $elem = shift @insns;
2281 my $value = shift @insns; 2289 my $value = shift @insns;
2282 2290
2283 $object = $default if $object eq "{default}"; 2291 $object = $object eq "{default}" ? $default : dec_wguid enc_wguid $object;
2284 2292
2285 $bcd->{$object}{$elem} = $value; 2293 $bcd->{$object}{$elem} = $value;
2286 2294
2287 } elsif ($insn eq "eval") { 2295 } elsif ($insn eq "eval") {
2288 bcd_edit_eval shift @insns; 2296 bcd_edit_eval shift @insns;
2298 } 2306 }
2299 2307
2300} 2308}
2301 2309
2302############################################################################# 2310#############################################################################
2311# command line parser
2303 2312
2304# json to stdout 2313# json to stdout
2305sub prjson($) { 2314sub prjson($) {
2306 print $json_coder->encode ($_[0]); 2315 print $json_coder->encode ($_[0]);
2307} 2316}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines