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

Comparing pbcdedit/pbcdedit (file contents):
Revision 1.36 by root, Thu Aug 15 08:53:14 2019 UTC vs.
Revision 1.37 by root, Thu Aug 15 22:23:49 2019 UTC

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.016; # numerous features need 5.14, __SUB__ needs 5.16 22use 5.016; # numerous features need 5.14, __SUB__ needs 5.16
23 23
24our $VERSION = '1.1'; 24our $VERSION = '1.2';
25our $JSON_VERSION = 1; # the versiobn of the json objects generated by this program 25our $JSON_VERSION = 2; # the version of the json objects generated by this program
26
27our $CHANGELOG = <<EOF;
281.2 Fri Aug 16 00:20:41 CEST 2019
29 - bcde element names now depend on the bcd object type they are in,
30 also affects "elements" output.
31 - json schema bumped to 2.
32 - new version command.
33 - numerous minor bugfixes.
34
35EOF
26 36
27=head1 NAME 37=head1 NAME
28 38
29 pbcdedit - portable boot configuration data (BCD) store editor 39 pbcdedit - portable boot configuration data (BCD) store editor
30 40
31=head1 SYNOPSIS 41=head1 SYNOPSIS
32 42
33 pbcdedit help # output manual page 43 pbcdedit help # output manual page
44 pbcdedit version # output version and changelog
34 45
35 pbcdedit export path/to/BCD # output BCD hive as JSON 46 pbcdedit export path/to/BCD # output BCD hive as JSON
36 pbcdedit import path/to/BCD # convert standard input to BCD hive 47 pbcdedit import path/to/BCD # convert standard input to BCD hive
37 pbcdedit edit path/to/BCD edit-instructions... 48 pbcdedit edit path/to/BCD edit-instructions...
38 49
91=over 102=over
92 103
93=item C<help> 104=item C<help>
94 105
95Displays the whole manual page (this document). 106Displays the whole manual page (this document).
107
108=item C<version>
109
110This outputs the PBCDEDIT version, the JSON schema version it uses and the
111full log of changes.
96 112
97=item C<export> F<path> 113=item C<export> F<path>
98 114
99Reads a BCD data store and writes a JSON representation of it to standard 115Reads a BCD data store and writes a JSON representation of it to standard
100output. 116output.
827=cut 843=cut
828 844
829# common sense is optional, but recommended 845# common sense is optional, but recommended
830BEGIN { eval { require "common/sense.pm"; } && common::sense->import } 846BEGIN { eval { require "common/sense.pm"; } && common::sense->import }
831 847
848no warnings 'portable'; # avoid 32 bit integer warnings
849
832use Encode (); 850use Encode ();
833use List::Util (); 851use List::Util ();
834use IO::Handle (); 852use IO::Handle ();
835use Time::HiRes (); 853use Time::HiRes ();
836 854
1358sub BCDE_FORMAT_GUID_LIST () { 0x04000000 } 1376sub BCDE_FORMAT_GUID_LIST () { 0x04000000 }
1359sub BCDE_FORMAT_INTEGER () { 0x05000000 } 1377sub BCDE_FORMAT_INTEGER () { 0x05000000 }
1360sub BCDE_FORMAT_BOOLEAN () { 0x06000000 } 1378sub BCDE_FORMAT_BOOLEAN () { 0x06000000 }
1361sub BCDE_FORMAT_INTEGER_LIST () { 0x07000000 } 1379sub BCDE_FORMAT_INTEGER_LIST () { 0x07000000 }
1362 1380
1363sub dec_device;
1364sub enc_device;
1365
1366sub enc_integer($) { 1381sub enc_integer($) {
1367 no warnings 'portable'; # ugh
1368 my $value = shift; 1382 my $value = shift;
1369 $value = oct $value if $value =~ /^0[bBxX]/; 1383 $value = oct $value if $value =~ /^0[bBxX]/;
1370 unpack "H*", pack "Q<", $value 1384 unpack "H*", pack "Q<", $value
1371} 1385}
1386
1387sub enc_device($$);
1388sub dec_device($$);
1372 1389
1373our %bcde_dec = ( 1390our %bcde_dec = (
1374 BCDE_FORMAT_DEVICE , \&dec_device, 1391 BCDE_FORMAT_DEVICE , \&dec_device,
1375# # for round-trip verification 1392# # for round-trip verification
1376# BCDE_FORMAT_DEVICE , sub { 1393# BCDE_FORMAT_DEVICE , sub {
1386 BCDE_FORMAT_BOOLEAN , sub { shift eq "00" ? 0 : 1 }, 1403 BCDE_FORMAT_BOOLEAN , sub { shift eq "00" ? 0 : 1 },
1387 BCDE_FORMAT_INTEGER_LIST, sub { join " ", unpack "Q*", pack "H*", shift }, # not sure if this cna be 4 bytes 1404 BCDE_FORMAT_INTEGER_LIST, sub { join " ", unpack "Q*", pack "H*", shift }, # not sure if this cna be 4 bytes
1388); 1405);
1389 1406
1390our %bcde_enc = ( 1407our %bcde_enc = (
1391 BCDE_FORMAT_DEVICE , sub { binary => enc_device shift }, 1408 BCDE_FORMAT_DEVICE , sub { binary => enc_device $_[0], $_[1] },
1392 BCDE_FORMAT_STRING , sub { sz => shift }, 1409 BCDE_FORMAT_STRING , sub { sz => shift },
1393 BCDE_FORMAT_GUID , sub { sz => "{" . (dec_guid enc_wguid shift) . "}" }, 1410 BCDE_FORMAT_GUID , sub { sz => "{" . (dec_guid enc_wguid shift) . "}" },
1394 BCDE_FORMAT_GUID_LIST , sub { multi_sz => [map "{" . (dec_guid enc_wguid $_) . "}", split /\s+/, shift ] }, 1411 BCDE_FORMAT_GUID_LIST , sub { multi_sz => [map "{" . (dec_guid enc_wguid $_) . "}", split /\s+/, shift ] },
1395 BCDE_FORMAT_INTEGER , sub { binary => enc_integer shift }, 1412 BCDE_FORMAT_INTEGER , sub { binary => enc_integer shift },
1396 BCDE_FORMAT_BOOLEAN , sub { binary => shift ? "01" : "00" }, 1413 BCDE_FORMAT_BOOLEAN , sub { binary => shift ? "01" : "00" },
1397 BCDE_FORMAT_INTEGER_LIST, sub { binary => join "", map enc_integer $_, split /\s+/, shift }, 1414 BCDE_FORMAT_INTEGER_LIST, sub { binary => join "", map enc_integer $_, split /\s+/, shift },
1398); 1415);
1399 1416
1400# BCD Elements 1417# BCD Elements
1401our %bcde = ( 1418our %bcde_byclass = (
1419 any => {
1402 0x11000001 => 'device', 1420 0x11000001 => 'device',
1403 0x12000002 => 'path', 1421 0x12000002 => 'path',
1404 0x12000004 => 'description', 1422 0x12000004 => 'description',
1405 0x12000005 => 'locale', 1423 0x12000005 => 'locale',
1406 0x14000006 => 'inherit', 1424 0x14000006 => 'inherit',
1407 0x15000007 => 'truncatememory', 1425 0x15000007 => 'truncatememory',
1408 0x14000008 => 'recoverysequence', 1426 0x14000008 => 'recoverysequence',
1409 0x16000009 => 'recoveryenabled', 1427 0x16000009 => 'recoveryenabled',
1410 0x1700000a => 'badmemorylist', 1428 0x1700000a => 'badmemorylist',
1411 0x1600000b => 'badmemoryaccess', 1429 0x1600000b => 'badmemoryaccess',
1412 0x1500000c => 'firstmegabytepolicy', 1430 0x1500000c => 'firstmegabytepolicy',
1413 0x1500000d => 'relocatephysical', 1431 0x1500000d => 'relocatephysical',
1414 0x1500000e => 'avoidlowmemory', 1432 0x1500000e => 'avoidlowmemory',
1415 0x1600000f => 'traditionalkseg', 1433 0x1600000f => 'traditionalkseg',
1416 0x16000010 => 'bootdebug', 1434 0x16000010 => 'bootdebug',
1417 0x15000011 => 'debugtype', 1435 0x15000011 => 'debugtype',
1418 0x15000012 => 'debugaddress', 1436 0x15000012 => 'debugaddress',
1419 0x15000013 => 'debugport', 1437 0x15000013 => 'debugport',
1420 0x15000014 => 'baudrate', 1438 0x15000014 => 'baudrate',
1421 0x15000015 => 'channel', 1439 0x15000015 => 'channel',
1422 0x12000016 => 'targetname', 1440 0x12000016 => 'targetname',
1423 0x16000017 => 'noumex', 1441 0x16000017 => 'noumex',
1424 0x15000018 => 'debugstart', 1442 0x15000018 => 'debugstart',
1425 0x12000019 => 'busparams', 1443 0x12000019 => 'busparams',
1426 0x1500001a => 'hostip', 1444 0x1500001a => 'hostip',
1427 0x1500001b => 'port', 1445 0x1500001b => 'port',
1428 0x1600001c => 'dhcp', 1446 0x1600001c => 'dhcp',
1429 0x1200001d => 'key', 1447 0x1200001d => 'key',
1430 0x1600001e => 'vm', 1448 0x1600001e => 'vm',
1431 0x16000020 => 'bootems', 1449 0x16000020 => 'bootems',
1432 0x15000022 => 'emsport', 1450 0x15000022 => 'emsport',
1433 0x15000023 => 'emsbaudrate', 1451 0x15000023 => 'emsbaudrate',
1434 0x12000030 => 'loadoptions', 1452 0x12000030 => 'loadoptions',
1435 0x16000040 => 'advancedoptions', 1453 0x16000040 => 'advancedoptions',
1436 0x16000041 => 'optionsedit', 1454 0x16000041 => 'optionsedit',
1437 0x15000042 => 'keyringaddress', 1455 0x15000042 => 'keyringaddress',
1438 0x11000043 => 'bootstatdevice', 1456 0x11000043 => 'bootstatdevice',
1439 0x12000044 => 'bootstatfilepath', 1457 0x12000044 => 'bootstatfilepath',
1440 0x16000045 => 'preservebootstat', 1458 0x16000045 => 'preservebootstat',
1441 0x16000046 => 'graphicsmodedisabled', 1459 0x16000046 => 'graphicsmodedisabled',
1442 0x15000047 => 'configaccesspolicy', 1460 0x15000047 => 'configaccesspolicy',
1443 0x16000048 => 'nointegritychecks', 1461 0x16000048 => 'nointegritychecks',
1444 0x16000049 => 'testsigning', 1462 0x16000049 => 'testsigning',
1445 0x1200004a => 'fontpath', 1463 0x1200004a => 'fontpath',
1446 0x1500004b => 'integrityservices', 1464 0x1500004b => 'integrityservices',
1447 0x1500004c => 'volumebandid', 1465 0x1500004c => 'volumebandid',
1448 0x16000050 => 'extendedinput', 1466 0x16000050 => 'extendedinput',
1449 0x15000051 => 'initialconsoleinput', 1467 0x15000051 => 'initialconsoleinput',
1450 0x15000052 => 'graphicsresolution', 1468 0x15000052 => 'graphicsresolution',
1451 0x16000053 => 'restartonfailure', 1469 0x16000053 => 'restartonfailure',
1452 0x16000054 => 'highestmode', 1470 0x16000054 => 'highestmode',
1453 0x16000060 => 'isolatedcontext', 1471 0x16000060 => 'isolatedcontext',
1454 0x15000065 => 'displaymessage', 1472 0x15000065 => 'displaymessage',
1455 0x15000066 => 'displaymessageoverride', 1473 0x15000066 => 'displaymessageoverride',
1456 0x16000068 => 'nobootuxtext', 1474 0x16000068 => 'nobootuxtext',
1457 0x16000069 => 'nobootuxprogress', 1475 0x16000069 => 'nobootuxprogress',
1458 0x1600006a => 'nobootuxfade', 1476 0x1600006a => 'nobootuxfade',
1459 0x1600006b => 'bootuxreservepooldebug', 1477 0x1600006b => 'bootuxreservepooldebug',
1460 0x1600006c => 'bootuxdisabled', 1478 0x1600006c => 'bootuxdisabled',
1461 0x1500006d => 'bootuxfadeframes', 1479 0x1500006d => 'bootuxfadeframes',
1462 0x1600006e => 'bootuxdumpstats', 1480 0x1600006e => 'bootuxdumpstats',
1463 0x1600006f => 'bootuxshowstats', 1481 0x1600006f => 'bootuxshowstats',
1464 0x16000071 => 'multibootsystem', 1482 0x16000071 => 'multibootsystem',
1465 0x16000072 => 'nokeyboard', 1483 0x16000072 => 'nokeyboard',
1466 0x15000073 => 'aliaswindowskey', 1484 0x15000073 => 'aliaswindowskey',
1467 0x16000074 => 'bootshutdowndisabled', 1485 0x16000074 => 'bootshutdowndisabled',
1468 0x15000075 => 'performancefrequency', 1486 0x15000075 => 'performancefrequency',
1469 0x15000076 => 'securebootrawpolicy', 1487 0x15000076 => 'securebootrawpolicy',
1470 0x17000077 => 'allowedinmemorysettings', 1488 0x17000077 => 'allowedinmemorysettings',
1471 0x15000079 => 'bootuxtransitiontime', 1489 0x15000079 => 'bootuxtransitiontime',
1472 0x1600007a => 'mobilegraphics', 1490 0x1600007a => 'mobilegraphics',
1473 0x1600007b => 'forcefipscrypto', 1491 0x1600007b => 'forcefipscrypto',
1474 0x1500007d => 'booterrorux', 1492 0x1500007d => 'booterrorux',
1475 0x1600007e => 'flightsigning', 1493 0x1600007e => 'flightsigning',
1476 0x1500007f => 'measuredbootlogformat', 1494 0x1500007f => 'measuredbootlogformat',
1477 0x15000080 => 'displayrotation', 1495 0x15000080 => 'displayrotation',
1478 0x15000081 => 'logcontrol', 1496 0x15000081 => 'logcontrol',
1479 0x16000082 => 'nofirmwaresync', 1497 0x16000082 => 'nofirmwaresync',
1480 0x11000084 => 'windowssyspart', 1498 0x11000084 => 'windowssyspart',
1481 0x16000087 => 'numlock', 1499 0x16000087 => 'numlock',
1482 0x22000001 => 'bpbstring', 1500 0x26000202 => 'skipffumode',
1501 0x26000203 => 'forceffumode',
1502 0x25000510 => 'chargethreshold',
1503 0x26000512 => 'offmodecharging',
1504 0x25000aaa => 'bootflow',
1505 0x45000001 => 'devicetype',
1506 0x42000002 => 'applicationrelativepath',
1507 0x42000003 => 'ramdiskdevicerelativepath',
1508 0x46000004 => 'omitosloaderelements',
1509 0x47000006 => 'elementstomigrate',
1510 0x46000010 => 'recoveryos',
1511 },
1512 bootapp => {
1513 0x26000145 => 'enablebootdebugpolicy',
1514 0x26000146 => 'enablebootorderclean',
1515 0x26000147 => 'enabledeviceid',
1516 0x26000148 => 'enableffuloader',
1517 0x26000149 => 'enableiuloader',
1518 0x2600014a => 'enablemassstorage',
1519 0x2600014b => 'enablerpmbprovisioning',
1520 0x2600014c => 'enablesecurebootpolicy',
1521 0x2600014d => 'enablestartcharge',
1522 0x2600014e => 'enableresettpm',
1523 },
1524 bootmgr => {
1483 0x24000001 => 'displayorder', 1525 0x24000001 => 'displayorder',
1484 0x21000001 => 'filedevice',
1485 0x21000001 => 'osdevice',
1486 0x25000001 => 'passcount',
1487 0x26000001 => 'pxesoftreboot',
1488 0x22000002 => 'applicationname',
1489 0x24000002 => 'bootsequence', 1526 0x24000002 => 'bootsequence',
1490 0x22000002 => 'filepath',
1491 0x22000002 => 'systemroot',
1492 0x25000002 => 'testmix',
1493 0x26000003 => 'cacheenable',
1494 0x26000003 => 'customsettings',
1495 0x23000003 => 'default', 1527 0x23000003 => 'default',
1496 0x25000003 => 'failurecount',
1497 0x26000004 => 'failuresenabled',
1498 0x26000004 => 'pae',
1499 0x26000004 => 'stampdisks',
1500 0x25000004 => 'testtofail',
1501 0x25000004 => 'timeout', 1528 0x25000004 => 'timeout',
1502 0x21000005 => 'associatedosdevice',
1503 0x26000005 => 'cacheenable',
1504 0x26000005 => 'resume', 1529 0x26000005 => 'resume',
1505 0x25000005 => 'stridefailcount',
1506 0x26000006 => 'debugoptionenabled',
1507 0x25000006 => 'invcfailcount',
1508 0x23000006 => 'resumeobject', 1530 0x23000006 => 'resumeobject',
1509 0x25000007 => 'bootux',
1510 0x25000007 => 'matsfailcount',
1511 0x24000007 => 'startupsequence', 1531 0x24000007 => 'startupsequence',
1512 0x25000008 => 'bootmenupolicy',
1513 0x25000008 => 'randfailcount',
1514 0x25000009 => 'chckrfailcount',
1515 0x26000010 => 'detecthal',
1516 0x24000010 => 'toolsdisplayorder', 1532 0x24000010 => 'toolsdisplayorder',
1517 0x22000011 => 'kernel',
1518 0x22000012 => 'hal',
1519 0x22000013 => 'dbgtransport',
1520 0x26000020 => 'displaybootmenu', 1533 0x26000020 => 'displaybootmenu',
1521 0x25000020 => 'nx',
1522 0x26000021 => 'noerrordisplay', 1534 0x26000021 => 'noerrordisplay',
1523 0x25000021 => 'pae',
1524 0x21000022 => 'bcddevice', 1535 0x21000022 => 'bcddevice',
1525 0x26000022 => 'winpe',
1526 0x22000023 => 'bcdfilepath', 1536 0x22000023 => 'bcdfilepath',
1527 0x26000024 => 'hormenabled', 1537 0x26000024 => 'hormenabled',
1528 0x26000024 => 'hormenabled',
1529 0x26000024 => 'nocrashautoreboot',
1530 0x26000025 => 'hiberboot', 1538 0x26000025 => 'hiberboot',
1531 0x26000025 => 'lastknowngood',
1532 0x26000026 => 'oslnointegritychecks',
1533 0x22000026 => 'passwordoverride', 1539 0x22000026 => 'passwordoverride',
1534 0x26000027 => 'osltestsigning',
1535 0x22000027 => 'pinpassphraseoverride', 1540 0x22000027 => 'pinpassphraseoverride',
1536 0x26000028 => 'processcustomactionsfirst', 1541 0x26000028 => 'processcustomactionsfirst',
1537 0x27000030 => 'customactions', 1542 0x27000030 => 'customactions',
1538 0x26000030 => 'nolowmem',
1539 0x26000031 => 'persistbootsequence', 1543 0x26000031 => 'persistbootsequence',
1540 0x25000031 => 'removememory',
1541 0x25000032 => 'increaseuserva',
1542 0x26000032 => 'skipstartupsequence', 1544 0x26000032 => 'skipstartupsequence',
1543 0x25000033 => 'perfmem',
1544 0x22000040 => 'fverecoveryurl', 1545 0x22000040 => 'fverecoveryurl',
1545 0x26000040 => 'vga',
1546 0x22000041 => 'fverecoverymessage', 1546 0x22000041 => 'fverecoverymessage',
1547 },
1548 device => {
1549 0x35000001 => 'ramdiskimageoffset',
1550 0x35000002 => 'ramdisktftpclientport',
1551 0x31000003 => 'ramdisksdidevice',
1552 0x32000004 => 'ramdisksdipath',
1553 0x35000005 => 'ramdiskimagelength',
1554 0x36000006 => 'exportascd',
1555 0x35000007 => 'ramdisktftpblocksize',
1556 0x35000008 => 'ramdisktftpwindowsize',
1557 0x36000009 => 'ramdiskmcenabled',
1558 0x3600000a => 'ramdiskmctftpfallback',
1559 0x3600000b => 'ramdisktftpvarwindow',
1560 },
1561 memdiag => {
1562 0x25000001 => 'passcount',
1563 0x25000002 => 'testmix',
1564 0x25000003 => 'failurecount',
1565 0x26000003 => 'cacheenable',
1566 0x25000004 => 'testtofail',
1567 0x26000004 => 'failuresenabled',
1568 0x25000005 => 'stridefailcount',
1569 0x26000005 => 'cacheenable',
1570 0x25000006 => 'invcfailcount',
1571 0x25000007 => 'matsfailcount',
1572 0x25000008 => 'randfailcount',
1573 0x25000009 => 'chckrfailcount',
1574 },
1575 ntldr => {
1576 0x22000001 => 'bpbstring',
1577 },
1578 osloader => {
1579 0x21000001 => 'osdevice',
1580 0x22000002 => 'systemroot',
1581 0x23000003 => 'resumeobject',
1582 0x26000004 => 'stampdisks',
1583 0x26000010 => 'detecthal',
1584 0x22000011 => 'kernel',
1585 0x22000012 => 'hal',
1586 0x22000013 => 'dbgtransport',
1587 0x25000020 => 'nx',
1588 0x25000021 => 'pae',
1589 0x26000022 => 'winpe',
1590 0x26000024 => 'nocrashautoreboot',
1591 0x26000025 => 'lastknowngood',
1592 0x26000026 => 'oslnointegritychecks',
1593 0x26000027 => 'osltestsigning',
1594 0x26000030 => 'nolowmem',
1595 0x25000031 => 'removememory',
1596 0x25000032 => 'increaseuserva',
1597 0x25000033 => 'perfmem',
1598 0x26000040 => 'vga',
1547 0x26000041 => 'quietboot', 1599 0x26000041 => 'quietboot',
1548 0x26000042 => 'novesa', 1600 0x26000042 => 'novesa',
1549 0x26000043 => 'novga', 1601 0x26000043 => 'novga',
1550 0x25000050 => 'clustermodeaddressing', 1602 0x25000050 => 'clustermodeaddressing',
1551 0x26000051 => 'usephysicaldestination', 1603 0x26000051 => 'usephysicaldestination',
1552 0x25000052 => 'restrictapiccluster', 1604 0x25000052 => 'restrictapiccluster',
1553 0x22000053 => 'evstore', 1605 0x22000053 => 'evstore',
1554 0x26000054 => 'uselegacyapicmode', 1606 0x26000054 => 'uselegacyapicmode',
1555 0x26000060 => 'onecpu', 1607 0x26000060 => 'onecpu',
1556 0x25000061 => 'numproc', 1608 0x25000061 => 'numproc',
1557 0x26000062 => 'maxproc', 1609 0x26000062 => 'maxproc',
1558 0x25000063 => 'configflags', 1610 0x25000063 => 'configflags',
1559 0x26000064 => 'maxgroup', 1611 0x26000064 => 'maxgroup',
1560 0x26000065 => 'groupaware', 1612 0x26000065 => 'groupaware',
1561 0x25000066 => 'groupsize', 1613 0x25000066 => 'groupsize',
1562 0x26000070 => 'usefirmwarepcisettings', 1614 0x26000070 => 'usefirmwarepcisettings',
1563 0x25000071 => 'msi', 1615 0x25000071 => 'msi',
1564 0x25000072 => 'pciexpress', 1616 0x25000072 => 'pciexpress',
1565 0x25000080 => 'safeboot', 1617 0x25000080 => 'safeboot',
1566 0x26000081 => 'safebootalternateshell', 1618 0x26000081 => 'safebootalternateshell',
1567 0x26000090 => 'bootlog', 1619 0x26000090 => 'bootlog',
1568 0x26000091 => 'sos', 1620 0x26000091 => 'sos',
1569 0x260000a0 => 'debug', 1621 0x260000a0 => 'debug',
1570 0x260000a1 => 'halbreakpoint', 1622 0x260000a1 => 'halbreakpoint',
1571 0x260000a2 => 'useplatformclock', 1623 0x260000a2 => 'useplatformclock',
1572 0x260000a3 => 'forcelegacyplatform', 1624 0x260000a3 => 'forcelegacyplatform',
1573 0x260000a4 => 'useplatformtick', 1625 0x260000a4 => 'useplatformtick',
1574 0x260000a5 => 'disabledynamictick', 1626 0x260000a5 => 'disabledynamictick',
1575 0x250000a6 => 'tscsyncpolicy', 1627 0x250000a6 => 'tscsyncpolicy',
1576 0x260000b0 => 'ems', 1628 0x260000b0 => 'ems',
1577 0x250000c0 => 'forcefailure', 1629 0x250000c0 => 'forcefailure',
1578 0x250000c1 => 'driverloadfailurepolicy', 1630 0x250000c1 => 'driverloadfailurepolicy',
1579 0x250000c2 => 'bootmenupolicy', 1631 0x250000c2 => 'bootmenupolicy',
1580 0x260000c3 => 'onetimeadvancedoptions', 1632 0x260000c3 => 'onetimeadvancedoptions',
1581 0x260000c4 => 'onetimeoptionsedit', 1633 0x260000c4 => 'onetimeoptionsedit',
1582 0x250000e0 => 'bootstatuspolicy', 1634 0x250000e0 => 'bootstatuspolicy',
1583 0x260000e1 => 'disableelamdrivers', 1635 0x260000e1 => 'disableelamdrivers',
1584 0x250000f0 => 'hypervisorlaunchtype', 1636 0x250000f0 => 'hypervisorlaunchtype',
1585 0x220000f1 => 'hypervisorpath', 1637 0x220000f1 => 'hypervisorpath',
1586 0x260000f2 => 'hypervisordebug', 1638 0x260000f2 => 'hypervisordebug',
1587 0x250000f3 => 'hypervisordebugtype', 1639 0x250000f3 => 'hypervisordebugtype',
1588 0x250000f4 => 'hypervisordebugport', 1640 0x250000f4 => 'hypervisordebugport',
1589 0x250000f5 => 'hypervisorbaudrate', 1641 0x250000f5 => 'hypervisorbaudrate',
1590 0x250000f6 => 'hypervisorchannel', 1642 0x250000f6 => 'hypervisorchannel',
1591 0x250000f7 => 'bootux', 1643 0x250000f7 => 'bootux',
1592 0x260000f8 => 'hypervisordisableslat', 1644 0x260000f8 => 'hypervisordisableslat',
1593 0x220000f9 => 'hypervisorbusparams', 1645 0x220000f9 => 'hypervisorbusparams',
1594 0x250000fa => 'hypervisornumproc', 1646 0x250000fa => 'hypervisornumproc',
1595 0x250000fb => 'hypervisorrootprocpernode', 1647 0x250000fb => 'hypervisorrootprocpernode',
1596 0x260000fc => 'hypervisoruselargevtlb', 1648 0x260000fc => 'hypervisoruselargevtlb',
1597 0x250000fd => 'hypervisorhostip', 1649 0x250000fd => 'hypervisorhostip',
1598 0x250000fe => 'hypervisorhostport', 1650 0x250000fe => 'hypervisorhostport',
1599 0x250000ff => 'hypervisordebugpages', 1651 0x250000ff => 'hypervisordebugpages',
1600 0x25000100 => 'tpmbootentropy', 1652 0x25000100 => 'tpmbootentropy',
1601 0x22000110 => 'hypervisorusekey', 1653 0x22000110 => 'hypervisorusekey',
1602 0x22000112 => 'hypervisorproductskutype', 1654 0x22000112 => 'hypervisorproductskutype',
1603 0x25000113 => 'hypervisorrootproc', 1655 0x25000113 => 'hypervisorrootproc',
1604 0x26000114 => 'hypervisordhcp', 1656 0x26000114 => 'hypervisordhcp',
1605 0x25000115 => 'hypervisoriommupolicy', 1657 0x25000115 => 'hypervisoriommupolicy',
1606 0x26000116 => 'hypervisorusevapic', 1658 0x26000116 => 'hypervisorusevapic',
1607 0x22000117 => 'hypervisorloadoptions', 1659 0x22000117 => 'hypervisorloadoptions',
1608 0x25000118 => 'hypervisormsrfilterpolicy', 1660 0x25000118 => 'hypervisormsrfilterpolicy',
1609 0x25000119 => 'hypervisormmionxpolicy', 1661 0x25000119 => 'hypervisormmionxpolicy',
1610 0x2500011a => 'hypervisorschedulertype', 1662 0x2500011a => 'hypervisorschedulertype',
1611 0x25000120 => 'xsavepolicy', 1663 0x25000120 => 'xsavepolicy',
1612 0x25000121 => 'xsaveaddfeature0', 1664 0x25000121 => 'xsaveaddfeature0',
1613 0x25000122 => 'xsaveaddfeature1', 1665 0x25000122 => 'xsaveaddfeature1',
1614 0x25000123 => 'xsaveaddfeature2', 1666 0x25000123 => 'xsaveaddfeature2',
1615 0x25000124 => 'xsaveaddfeature3', 1667 0x25000124 => 'xsaveaddfeature3',
1616 0x25000125 => 'xsaveaddfeature4', 1668 0x25000125 => 'xsaveaddfeature4',
1617 0x25000126 => 'xsaveaddfeature5', 1669 0x25000126 => 'xsaveaddfeature5',
1618 0x25000127 => 'xsaveaddfeature6', 1670 0x25000127 => 'xsaveaddfeature6',
1619 0x25000128 => 'xsaveaddfeature7', 1671 0x25000128 => 'xsaveaddfeature7',
1620 0x25000129 => 'xsaveremovefeature', 1672 0x25000129 => 'xsaveremovefeature',
1621 0x2500012a => 'xsaveprocessorsmask', 1673 0x2500012a => 'xsaveprocessorsmask',
1622 0x2500012b => 'xsavedisable', 1674 0x2500012b => 'xsavedisable',
1623 0x2500012c => 'kerneldebugtype', 1675 0x2500012c => 'kerneldebugtype',
1624 0x2200012d => 'kernelbusparams', 1676 0x2200012d => 'kernelbusparams',
1625 0x2500012e => 'kerneldebugaddress', 1677 0x2500012e => 'kerneldebugaddress',
1626 0x2500012f => 'kerneldebugport', 1678 0x2500012f => 'kerneldebugport',
1627 0x25000130 => 'claimedtpmcounter', 1679 0x25000130 => 'claimedtpmcounter',
1628 0x25000131 => 'kernelchannel', 1680 0x25000131 => 'kernelchannel',
1629 0x22000132 => 'kerneltargetname', 1681 0x22000132 => 'kerneltargetname',
1630 0x25000133 => 'kernelhostip', 1682 0x25000133 => 'kernelhostip',
1631 0x25000134 => 'kernelport', 1683 0x25000134 => 'kernelport',
1632 0x26000135 => 'kerneldhcp', 1684 0x26000135 => 'kerneldhcp',
1633 0x22000136 => 'kernelkey', 1685 0x22000136 => 'kernelkey',
1634 0x22000137 => 'imchivename', 1686 0x22000137 => 'imchivename',
1635 0x21000138 => 'imcdevice', 1687 0x21000138 => 'imcdevice',
1636 0x25000139 => 'kernelbaudrate', 1688 0x25000139 => 'kernelbaudrate',
1637 0x22000140 => 'mfgmode', 1689 0x22000140 => 'mfgmode',
1638 0x26000141 => 'event', 1690 0x26000141 => 'event',
1639 0x25000142 => 'vsmlaunchtype', 1691 0x25000142 => 'vsmlaunchtype',
1640 0x25000144 => 'hypervisorenforcedcodeintegrity', 1692 0x25000144 => 'hypervisorenforcedcodeintegrity',
1641 0x26000145 => 'enablebootdebugpolicy',
1642 0x26000146 => 'enablebootorderclean',
1643 0x26000147 => 'enabledeviceid',
1644 0x26000148 => 'enableffuloader',
1645 0x26000149 => 'enableiuloader',
1646 0x2600014a => 'enablemassstorage',
1647 0x2600014b => 'enablerpmbprovisioning',
1648 0x2600014c => 'enablesecurebootpolicy',
1649 0x2600014d => 'enablestartcharge',
1650 0x2600014e => 'enableresettpm',
1651 0x21000150 => 'systemdatadevice', 1693 0x21000150 => 'systemdatadevice',
1652 0x21000151 => 'osarcdevice', 1694 0x21000151 => 'osarcdevice',
1653 0x21000153 => 'osdatadevice', 1695 0x21000153 => 'osdatadevice',
1654 0x21000154 => 'bspdevice', 1696 0x21000154 => 'bspdevice',
1655 0x21000155 => 'bspfilepath', 1697 0x21000155 => 'bspfilepath',
1656 0x26000202 => 'skipffumode', 1698 },
1657 0x26000203 => 'forceffumode', 1699 resume => {
1658 0x25000510 => 'chargethreshold', 1700 0x21000001 => 'filedevice',
1659 0x26000512 => 'offmodecharging', 1701 0x22000002 => 'filepath',
1660 0x25000aaa => 'bootflow', 1702 0x26000003 => 'customsettings',
1661 0x35000001 => 'ramdiskimageoffset', 1703 0x26000004 => 'pae',
1662 0x35000002 => 'ramdisktftpclientport', 1704 0x21000005 => 'associatedosdevice',
1663 0x31000003 => 'ramdisksdidevice', 1705 0x26000006 => 'debugoptionenabled',
1664 0x32000004 => 'ramdisksdipath', 1706 0x25000007 => 'bootux',
1665 0x35000005 => 'ramdiskimagelength', 1707 0x25000008 => 'bootmenupolicy',
1666 0x36000006 => 'exportascd', 1708 0x26000024 => 'hormenabled',
1667 0x35000007 => 'ramdisktftpblocksize', 1709 },
1668 0x35000008 => 'ramdisktftpwindowsize', 1710 startup => {
1669 0x36000009 => 'ramdiskmcenabled', 1711 0x26000001 => 'pxesoftreboot',
1670 0x3600000a => 'ramdiskmctftpfallback', 1712 0x22000002 => 'applicationname',
1671 0x3600000b => 'ramdisktftpvarwindow', 1713 },
1672 0x45000001 => 'devicetype',
1673 0x42000002 => 'applicationrelativepath',
1674 0x42000003 => 'ramdiskdevicerelativepath',
1675 0x46000004 => 'omitosloaderelements',
1676 0x47000006 => 'elementstomigrate',
1677 0x46000010 => 'recoveryos',
1678); 1714);
1679 1715
1680our %rbcde = reverse %bcde; 1716# mask, value => class
1717our @bcde_typeclass = (
1718 [0x00000000, 0x00000000, 'any'],
1719 [0xf00fffff, 0x1000000a, 'bootapp'],
1720 [0xf0ffffff, 0x2020000a, 'bootapp'],
1721 [0xf00fffff, 0x10000001, 'bootmgr'],
1722 [0xf00fffff, 0x10000002, 'bootmgr'],
1723 [0xf0ffffff, 0x20200001, 'bootmgr'],
1724 [0xf0ffffff, 0x20200002, 'bootmgr'],
1725 [0xf0f00000, 0x20300000, 'device'],
1726 [0xf0000000, 0x30000000, 'device'],
1727 [0xf00fffff, 0x10000005, 'memdiag'],
1728 [0xf0ffffff, 0x20200005, 'memdiag'],
1729 [0xf00fffff, 0x10000006, 'ntldr'],
1730 [0xf00fffff, 0x10000007, 'ntldr'],
1731 [0xf0ffffff, 0x20200006, 'ntldr'],
1732 [0xf0ffffff, 0x20200007, 'ntldr'],
1733 [0xf00fffff, 0x10000003, 'osloader'],
1734 [0xf0ffffff, 0x20200003, 'osloader'],
1735 [0xf00fffff, 0x10000004, 'resume'],
1736 [0xf0ffffff, 0x20200004, 'resume'],
1737 [0xf00fffff, 0x10000009, 'startup'],
1738 [0xf0ffffff, 0x20200009, 'startup'],
1739);
1681 1740
1741our %rbcde_byclass;
1742
1743while (my ($k, $v) = each %bcde_byclass) {
1744 $rbcde_byclass{$k} = { reverse %$v };
1745}
1746
1747# decodes (numerical elem, type) to name
1682sub dec_bcde_id($) { 1748sub dec_bcde_id($$) {
1749 for my $class (@bcde_typeclass) {
1750 if (($_[1] & $class->[0]) == $class->[1]) {
1751 if (my $id = $bcde_byclass{$class->[2]}{$_[0]}) {
1752 return $id;
1753 }
1754 }
1755 }
1756
1683 $bcde{$_[0]} // sprintf "custom:%08x", $_[0] 1757 sprintf "custom:%08x", $_[0]
1684} 1758}
1685 1759
1760# encodes (elem as name, type)
1686sub enc_bcde_id($) { 1761sub enc_bcde_id($$) {
1687 $_[0] =~ /^custom:([0-9a-fA-F]{8}$)/ 1762 $_[0] =~ /^custom:(?:0x)?([0-9a-fA-F]{8}$)/
1688 ? hex $1 1763 and return hex $1;
1689 : $rbcde{$_[0]} 1764
1765 for my $class (@bcde_typeclass) {
1766 if (($_[1] & $class->[0]) == $class->[1]) {
1767 if (my $value = $rbcde_byclass{$class->[2]}{$_[0]}) {
1768 return $value;
1769 }
1770 }
1771 }
1772
1773 undef
1690} 1774}
1691 1775
1692# decode/encode bcd device element - the horror, no documentaion 1776# decode/encode bcd device element - the horror, no documentaion
1693# whatsoever, supercomplex, superinconsistent. 1777# whatsoever, supercomplex, superinconsistent.
1694 1778
1698 1782
1699our $NULL_DEVICE = "\x00" x 16; 1783our $NULL_DEVICE = "\x00" x 16;
1700 1784
1701# biggest bitch to decode, ever 1785# biggest bitch to decode, ever
1702# this decoded a device portion after the GUID 1786# this decoded a device portion after the GUID
1703sub dec_device_($); 1787sub dec_device_($$);
1704sub dec_device_($) { 1788sub dec_device_($$) {
1705 my ($device) = @_; 1789 my ($device, $type) = @_;
1706 1790
1707 my $res; 1791 my $res;
1708 1792
1709 my ($type, $flags, $length, $pad) = unpack "VVVV", substr $device, 0, 4 * 4, ""; 1793 my ($type, $flags, $length, $pad) = unpack "VVVV", substr $device, 0, 4 * 4, "";
1710 1794
1755 1839
1756 my $partid = $parttype eq "gpt" ? dec_guid $partdata 1840 my $partid = $parttype eq "gpt" ? dec_guid $partdata
1757 : $type eq "partition" ? unpack "Q<", $partdata # byte offset to partition start 1841 : $type eq "partition" ? unpack "Q<", $partdata # byte offset to partition start
1758 : unpack "L<", $partdata; # partition number, one-based 1842 : unpack "L<", $partdata; # partition number, one-based
1759 1843
1760 (my $parent, $device) = dec_device_ $device; 1844 (my $parent, $device) = dec_device_ $device, $type;
1761 1845
1762 $res .= "="; 1846 $res .= "=";
1763 $res .= "<$parent>"; 1847 $res .= "<$parent>";
1764 $res .= ",$blocktype,$parttype,$diskid,$partid"; 1848 $res .= ",$blocktype,$parttype,$diskid,$partid";
1765 1849
1785 or die "unsupported file descriptor version '$fver'\n"; 1869 or die "unsupported file descriptor version '$fver'\n";
1786 1870
1787 $ftype == 5 1871 $ftype == 5
1788 or die "unsupported file descriptor path type '$type'\n"; 1872 or die "unsupported file descriptor path type '$type'\n";
1789 1873
1790 (my $parent, $path) = dec_device_ $path; 1874 (my $parent, $path) = dec_device_ $path, $type;
1791 1875
1792 $path = $dec_path->($path, "file device without path"); 1876 $path = $dec_path->($path, "file device without path");
1793 1877
1794 ($parent, $path) 1878 ($parent, $path)
1795 }; 1879 };
1801 1885
1802 } elsif ($blocktype eq "vhd") { 1886 } elsif ($blocktype eq "vhd") {
1803 $device =~ s/^\x00{20}//s 1887 $device =~ s/^\x00{20}//s
1804 or die "virtualdisk has non-zero fields I don't understand\n"; 1888 or die "virtualdisk has non-zero fields I don't understand\n";
1805 1889
1806 (my $parent, $device) = dec_device_ $device; 1890 (my $parent, $device) = dec_device_ $device, $type;
1807 1891
1808 $res .= "=vhd,<$parent>"; 1892 $res .= "=vhd,<$parent>";
1809 1893
1810 } elsif ($blocktype eq "ramdisk") { 1894 } elsif ($blocktype eq "ramdisk") {
1811 my ($base, $size, $offset) = unpack "Q< Q< L<", substr $device, 0, 8 + 8 + 4, ""; 1895 my ($base, $size, $offset) = unpack "Q< Q< L<", substr $device, 0, 8 + 8 + 4, "";
1824 my ($mode, $elem, $parent) = unpack "VVV", substr $device, 0, 4 * 3, ""; 1908 my ($mode, $elem, $parent) = unpack "VVV", substr $device, 0, 4 * 3, "";
1825 1909
1826 if ($parent) { 1910 if ($parent) {
1827 # not sure why this is an offset - it must come after the path 1911 # not sure why this is an offset - it must come after the path
1828 $parent = substr $device, $parent - 4 * 3 - 4 * 4, 1e9, ""; 1912 $parent = substr $device, $parent - 4 * 3 - 4 * 4, 1e9, "";
1829 ($parent, my $tail) = dec_device_ $parent; 1913 ($parent, my $tail) = dec_device_ $parent, $type;
1830 0 == length $tail 1914 0 == length $tail
1831 or die "trailing data after locate device parent\n"; 1915 or die "trailing data after locate device parent\n";
1832 } else { 1916 } else {
1833 $parent = "null"; 1917 $parent = "null";
1834 } 1918 }
1840 1924
1841 if ($mode == 0) { # "Element" 1925 if ($mode == 0) { # "Element"
1842 !length $path 1926 !length $path
1843 or die "device locate mode 0 having non-empty path ($mode, $elem, $path)\n"; 1927 or die "device locate mode 0 having non-empty path ($mode, $elem, $path)\n";
1844 1928
1845 $elem = dec_bcde_id $elem; 1929 $elem = dec_bcde_id $elem, $type;
1846 $res .= "element,$elem"; 1930 $res .= "element,$elem";
1847 1931
1848 } elsif ($mode == 1) { # "String" 1932 } elsif ($mode == 1) { # "String"
1849 !$elem 1933 !$elem
1850 or die "device locate mode 1 having non-zero element\n"; 1934 or die "device locate mode 1 having non-zero element\n";
1875 1959
1876 ($res, $tail) 1960 ($res, $tail)
1877} 1961}
1878 1962
1879# decode a full binary BCD device descriptor 1963# decode a full binary BCD device descriptor
1880sub dec_device($) { 1964sub dec_device($$) {
1881 my ($device) = @_; 1965 my ($device, $type) = @_;
1882 1966
1883 $device = pack "H*", $device; 1967 $device = pack "H*", $device;
1884 1968
1885 my $guid = dec_guid substr $device, 0, 16, ""; 1969 my $guid = dec_guid substr $device, 0, 16, "";
1886 $guid = $guid eq "00000000-0000-0000-0000-000000000000" 1970 $guid = $guid eq "00000000-0000-0000-0000-000000000000"
1887 ? "" : "{$guid}"; 1971 ? "" : "{$guid}";
1888 1972
1889 eval { 1973 eval {
1890 my ($dev, $tail) = dec_device_ $device; 1974 my ($dev, $tail) = dec_device_ $device, $type;
1891 1975
1892 $tail eq "" 1976 $tail eq ""
1893 or die "unsupported trailing data after device descriptor\n"; 1977 or die "unsupported trailing data after device descriptor\n";
1894 1978
1895 "$guid$dev" 1979 "$guid$dev"
1907 1991
1908 undef 1992 undef
1909} 1993}
1910 1994
1911# encode the device portion after the GUID 1995# encode the device portion after the GUID
1912sub enc_device_; 1996sub enc_device_($$);
1913sub enc_device_ { 1997sub enc_device_($$) {
1914 my ($device) = @_; 1998 my ($device, $type) = @_;
1915 1999
1916 my $enc_path = sub { 2000 my $enc_path = sub {
1917 my $path = shift; 2001 my $path = shift;
1918 $path =~ s/\//\\/g; 2002 $path =~ s/\//\\/g;
1919 (Encode::encode "UTF-16LE", $path) . "\x00\x00" 2003 (Encode::encode "UTF-16LE", $path) . "\x00\x00"
1937 2021
1938 my $parse_parent = sub { 2022 my $parse_parent = sub {
1939 my $parent; 2023 my $parent;
1940 2024
1941 if (s/^<//) { 2025 if (s/^<//) {
1942 ($parent, $_) = enc_device_ $_; 2026 ($parent, $_) = enc_device_ $_, $type;
1943 s/^>// 2027 s/^>//
1944 or die "$device: syntax error: parent device not followed by '>'\n"; 2028 or die "$device: syntax error: parent device not followed by '>'\n";
1945 } else { 2029 } else {
1946 $parent = $NULL_DEVICE; 2030 $parent = $NULL_DEVICE;
1947 } 2031 }
2035 2119
2036 s/^,// 2120 s/^,//
2037 or die "$_: missing comma after locate parent device\n"; 2121 or die "$_: missing comma after locate parent device\n";
2038 2122
2039 if (s/^element,//) { 2123 if (s/^element,//) {
2040 s/^([0-9a-z]+)//i 2124 s/^([0-9a-z:]+)//i
2041 or die "$_ locate element must be either name or 8-digit hex id\n"; 2125 or die "$_ locate element must be either name or 8-digit hex id\n";
2042 $elem = enc_bcde_id $1; 2126 $elem = enc_bcde_id $1, $type;
2043 $mode = 0; 2127 $mode = 0;
2044 $path = $enc_path->(""); 2128 $path = $enc_path->("");
2045 2129
2046 } elsif (s/^path,//) { 2130 } elsif (s/^path,//) {
2047 $mode = 1; 2131 $mode = 1;
2126 ); 2210 );
2127 } 2211 }
2128} 2212}
2129 2213
2130# encode a full binary BCD device descriptor 2214# encode a full binary BCD device descriptor
2131sub enc_device { 2215sub enc_device($$) {
2132 my ($device) = @_; 2216 my ($device, $type) = @_;
2133 2217
2134 my $guid = "\x00" x 16; 2218 my $guid = "\x00" x 16;
2135 2219
2136 if ($device =~ s/^\{([A-Za-z0-9\-]+)\}//) { 2220 if ($device =~ s/^\{([A-Za-z0-9\-]+)\}//) {
2137 $guid = enc_guid $1 2221 $guid = enc_guid $1
2138 or die "$device: does not start with valid guid\n"; 2222 or die "$device: does not start with valid guid\n";
2139 } 2223 }
2140 2224
2141 my ($descriptor, $tail) = enc_device_ $device; 2225 my ($descriptor, $tail) = enc_device_ $device, $type;
2142 2226
2143 length $tail 2227 length $tail
2144 and die "$device: garbage after device descriptor\n"; 2228 and die "$device: garbage after device descriptor\n";
2145 2229
2146 unpack "H*", $guid . $descriptor 2230 unpack "H*", $guid . $descriptor
2161 $k = $bcd_objects{$k} // $k; 2245 $k = $bcd_objects{$k} // $k;
2162 2246
2163 my $type = $v->{Description}[0]{Type}[1]; 2247 my $type = $v->{Description}[0]{Type}[1];
2164 2248
2165 if ($type != $bcd_object_types{$k}) { 2249 if ($type != $bcd_object_types{$k}) {
2166 $type = $bcd_types{$type} // sprintf "0x%08x", $type; 2250 $kv{type} = $bcd_types{$type} // sprintf "0x%08x", $type;
2167 $kv{type} = $type;
2168 } 2251 }
2169 2252
2170 my $elems = $v->{Elements}[1]; 2253 my $elems = $v->{Elements}[1];
2171 2254
2172 while (my ($k, $v) = each %$elems) { 2255 while (my ($k, $v) = each %$elems) {
2173 my $k = hex $k; 2256 my $k = hex $k;
2174 2257
2175 my $v = $bcde_dec{$k & BCDE_FORMAT}->($v->[0]{Element}[1]); 2258 my $v = $bcde_dec{$k & BCDE_FORMAT}->($v->[0]{Element}[1], $type);
2176 my $k = dec_bcde_id $k; 2259 my $k = dec_bcde_id $k, $type;
2177 2260
2178 $kv{$k} = $v; 2261 $kv{$k} = $v;
2179 } 2262 }
2180 2263
2181 $bcd{$k} = \%kv; 2264 $bcd{$k} = \%kv;
2222 my %elem; 2305 my %elem;
2223 2306
2224 while (my ($k, $v) = each %$v) { 2307 while (my ($k, $v) = each %$v) {
2225 next if $k eq "type"; 2308 next if $k eq "type";
2226 2309
2227 $k = (enc_bcde_id $k) // die "$k: invalid bcde element name or id\n"; 2310 $k = (enc_bcde_id $k, $type) // die "$k: invalid bcde element name or id\n";
2228 $elem{sprintf "%08x", $k} = [{ 2311 $elem{sprintf "%08x", $k} = [{
2229 Element => [ ($bcde_enc{$k & BCDE_FORMAT} // die "$k: unable to encode unknown bcd element type}")->($v)] 2312 Element => [ ($bcde_enc{$k & BCDE_FORMAT} // die "$k: unable to encode unknown bcd element type}")->($v)]
2230 }]; 2313 }];
2231 } 2314 }
2232 2315
2355 2438
2356 print "\n"; 2439 print "\n";
2357 2440
2358 printf "%-39s %-23s %s\n", "Object GUID", "Alias", "(Hex) Default Type"; 2441 printf "%-39s %-23s %s\n", "Object GUID", "Alias", "(Hex) Default Type";
2359 for my $name (sort keys %rbcd_objects) { 2442 for my $name (sort keys %rbcd_objects) {
2360 my $guid = $rbcd_objects{$name}; 2443 my $guid = $rbcd_objects{$name};
2361 my $type = $bcd_object_types{$name}; 2444 my $type = $bcd_object_types{$name};
2362 my $tname = $bcd_types{$type}; 2445 my $tname = $bcd_types{$type};
2363 2446
2364 $type = $type ? sprintf "(%08x) %s", $type, $tname : "-"; 2447 $type = $type ? sprintf "(%08x) %s", $type, $tname : "-";
2365 2448
2366 printf "%-39s %-23s %s\n", $guid, $name, $type; 2449 printf "%-39s %-23s %s\n", $guid, $name, $type;
2380 BCDE_FORMAT_GUID_LIST , "guid list", 2463 BCDE_FORMAT_GUID_LIST , "guid list",
2381 BCDE_FORMAT_INTEGER , "integer", 2464 BCDE_FORMAT_INTEGER , "integer",
2382 BCDE_FORMAT_BOOLEAN , "boolean", 2465 BCDE_FORMAT_BOOLEAN , "boolean",
2383 BCDE_FORMAT_INTEGER_LIST, "integer list", 2466 BCDE_FORMAT_INTEGER_LIST, "integer list",
2384 ); 2467 );
2385 my %rbcde = reverse %bcde;
2386 $_ = sprintf "%08x", $_ for values %rbcde;
2387 2468
2388 my %element; 2469 my %element;
2389 2470
2471 for my $class (sort keys %rbcde_byclass) {
2472 my $rbcde = $rbcde_byclass{$class};
2473
2390 unless ($json) { 2474 unless ($json) {
2391 print "\n"; 2475 print "\n";
2476 printf "Elements applicable to class(es): $class\n";
2392 printf "%-9s %-12s %s\n", "Element", "Format", "Name Alias"; 2477 printf "%-9s %-12s %s\n", "Element", "Format", "Name Alias";
2393 } 2478 }
2394 for my $name (sort keys %rbcde) { 2479 for my $name (sort keys %$rbcde) {
2395 my $id = $rbcde{$name}; 2480 my $id = $rbcde->{$name};
2396 my $format = $format_name{(hex $id) & BCDE_FORMAT}; 2481 my $format = $format_name{$id & BCDE_FORMAT};
2482 $id = sprintf "%08x", $id;
2397 2483
2398 if ($json) { 2484 if ($json) {
2399 $element{$id} = [$format, $name]; 2485 $element{$id} = [$class, $format, $name];
2400 } else { 2486 } else {
2401 printf "%-9s %-12s %s\n", $id, $format, $name; 2487 printf "%-9s %-12s %s\n", $id, $format, $name;
2488 }
2402 } 2489 }
2403 } 2490 }
2404 print "\n" unless $json; 2491 print "\n" unless $json;
2405 2492
2406 prjson { 2493 prjson {
2407 version => $JSON_VERSION, 2494 version => $JSON_VERSION,
2408 element => \%element, 2495 element => \%element,
2496 class => \@bcde_typeclass,
2409 } if $json; 2497 } if $json;
2410 2498
2411 }, 2499 },
2412 2500
2413 export => sub { 2501 export => sub {
2465 } 2553 }
2466 } 2554 }
2467 } 2555 }
2468 } 2556 }
2469 }, 2557 },
2558
2559 version => sub {
2560 print "\n",
2561 "PBCDEDIT version $VERSION, copyright 2019 Marc A. Lehmann <pbcdedit\@schmorp.de>.\n",
2562 "JSON schema version: $JSON_VERSION\n",
2563 "Licensed under the GNU General Public License Version 3.0, or any later version.\n",
2564 "\n",
2565 $CHANGELOG,
2566 "\n";
2567 },
2470); 2568);
2471 2569
2472my $cmd = shift; 2570my $cmd = shift;
2473 2571
2474unless (exists $CMD{$cmd}) { 2572unless (exists $CMD{$cmd}) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines