sl@0: # Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: # All rights reserved. sl@0: # This component and the accompanying materials are made available sl@0: # under the terms of "Eclipse Public License v1.0" sl@0: # which accompanies this distribution, and is available sl@0: # at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: # sl@0: # Initial Contributors: sl@0: # Nokia Corporation - initial contribution. sl@0: # sl@0: # Contributors: sl@0: # sl@0: # Description: sl@0: # Feature Registry Configuration File Lister/Checker sl@0: # sl@0: # sl@0: sl@0: use strict; sl@0: sl@0: # Usage help text sl@0: my $usage = "Feature Registry Configuration File Lister/Checker\n" . sl@0: "Copyright (c) 2005 Symbian Software Ltd. All rights reserved\n\n" . sl@0: "Usage: perl $0 BINCONFIGFILE\n\n" . sl@0: "Returns 0 if config file is valid, non-zero and reasons otherwise\n"; sl@0: sl@0: # Process command line sl@0: if (1 != scalar(@ARGV)) sl@0: { sl@0: print $usage; sl@0: exit 1; sl@0: } sl@0: my $binConfigFile = $ARGV[0]; sl@0: sl@0: # open config file in binary mode sl@0: my $BINCONFIG; sl@0: if (!open ($BINCONFIG, $binConfigFile)) sl@0: { sl@0: print "ERROR: Binary config file is missing or cannot be opened"; sl@0: exit 1; sl@0: } sl@0: binmode $BINCONFIG; sl@0: sl@0: # Check file size sl@0: my ($dev, $ino, $mode, $nlink, $_uid, $_gid, $redv, $size, $atime, $mtime, $ctime, $blksize, $blocks) sl@0: = stat $BINCONFIG; sl@0: my $headerSize = 16; sl@0: if ($size < $headerSize) sl@0: { sl@0: print "INVALID Feature Registry Config File: file is too small, must have at least 16 byte header"; sl@0: exit 1; sl@0: } sl@0: my $KMaxLargePropertySize = 65535; sl@0: if ($size > $KMaxLargePropertySize) sl@0: { sl@0: print "INVALID Feature Registry Config File: File is larger than limit of 65535 bytes"; sl@0: exit 1; sl@0: } sl@0: if ($size > 4096) # arbitrarily chosen; it may be sensible to change the way featreg works if config files become this big sl@0: { sl@0: print "WARNING: Large Feature Registry config file (", $ARGV[0], "); something may be wrong\n"; sl@0: } sl@0: sl@0: # Read and check header sl@0: my $packedHeader; sl@0: if (!read($BINCONFIG, $packedHeader, $headerSize) || sl@0: (length $packedHeader < 16)) sl@0: { sl@0: print "INVALID Feature Registry Config File: Could not read 16-byte header"; sl@0: exit 1; sl@0: } sl@0: my ($feat, $version, $entryCount, $rangeCount) = unpack 'a4I3', $packedHeader; sl@0: if ($feat ne 'feat') sl@0: { sl@0: print "INVALID Feature Registry Config File: First 4 bytes of header must be ASCII 'f' 'e' 'a' 't'"; sl@0: exit 1; sl@0: } sl@0: if ($version != 0) sl@0: { sl@0: print "INVALID Feature Registry Config File: Second 32-bit word in header (version/flags) must be zero"; sl@0: exit 1; sl@0: } sl@0: my $entrySize = 8; sl@0: my $rangeSize = 8; sl@0: my $expectedSize = $headerSize + $entryCount*$entrySize + $rangeCount*$rangeSize; sl@0: if ($expectedSize != $size) sl@0: { sl@0: print "INVALID Feature Registry Config File: Size of file ($size bytes) does not match size expected from header" . sl@0: " ($expectedSize bytes) for $entryCount feature entries and $rangeCount default ranges"; sl@0: exit 1; sl@0: } sl@0: sl@0: # Write information from the header: sl@0: print "Feature Registry Configuration file '$binConfigFile'\n"; sl@0: print "Contains $entryCount feature entries and $rangeCount default ranges\n"; sl@0: sl@0: print "---\n"; sl@0: sl@0: # Check individual feature entries are listed by increasing (and non-repeating) UID, and write them to STDOUT sl@0: my $lastFeatureUid = 0; sl@0: for (my $e = 0; $e < $entryCount; $e++) sl@0: { sl@0: my $packedEntry; sl@0: if (!read($BINCONFIG, $packedEntry, $entrySize) || sl@0: (length $packedEntry < $entrySize)) sl@0: { sl@0: print "INVALID Feature Registry Config File: Unable to read feature entry $e"; sl@0: exit 1; sl@0: } sl@0: my ($featureUid, $status) = unpack 'I2', $packedEntry; sl@0: printf "Feature UID 0x%08X, status = 0x%08X (%s)\n", $featureUid, $status, ($status & 1) ? 'supported' : 'not supported'; sl@0: if (($e > 0) && ($featureUid <= $lastFeatureUid)) sl@0: { sl@0: print "INVALID Feature Registry Config File: Feature entries not listed by increasing (and non-repeating) UID"; sl@0: exit 1; sl@0: } sl@0: if ($status & ~3) sl@0: { sl@0: print "WARNING Feature Registry Config File: Feature entry status bits 2-31 should be zero\n"; sl@0: } sl@0: $lastFeatureUid = $featureUid; sl@0: } sl@0: sl@0: print "---\n"; sl@0: sl@0: # Check default supported ranges are in low-UID / high-UID pairs sl@0: # AND that the Symbian Essential default range is covered: sl@0: my $EssentialDefaultSupportedRangeLowUid = 271030278; sl@0: my $EssentialDefaultSupportedRangeHighUid = 271063045; sl@0: if (($EssentialDefaultSupportedRangeLowUid != 0x10279806) || sl@0: ($EssentialDefaultSupportedRangeHighUid != 0x10281805)) sl@0: { sl@0: print "ERROR Mismatch on Feature Registry Symbian essential default-supported range"; sl@0: exit 1; sl@0: } sl@0: my $haveEssentialRange; sl@0: for (my $r = 0; $r < $rangeCount; $r++) sl@0: { sl@0: my $packedRange; sl@0: if (!read($BINCONFIG, $packedRange, $entrySize) || sl@0: (length $packedRange < $rangeSize)) sl@0: { sl@0: print "INVALID Feature Registry Config File: Unable to read default-supported range $r"; sl@0: exit 1; sl@0: } sl@0: my ($lowUid, $highUid) = unpack 'I2', $packedRange; sl@0: printf "Feature UID range 0x%08X to 0x%08X supported by default\n", $lowUid, $highUid; sl@0: if (($lowUid <= $EssentialDefaultSupportedRangeLowUid) && sl@0: ($highUid >= $EssentialDefaultSupportedRangeHighUid)) sl@0: { sl@0: $haveEssentialRange = 1; sl@0: } sl@0: if ($lowUid > $highUid) sl@0: { sl@0: print "INVALID Feature Registry Config File: Default-supported range is not listed in order Low-UID High-Uid"; sl@0: exit 1; sl@0: } sl@0: } sl@0: sl@0: if (!$haveEssentialRange) sl@0: { sl@0: printf "INVALID Feature Registry Config File: Symbian essential default-supported UID range 0x%08X to 0x%08X is not present\n", sl@0: $EssentialDefaultSupportedRangeLowUid, $EssentialDefaultSupportedRangeHighUid; sl@0: exit 1; sl@0: } sl@0: sl@0: # Confirm there's nothing more to read sl@0: my $junk; sl@0: if (read $BINCONFIG, $junk, 1) sl@0: { sl@0: printf "INVALID Feature Registry Config File: Unexpected data at end of binary configuration file"; sl@0: exit 1; sl@0: } sl@0: sl@0: # Warn if the filename is not 'featreg.cfg' (case insensitive) sl@0: if ($binConfigFile !~ m/[Ff][Ee][Aa][Tt][Rr][Ee][Gg]\.[Cc][Ff][Gg]$/) sl@0: { sl@0: printf "WARNING Feature Registry Config File must be called 'featreg.cfg'"; sl@0: } sl@0: sl@0: # Success - a valid configuration file (but it's up to you to guarantee the entries and ranges are correct, sl@0: # and to put the file in the correct location sl@0: exit 0;