widgettools/wrtwidgetpreinstaller/src/installwidgets.pl
branchRCL_3
changeset 25 a8ece8c8fac1
child 28 78ea955b5d24
equal deleted inserted replaced
23:cbece5a7b057 25:a8ece8c8fac1
       
     1 #
       
     2 # Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 #
       
    16 
       
    17 use strict;
       
    18 use warnings;
       
    19 use File::Spec::Functions;
       
    20 use Getopt::Long;
       
    21 use Pod::Usage;
       
    22 
       
    23 # Version of the script - just use the date
       
    24 $main::VERSION = '25-May-2010';
       
    25 
       
    26 # New getopt::long provides this - but old version doesn't?
       
    27 sub version
       
    28   {
       
    29   print sprintf("$0: $main::VERSION\n$^X: %vd\nos: $^O", $^V);
       
    30   exit;
       
    31   }
       
    32 
       
    33 # Get arguments
       
    34 my ( $help, $version, $verbose, $debug, $epocroot, $l10n );
       
    35 GetOptions( "help" => \$help, "version|ver" => \$version,
       
    36       "verbose|v" => \$verbose,  "debug" => \$debug,
       
    37       "epocroot|e=s" => \$epocroot, "localization|l=s" => \$l10n )
       
    38   or pod2usage('Invalid parameters');
       
    39 
       
    40 # Handle help and version
       
    41 pod2usage({ verbose => 1, exitval => 0}) if $help;
       
    42 version() if $version;
       
    43 
       
    44 # Interpret arguments
       
    45 $verbose = 1 if $debug;
       
    46 $verbose = $verbose ? '-v' : '';
       
    47 $epocroot = $ENV{EPOCROOT} if !$epocroot;
       
    48 
       
    49 # Interpret localization l10n argument
       
    50 
       
    51 # There are two modes.  In one mode you specify the location of a
       
    52 # lproj.xml file and the code computes l10n files for all languages so
       
    53 # that runtime locale selection should work.  In the other mode you
       
    54 # specify a language code (example, fr for French) and the code
       
    55 # computes l10n just for that language.
       
    56 $l10n = '' if !$l10n;
       
    57 my $lproj = '';
       
    58 if ($l10n =~ /lproj\.xml$/i)
       
    59   {
       
    60   $lproj = $l10n;
       
    61   $l10n = '';
       
    62   }
       
    63 
       
    64 my ($configini, @unnecessary) = @ARGV;
       
    65 
       
    66 if ($configini)
       
    67   {
       
    68   # There shouldn't be any need for any other arguments
       
    69   pod2usage('Unnecessary arguments supplied.') if @unnecessary;
       
    70 
       
    71   # Now do the installation
       
    72   my $installer = WidgetInstaller->new('verbose' => $verbose, 'debug' => $debug, 'epocroot' => $epocroot, 'lproj' => $lproj, 'l10n' => $l10n);
       
    73   $installer->installConfig($configini);
       
    74   }
       
    75 else
       
    76   {
       
    77   pod2usage('Missing config.ini argument.');
       
    78   }
       
    79 
       
    80 # ***
       
    81 # Package for installing Widgets
       
    82 #
       
    83 
       
    84 package WidgetInstaller;
       
    85 
       
    86 use File::Spec::Functions;
       
    87 use File::Path;
       
    88 use File::Basename;
       
    89 use Unicode::String qw(utf8 utf16);
       
    90 use File::Temp qw/tempdir/;
       
    91 use File::Copy;
       
    92 use XML::Parser;
       
    93 use Data::Dumper;
       
    94 use XML::Simple;
       
    95 
       
    96 # CONSTANTS
       
    97 use constant ICON_SIZES => "88,32,24";      # Size of icons to generate in the MBM file
       
    98 #use constant INTERNAL_UID_LOWER => 0x2000DAD2; # Lower UID bound for midlets installed to internal drives and rom
       
    99 #use constant EXTERNAL_UID_LOWER => 0x2000DCC6; # Lower UID bound for midlets installed to removable cards
       
   100 use constant INTERNAL_UID_LOWER_WRT => 0x2000DAD2;  # Lower UID bound for WRT widgets installed to internal drives and rom
       
   101 use constant INTERNAL_UID_LOWER_CWRT => 0x2000DBCC; # Lower UID bound for CWRT widgets installed to internal drives and rom
       
   102 use constant EXTERNAL_UID_LOWER_WRT => 0x2000DCC6;  # Lower UID bound for WRT widgets installed to removable cards
       
   103 use constant EXTERNAL_UID_LOWER_CWRT => 0x2000DDC0; # Lower UID bound for CWRT widgets installed to removable cards
       
   104 use constant WIDGET_UI_UID => 0x10282822;   # UID of the widget app
       
   105 use constant CWRT_WIDGET_UI_UID => 0x200267C0;    # UID of the cwrt widget app
       
   106 use constant SWIDGET_UI_UID => 0x102829A0;	# UID of the securewidget app
       
   107 use constant CWRT_WIDGET_UI_NON_NOKIA_UID => 0x200267D6;    # UID of the cwrt widget app
       
   108 
       
   109 # Folder paths
       
   110 use constant DESTINATION => 'private/10003a3f/import/apps/NonNative/Resource';
       
   111 use constant ROM_DEST => 'epoc32/release/winscw/udeb/Z/';
       
   112 use constant DRIVE_DEST => 'epoc32/winscw/%s';
       
   113 use constant WIDGET_REGISTRY => 'private/10282f06/WidgetEntryStore.xml';
       
   114 use constant CWRT_WIDGET_REGISTRY => 'private/10282f06/CWRTWidgetEntryStore.xml';
       
   115 use constant CWRT_WEBAPP_REGISTRY => 'private/200267D9/webapp_registry.db';
       
   116 use constant CWRT_ACCESS_POLICY_PATH => 'browser_access_policy.xml';
       
   117 use constant WIDGET_NAME => 'en-gb/widget/name';
       
   118 use constant WIDGET_PROCESSUID => 'processUid';
       
   119 use constant WIDGET_ID => 'widget/id';
       
   120 use constant WIDGET_VERSION => 'widget/version';
       
   121 use constant WIDGET_CONTENT => 'widget/content';
       
   122 use constant WIDGET_FEATURE => 'widget/feature/';
       
   123 use constant WIDGET_FEATURE_PARAM => '/param/';
       
   124 use constant WIDGET_ACCESS => 'widget/access/';
       
   125 use constant WIDGET_HEIGHT => 'widget/height';
       
   126 use constant WIDGET_WIDTH => 'widget/width';
       
   127 use constant WIDGET_NOKIA_SHAREDLIB => 'widget/NOKIA:sharedlibrary';
       
   128 use constant WIDGET_NOKIA_SHAREDLIB_FOLDER => 'widget/NOKIA:sharedlibrary/NOKIA:folder';
       
   129 use constant WIDGET_NOKIA_SHAREDLIB_WIDGET => 'widget/NOKIA:sharedlibrary/NOKIA:widget';
       
   130 use constant WIDGET_NOKIA_SHAREDLIB_ICON => 'widget/NOKIA:sharedlibrary/NOKIA:icon';
       
   131 use constant KEY_VALUE_SEPERATOR => ',';
       
   132 use constant KEY_VALUE_PAIR_SEPERATOR => ';';
       
   133 use constant KEY_ATTR_SEPERATOR => ':';
       
   134 
       
   135 our $w3c_widget = 0 ;
       
   136 our $hashval;
       
   137 our $non_nokia_widget = 0;
       
   138 our ($isSharedLibrary, $sharedFolderName ,$isSharedWidget, $isSharedIcon)= (0,'',0,0);
       
   139 our (@staticUidWrtIntList,@staticUidCwrtIntList,@staticUidWrtExtList,@staticUidCwrtExtList) = ({},{},{},{});
       
   140 our $isSecureWidget = 0;
       
   141 
       
   142 # Create a new object
       
   143 sub new
       
   144   {
       
   145   my $invocant = shift;
       
   146   my $self = bless({}, ref $invocant || $invocant);
       
   147 
       
   148   my %args = @_;
       
   149   $self->{'args'} = \%args;
       
   150   $self->{'args'}->{'verbose'} = $self->{'args'}->{'verbose'} ? '-v' : '';
       
   151 
       
   152   $self->{'installedFiles'} = ();
       
   153   $self->{'freeuidwrtint'} = INTERNAL_UID_LOWER_WRT;
       
   154   $self->{'freeuidwrtext'} = EXTERNAL_UID_LOWER_WRT;
       
   155   $self->{'freeuidcwrtint'} = INTERNAL_UID_LOWER_CWRT;
       
   156   $self->{'freeuidcwrtext'} = EXTERNAL_UID_LOWER_CWRT;
       
   157   $self->{'langmapping'} = $self->getLangMapping($self->{'args'}->{'lproj'}) unless $self->{'args'}->{'l10n'};
       
   158   
       
   159   #Check if localisation argument is land number ID; If true, get the lang Name using langmapping file - Widget_lproj.xml 
       
   160   if ($l10n =~ /\d+$/)
       
   161   {
       
   162     print "\nLANG ID given as localisation argument :: $l10n \n";
       
   163     $self->{'langmapping'} = $self->getLangMapping();
       
   164     
       
   165     if($self->{'langmapping'})
       
   166     {
       
   167       # Iterate through all the languages we know about
       
   168       for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++)
       
   169       {
       
   170         my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] );
       
   171         if($l10n == $langid)
       
   172         {
       
   173           print "Setting argument to LangName - $langname \n";
       
   174           $self->{'args'}->{'l10n'} = lc($langname);
       
   175           last;
       
   176         }
       
   177       }
       
   178     }
       
   179   }
       
   180 
       
   181   return $self;
       
   182   }
       
   183   
       
   184 # Gets the language mapping from the Widget_lproj.xml file
       
   185 sub getLangMapping
       
   186   {
       
   187   my ( $self, $lproj ) = @_;
       
   188 
       
   189   # Get the LPROJ file which specifies lang id mappings
       
   190   if (!$lproj)
       
   191     {
       
   192     (my $EPOCROOT = $ENV{EPOCROOT}) =~ s/[\/\\]+$//;
       
   193     $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/winscw/c/private/10282f06/Widget_lproj.xml");
       
   194     $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/winscw/c/private/10282f06/Widget_lproj.xml") if !-e $lproj;
       
   195     $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj;
       
   196     $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj;
       
   197     $lproj = WidgetInstaller::fixFilename("${epocroot}S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj;
       
   198     $lproj = WidgetInstaller::fixFilename("$EPOCROOT/S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj;
       
   199     $lproj = WidgetInstaller::findCmd('Widget_lproj.xml') if !-e $lproj;
       
   200     $lproj = WidgetInstaller::findCmd('internal/Widget_lproj.xml') if !-e $lproj;
       
   201     undef $lproj if !-e $lproj;
       
   202 
       
   203     # Display a warning if localisation can't be performed
       
   204     warn "WARNING: Can't find Widget_lproj.xml - localisation is disabled.\n" if !$lproj;
       
   205     }
       
   206 
       
   207   # Load the mapping file
       
   208   if ($lproj)
       
   209     {
       
   210     die "Can't find $lproj file." if !-e $lproj;
       
   211     print "Localisation support enabled using config: $lproj\n" if $verbose;
       
   212     my $mapping = XMLin($lproj);
       
   213     print "Found ", scalar(@{ $mapping->{'LangID'} }), " language mappings.\n" if $verbose;
       
   214     return $mapping;
       
   215     }
       
   216   }
       
   217 
       
   218 # Install Widgets listed in config file
       
   219 # Format is as follows where "drive-z" specifies widgets for drive z: etc...
       
   220 # Comments are okay - they start with a # character
       
   221 # If the file doesn't exist as given then EPOCROOT is prepended to the filename to try and find it
       
   222 #
       
   223 # You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename
       
   224 # This will set the BlanketPermissionGranted attribute in the registry.
       
   225 # Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated.
       
   226 #
       
   227 # You can specify commands to run before exit after a [run-commands] or [homescreen-processor] 
       
   228 #
       
   229 # [drive-z]
       
   230 # \path\widget1.wgz
       
   231 # widget2.wdgt.zip [HomeScreen]
       
   232 #
       
   233 # [drive-e]
       
   234 # widget3.wgz
       
   235 #
       
   236 # [run-commands]
       
   237 # dostuff.pl
       
   238 #
       
   239 
       
   240 sub installConfig
       
   241   {
       
   242   my ( $self, $file ) = @_;
       
   243   $self->{'installedFiles'} = ();
       
   244 
       
   245   my ( %installData, $sectionName );
       
   246   open CONFIG, $file or die "Failed to open config file $file: $!";
       
   247   
       
   248   # Loop for gathering STATIC UIDs allocated for widgets in config INI file
       
   249   while(my $line = <CONFIG>)
       
   250   {
       
   251     # Ignore comments
       
   252     $line =~ s/\#.*$//;
       
   253     
       
   254     if ($line =~ /^\[([^\]]+)\]/)
       
   255       {
       
   256       $sectionName = lc $1;
       
   257       next;
       
   258       }
       
   259 
       
   260     # Process sections after this point
       
   261     next if !$sectionName;
       
   262     chomp $line;
       
   263 
       
   264     # Have we found a list of widgets?
       
   265     if ($sectionName =~ /^drive-([a-z])/)
       
   266     {
       
   267       my $drive = uc($1);
       
   268       #Assuming Static UID given in ini are within int/ext/wgt/wgz specified ranges
       
   269       # Add Static UID to the respective list
       
   270       if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i)
       
   271       {
       
   272         if ($3)
       
   273         {
       
   274           my $uid = hex($3);
       
   275           
       
   276           if ($drive =~ /^[zcZC]/)
       
   277           {
       
   278             if(($uid >= INTERNAL_UID_LOWER_WRT) && ($uid < INTERNAL_UID_LOWER_CWRT))
       
   279             {
       
   280               push(@staticUidWrtIntList,$uid) ;
       
   281             }
       
   282             else
       
   283             {
       
   284               push(@staticUidCwrtIntList,$uid);
       
   285             }
       
   286           }
       
   287           else
       
   288           {
       
   289             if(($uid >= EXTERNAL_UID_LOWER_WRT) && ($uid < EXTERNAL_UID_LOWER_CWRT))
       
   290             {
       
   291               push(@staticUidWrtExtList,$uid) ;
       
   292             }
       
   293             else
       
   294             {
       
   295               push(@staticUidCwrtExtList,$uid) ;
       
   296             }
       
   297           }
       
   298         }
       
   299       }
       
   300     }
       
   301   }
       
   302   close CONFIG;
       
   303   @staticUidWrtIntList = sort(@staticUidWrtIntList);
       
   304   print "SORTED WRT INTERNAL STATIC UID  @staticUidWrtIntList \n";
       
   305   @staticUidCwrtIntList = sort(@staticUidCwrtIntList);
       
   306   print "SORTED CWRT INTERNAL STATIC UID  @staticUidCwrtIntList \n";
       
   307   @staticUidWrtExtList = sort(@staticUidWrtExtList);
       
   308   print "SORTED WRT EXTERNAL STATIC UID @staticUidWrtExtList \n";
       
   309   @staticUidCwrtExtList = sort(@staticUidCwrtExtList);
       
   310   print "SORTED CWRT EXTERNAL STATIC UID @staticUidCwrtExtList \n";
       
   311   
       
   312   open CONFIG, $file or die "Failed to open config file $file: $!";
       
   313   # Main loop which reads the config INI line by line and installs widgets[wgz/wgt] in respective drives
       
   314   while(my $line = <CONFIG>)
       
   315     {
       
   316     # Ignore comments
       
   317     $line =~ s/\#.*$//;
       
   318 
       
   319     if ($line =~ /^\[([^\]]+)\]/)
       
   320       {
       
   321       $sectionName = lc $1;
       
   322       
       
   323       # Remember destination if any specified
       
   324       if ($sectionName =~ /^drive-([a-z])=(.+)$/)
       
   325         {
       
   326         $self->{'destination'}->{uc($1)} = $2;
       
   327         }
       
   328       next;
       
   329       }
       
   330 
       
   331     # Process sections after this point
       
   332     next if !$sectionName;
       
   333     chomp $line;
       
   334 
       
   335     # Have we found a list of widgets?
       
   336     if ($sectionName =~ /^drive-([a-z])/)
       
   337       {
       
   338       my $drive = uc($1);
       
   339       
       
   340       # Add to the list of Widget files
       
   341       if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i)
       
   342         {
       
   343         my $widget = $1;
       
   344         $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget;
       
   345         die "Can't find widget $widget" if !-e $widget;
       
   346         $self->{'homescreen'}{lc $widget} = 1 if $2; # Intended for the homescreen?
       
   347         $self->{'staticUID'}{lc $widget} = hex($3) if $3;
       
   348         $self->{'secure'}{lc $widget} = 0;
       
   349         $self->{'operator'}{lc $widget} = 1 if $4;
       
   350         print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'};
       
   351         push @{ $installData{"$drive:"} }, $widget;
       
   352         }
       
   353       elsif ($line =~ /^(.+?\.(?:wdgt\.zip|wgz))\s*(\[Secure\])?\s*(0x[a-fA-F0-9]{8})?\s*$/i)
       
   354         {
       
   355           my $widget = $1;
       
   356           $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget;
       
   357           die "Can't find widget $widget" if !-e $widget;
       
   358           $self->{'secure'}{lc $widget} = 1 if $2; # Intended for a secure widget handling?
       
   359           $self->{'staticUID'}{lc $widget} = hex($3) if $3;
       
   360           print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'};
       
   361           push @{ $installData{"$drive:"} }, $widget;
       
   362         }
       
   363       else
       
   364       	{
       
   365       		my $widget = $1;
       
   366       		$self->{'secure'}{lc $widget} = 0;
       
   367         }	
       
   368       }
       
   369     # Retrieve the command to execute before exit
       
   370     elsif ($sectionName =~ /^(run-commands|homescreen-processor)$/i && $line)
       
   371       {
       
   372       push @{ $self->{'exitcmds'} }, $line;
       
   373       }
       
   374     }
       
   375   close CONFIG;
       
   376 
       
   377   # Now intall the widgets for each drive specified in the config file
       
   378   foreach my $drive ( keys %installData )
       
   379     {
       
   380     $self->installFiles($drive, $installData{$drive} );
       
   381     $self->makeIBY($drive);
       
   382     $self->makeIBY($drive, 'localised') unless $self->{'args'}->{'l10n'};
       
   383     }
       
   384   
       
   385   # Exit commands at the end of the process
       
   386   if ($self->{'exitcmds'})
       
   387     {
       
   388     foreach my $cmd ( @{ $self->{'exitcmds'} } )
       
   389       {
       
   390       print "Executing: $cmd\n" if $self->{'args'}->{'verbose'};
       
   391       warn "WARNING: error running $cmd" if system($cmd) != 0;
       
   392       }
       
   393     }
       
   394   }
       
   395 
       
   396 # ***
       
   397 # Installs files to a drive
       
   398 #
       
   399 sub installFiles
       
   400   {
       
   401   my ( $self, $drive, $fileList ) = @_;
       
   402   my $startsrc ;
       
   403     my $iconsrc ;
       
   404   
       
   405    $isSharedLibrary = 0;
       
   406    $isSharedWidget = 0;
       
   407    $isSharedIcon = 0;
       
   408    $sharedFolderName ='';
       
   409    $isSecureWidget = 0;
       
   410     
       
   411   print "Installing files for drive $drive\n" if $self->{'args'}->{'verbose'};
       
   412 
       
   413   # Unregister any existing widgets as otherwise when the registry is rewritten their icons will appear in the emulator but they won't work
       
   414   $self->unregisterWidgets($drive);
       
   415 
       
   416   print "\n			INSTALLING FILES FOR DRIVE $drive				\n"; 
       
   417   # Process each widget in turn
       
   418   my ( @installedProps );
       
   419   my ( @installedCWRTProps );
       
   420   foreach my $filename ( @$fileList )
       
   421     {
       
   422     # Check the file exists
       
   423     die "Can't find $filename" if !-e $filename;
       
   424 
       
   425     # Create a temporary folder
       
   426     print "\nInstalling $filename\n";
       
   427     my $tempdir = tempdir ( DIR => '.', CLEANUP => !$self->{args}->{'debug'});
       
   428 
       
   429     # Prefer to use 7zip rather than unzip because it's better behaved wrt Unicode
       
   430     if (findCmd('7z.exe'))
       
   431       {
       
   432       $self->un7zipWidget($filename, $tempdir);
       
   433       }
       
   434     else
       
   435       {
       
   436       $self->unzipWidget($filename, $tempdir);
       
   437       }
       
   438         my $widgetdata ;
       
   439         
       
   440         $isSharedLibrary = 0;
       
   441         $isSharedWidget = 0;
       
   442         $isSharedIcon = 0;
       
   443         $sharedFolderName ='';
       
   444     
       
   445     my ( $root, $extracted, $size ) = $self->getFiles($tempdir);
       
   446     die "No files extracted from $filename" if !@$extracted;
       
   447     
       
   448     if ($self->{'operator'}{lc $filename})
       
   449 		{
       
   450     	print "\n NON NOKIA WGT \n";
       
   451     	$non_nokia_widget = 1;
       
   452     }
       
   453     else
       
   454     {
       
   455     	print "\n NOKIA WGT \n";
       
   456     	$non_nokia_widget = 0;
       
   457     }
       
   458     
       
   459     
       
   460     if (($filename =~ /.wgz/ )&& (my $plist = catfile($tempdir, $root, 'Info.plist')))
       
   461       {
       
   462           print ("S60 widget \n");
       
   463           
       
   464           $w3c_widget = 0;
       
   465           # Parse the XML file into a hash
       
   466               $widgetdata = parsePList($plist);
       
   467       }
       
   468     elsif (($filename =~ /.wgt/ ) && ( my $confxml = catfile($tempdir, $root, 'config.xml')))
       
   469       {
       
   470         print (" W3C widget \n"); 
       
   471       
       
   472           # Parse the XML file into a hash
       
   473             $widgetdata = parseConfXml($confxml,$self->{'args'}->{'l10n'});
       
   474             $w3c_widget = 1;
       
   475       }
       
   476     else
       
   477       {
       
   478       die "Can't find $root/Info.plist , $root/config.xml file";
       
   479       }       
       
   480 		
       
   481 	  if ($self->{'secure'}{lc $filename}){
       
   482 		$isSecureWidget = 1;
       
   483 	  } else {
       
   484 	  	$isSecureWidget = 0;
       
   485 	  }
       
   486 
       
   487     if( $w3c_widget )
       
   488       { 
       
   489       if( $widgetdata->{'MainHTML'} )
       
   490         {
       
   491         $startsrc = $widgetdata->{'MainHTML'};
       
   492         }
       
   493       else
       
   494         {
       
   495         $startsrc = 'index.html';
       
   496         }
       
   497       if( $widgetdata->{'IconPath'} )
       
   498         {
       
   499         $iconsrc = $widgetdata->{'IconPath'};
       
   500         }
       
   501       else
       
   502         {
       
   503         $iconsrc = 'icon.png';   
       
   504         }
       
   505         
       
   506   		if($non_nokia_widget)
       
   507   		{
       
   508   			$widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
   509   		}
       
   510   		else
       
   511   		{
       
   512       		$widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_UID;
       
   513       	}
       
   514       
       
   515       $widgetdata->{'MimeType'} = "application/widget";
       
   516       }         
       
   517 
       
   518     print "Identifier: $widgetdata->{'BundleIdentifier'}\n" if $self->{args}->{'verbose'};
       
   519     
       
   520     # Set widget package properties
       
   521     $widgetdata->{'FileName'} = $filename;
       
   522     $widgetdata->{'FileSize'} = $size;
       
   523 
       
   524     # Load the language translations for BundleDisplayName
       
   525     if ($self->{'args'}->{'l10n'})
       
   526       {
       
   527       my $localised = $self->getLocalisedStringByLangCode(catfile($tempdir, $root), 'DisplayName', $self->{'args'}->{'l10n'});
       
   528       $widgetdata->{'BundleDisplayName'} = $localised if $localised;
       
   529       }
       
   530     else
       
   531       {
       
   532       $widgetdata->{'LocBundleDisplayName'} = $self->getLocalisedStrings(catfile($tempdir, $root), 'DisplayName');
       
   533       }
       
   534 
       
   535     # Fix up some of the fields
       
   536     $widgetdata->{'BundleName'} = $widgetdata->{'BundleDisplayName'} if !$widgetdata->{'BundleName'};
       
   537     $widgetdata->{'AllowNetworkAccess'} = $widgetdata->{'AllowFullAccess'} if !$widgetdata->{'AllowNetworkAccess'};
       
   538     $widgetdata->{'DriveName'} = $drive;
       
   539     
       
   540     if( $w3c_widget )
       
   541       {
       
   542       $widgetdata->{'PropertyListVersion'} = 4;
       
   543       my $widget_uid;
       
   544       
       
   545       if($non_nokia_widget)
       
   546   		{
       
   547   			$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
   548   		}
       
   549   		else
       
   550   		{
       
   551       	$widget_uid = CWRT_WIDGET_UI_UID;
       
   552       }
       
   553       
       
   554       if($isSharedLibrary)
       
   555       {
       
   556         #In case of NOKIA:sharedlibrary, the extracted widget contents and data source are stored under private\<uid>\..\lib\<sharedfoldername>\
       
   557         $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08x\\%s\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7","lib",$sharedFolderName);
       
   558         $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08x\\%s\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" ,"lib" ,$sharedFolderName);
       
   559       }
       
   560       else
       
   561       {
       
   562         $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08x\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7", hashpjw($widgetdata->{'BundleIdentifier'}));
       
   563         $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08x\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" , hashpjw($widgetdata->{'BundleIdentifier'}));
       
   564       }
       
   565       $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$startsrc";
       
   566       $widgetdata->{'AllowNetworkAccess'} = 1;
       
   567       
       
   568       }
       
   569     else
       
   570       {
       
   571       $widgetdata->{'PropertyListVersion'} = 1;
       
   572       $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08x\\%s\\', $widgetdata->{'DriveName'}, WIDGET_UI_UID, $widgetdata->{'BundleIdentifier'});
       
   573       $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$root\\$widgetdata->{'MainHTML'}";
       
   574       $widgetdata->{'IconPath'} = "$widgetdata->{'BasePath'}$root\\";
       
   575       }
       
   576       
       
   577     $widgetdata->{'BlanketPermissionGranted'} = 0 if( ! $widgetdata->{'BlanketPermissionGranted'} );
       
   578     $widgetdata->{'MiniViewEnabled'} = 0  if( ! $widgetdata->{'MiniViewEnabled'} );
       
   579     
       
   580     # Indicate that the widget was pre-installed
       
   581     $widgetdata->{'PreInstalled'} = 1;
       
   582     
       
   583     # Set BlanketPermissionGranted flag if Widget is listed as a homescreen widget in the INI file
       
   584     # Error if MiniViewEnabled isn't set
       
   585     if ($self->{'homescreen'}{lc $filename})
       
   586       {
       
   587       $widgetdata->{'BlanketPermissionGranted'} = 1;
       
   588       die "ERROR: $filename - MiniViewEnabled not set for homescreen widget" if !$widgetdata->{'MiniViewEnabled'};
       
   589       }
       
   590 
       
   591     # Defining UID  
       
   592     if($self->{'staticUID'}{lc $filename})
       
   593       {
       
   594       print "Using Static UID from INI file\n";
       
   595       $widgetdata->{'Uid'} = $self->{'staticUID'}{lc $filename};
       
   596       }
       
   597     else
       
   598       {
       
   599       # Find the next free UID to use
       
   600       $widgetdata->{'Uid'} = $self->findfreeUid($widgetdata);
       
   601       }
       
   602     print sprintf("Using UID for midlet: 0x%08x\n", $widgetdata->{'Uid'}) if $self->{args}->{'verbose'};
       
   603 
       
   604     # Make sure the destination exists
       
   605     my $dest = $self->regFileName($drive);
       
   606     mkpath $dest;
       
   607 
       
   608     my $icon;
       
   609     if($w3c_widget)
       
   610     {
       
   611       my $locate = $self->{'args'}->{'l10n'};
       
   612       my $seperator ='-';
       
   613       my $position = -1;
       
   614       my $found = 0 ;
       
   615       if ($self->{'args'}->{'l10n'})
       
   616           {
       
   617             do
       
   618                {
       
   619                 my $searchdir = '.\\'.$tempdir.'\\locales\\'.$locate;
       
   620                 if( opendir(DIR, $searchdir))
       
   621                     {
       
   622                     my @files = grep(/$iconsrc$/,readdir(DIR));
       
   623                     closedir(DIR);
       
   624                     if(@files)
       
   625                        {
       
   626                         $iconsrc = 'locales\\'.$locate.'\\'.$iconsrc ;
       
   627                         $found = 1;
       
   628                        }
       
   629                     }  
       
   630                 if(($position = rindex($locate,$seperator)) > 0 )
       
   631                     {
       
   632                     $locate = substr($locate,0,$position);
       
   633                     }
       
   634                } while (!$found && $position > 0);
       
   635           }
       
   636           if ($iconsrc)
       
   637           {
       
   638             $icon = catfile($tempdir, $root, $iconsrc);    
       
   639           }
       
   640             
       
   641           if(-e $icon)
       
   642           {
       
   643              $widgetdata->{'DBIconPath'}= "$widgetdata->{'BasePath'}$iconsrc";
       
   644              print "Icon found -- $widgetdata->{'DBIconPath'} \n";
       
   645           }
       
   646           else
       
   647           {
       
   648               $icon = findCmd('default_widget_icon.png');
       
   649               print "default_widget_icon.png used \n";    
       
   650               $widgetdata->{'DBIconPath'}= ":/resource/default_widget_icon.png";
       
   651           }
       
   652       }
       
   653     else
       
   654     {
       
   655       $icon = catfile($tempdir, $root, 'Icon.png');
       
   656             die "ERROR: Widget bundle must include an Icon.png file in $root directory.\n" unless -e $icon;
       
   657     }
       
   658     
       
   659     # Create the MBM file icon - in case of sharedlibrary, create only if NOKIA:widget is true
       
   660     my $mbm;
       
   661     
       
   662     print("\nIs shared library - $isSharedLibrary \nIs sharedlib widget - $isSharedWidget \nIs Secure WGZ - $self->{'secure'}{lc $filename}\n");
       
   663     
       
   664 		if( ((!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget)) && (!$self->{'secure'}{lc $filename}))
       
   665     {
       
   666     	  print "Creating mbm !!!\n";
       
   667         die "ERROR: Can't find PNG2MBM command in PATH." if !(my $cmd = findCmd('png2mbm.exe'));
       
   668         $mbm = $self->regFileName($drive, sprintf("[%08x].mbm", $widgetdata->{'Uid'}));
       
   669         print "Generating: $mbm\n";
       
   670                     die "Failed to create MBM $mbm " if system("$cmd $self->{args}->{'verbose'} -in \"$icon\" -out $mbm -sizes ".ICON_SIZES) != 0;
       
   671     
       
   672         # Add the mbm to the list of files
       
   673         $self->addToRomList($drive, $mbm);
       
   674     
       
   675         # Create the INI file which defines the registry info
       
   676         my $ini = catfile($tempdir, 'reg.ini');
       
   677         $self->makeIni($widgetdata, $ini);
       
   678         unlink 'debug.ini'; copy($ini, 'debug.ini') if $debug;
       
   679         print "Generated INI file: $ini\n" if $self->{args}->{'verbose'};
       
   680     
       
   681         # Generate the registry files
       
   682         die "ERROR: Can't find WidgetRegFiles.exe command in PATH." if !($cmd = findCmd('WidgetRegFiles.exe'));
       
   683         die "Failed to generate registry files" if system("$cmd $ini") != 0;
       
   684         my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $widgetdata->{'Uid'})), catfile($dest, sprintf("%08x_loc.rsc", $widgetdata->{'Uid'})) );
       
   685         die "Failed to generate REG file: $!" if !-e $reg;
       
   686         $self->addToRomList($drive, $reg);
       
   687         die "Failed to generate LOC file: $!" if !-e $loc;
       
   688         if ($self->{'args'}->{'l10n'})
       
   689           {
       
   690               $self->addToRomList($drive, $loc);
       
   691           }
       
   692         else
       
   693           {
       
   694               $self->addToRomList($drive, $loc, 'localised');
       
   695           }
       
   696         }
       
   697         
       
   698     # Create install folder
       
   699     my $dir = $self->installDir($drive, $widgetdata->{'BundleIdentifier'});
       
   700     mkpath $dir;
       
   701 
       
   702     # Now copy the widget files to the right place
       
   703     print "Install Directory: $dir\n";
       
   704     foreach my $widgetfile ( @$extracted )
       
   705     {
       
   706       my ( $sourceFile, $destFile ) = ( catfile($tempdir, $widgetfile), catfile($dir, $widgetfile) );
       
   707       print "Copying $sourceFile to $destFile\n" if $self->{args}->{'debug'};
       
   708 
       
   709       # Create the directory if it doesn't exist already
       
   710       my $dir = dirname($destFile);
       
   711       if (!-d $dir)
       
   712         {
       
   713         mkpath ($dir) or die "Failed to create $dir $!";
       
   714         }
       
   715       unlink $destFile;
       
   716       if (!copy($sourceFile, $destFile))
       
   717         {
       
   718         warn "WARNING: Failed to copy $sourceFile to $destFile: $!";
       
   719         }
       
   720       #else
       
   721         {
       
   722         $self->addToRomList($drive, $destFile);
       
   723         }
       
   724     }
       
   725 
       
   726     # Copy the MBM file into the widget install directory
       
   727     # because native installation does and uses it after
       
   728     # installation to manage UID consistency.
       
   729     if( (!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget))
       
   730     {
       
   731         my $mbmName = sprintf("[%08x].mbm", $widgetdata->{'Uid'});
       
   732         my $destFile;
       
   733         if($w3c_widget)
       
   734         {
       
   735             my $dataDir;
       
   736             
       
   737             my $widget_uid;
       
   738       
       
   739 			      if($non_nokia_widget)
       
   740 			  		{
       
   741 			  			$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
   742 			  		}
       
   743 			  		else
       
   744 			  		{
       
   745 			      	$widget_uid = CWRT_WIDGET_UI_UID;
       
   746 			      }
       
   747             
       
   748             # NOKIA:sharedlibrary check
       
   749             if($isSharedWidget)
       
   750             {
       
   751                 $dataDir = fixFilename(catfile($self->destLocation($drive), 'Private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName));
       
   752             }
       
   753             else
       
   754             {
       
   755                 #in case of WGT copy .mbm to \epoc32\winscw\C\Private\200267c0\data\hash<BundleId>\
       
   756                 $dataDir = fixFilename(catfile($self->destLocation($drive), 'Private', sprintf("%08X", $widget_uid),"data", $hashval));
       
   757             }
       
   758             mkpath $dataDir;
       
   759             $destFile = catfile($dataDir,$mbmName);
       
   760         }
       
   761         else
       
   762         {
       
   763            $destFile = catfile($dir, $root, $mbmName);
       
   764         }
       
   765     		# Exclude securewidget from making a mbm file
       
   766 			if (!$self->{'secure'}{lc $filename}){
       
   767             print "Copying $mbm to $destFile\n" if $self->{args}->{'debug'};
       
   768             copy $mbm, $destFile or die "Failed to copy $mbm to $destFile: $!";
       
   769             $self->addToRomList($drive, $destFile);
       
   770           	}
       
   771         }
       
   772         
       
   773     # Remember the data for the registry
       
   774     if( $w3c_widget )
       
   775       {
       
   776       push @installedCWRTProps, $widgetdata;
       
   777       }
       
   778     else
       
   779       {
       
   780 	    if (!$self->{'secure'}{lc $filename}){
       
   781       		push @installedProps, $widgetdata;
       
   782       	}
       
   783       }
       
   784 
       
   785     if (!$debug)
       
   786       {
       
   787       # Perl v5.6 can't delete files with unicode in their name on Windows
       
   788       if ($] < 5.008 && $^O =~ /MSWin32/)
       
   789         {
       
   790         system("rmdir /s /q $tempdir");
       
   791         }
       
   792       else
       
   793         {
       
   794         rmtree $tempdir;
       
   795         }
       
   796       }
       
   797     #Generate the secsession for .wgt widgets
       
   798     if( $w3c_widget ) 
       
   799       {
       
   800       $self->addToRomList($drive, $self->makeSecSession($drive));
       
   801       }
       
   802   }
       
   803 
       
   804   my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY);
       
   805   $self->addToRomList($drive, $cwrtdbPath);
       
   806   
       
   807   # Generate the registry and IBY file
       
   808   $self->addToRomList($drive, $self->makeRegistry($drive, \@installedProps, 0));
       
   809   $self->addToRomList($drive, $self->makeRegistry($drive, \@installedCWRTProps, 1));
       
   810     
       
   811 
       
   812   print "\n\n %%%%%          WIDGET PRE-INSTALLATION completed for Drive $drive          %%%%% \n\n";
       
   813   }
       
   814 
       
   815 sub un7zipWidget
       
   816   {
       
   817   my ( $self, $filename, $tempdir ) = @_;
       
   818 
       
   819   # Unzip the file
       
   820   die "Can't find 7z.exe tool on PATH." if !findCmd('7z.exe');
       
   821   die "Failed to extract widget contents using 7zip: $!" if (system("7z x -aoa -o$tempdir \"$filename\" >nul 2>&1") != 0);
       
   822   }
       
   823 
       
   824 sub unzipWidget
       
   825   {
       
   826   my ( $self, $filename, $tempdir ) = @_;
       
   827 
       
   828   # Unzip the file
       
   829   die "Can't find unzip.exe tool on PATH." if !findCmd('unzip.exe');
       
   830   die "Failed to extract widget contents using zip: $!" if (system("unzip.exe \"$filename\" -d $tempdir >nul 2>&1") != 0);
       
   831   }
       
   832 
       
   833 # Recursively get list of files in a folder
       
   834 sub getFiles
       
   835   {
       
   836   my ( $self, $tempdir ) = @_;
       
   837 
       
   838   my $root = '.';
       
   839   my @extracted;
       
   840   my $size =0;
       
   841   
       
   842   my @dirs = '.';
       
   843   foreach my $dir ( @dirs )
       
   844     {
       
   845     opendir DIR, catfile($tempdir, $dir) or die "Failed to opendir $dir: $!";
       
   846     foreach ( grep !/^\.{1,2}$/, readdir DIR )
       
   847       {
       
   848       my $name = catfile($dir, $_);
       
   849       my $fullname = catfile($tempdir, $name);
       
   850       if (-d $fullname)
       
   851         {
       
   852         push @dirs, $name;
       
   853         }
       
   854       else
       
   855         {
       
   856         # Remember total size for later
       
   857         if (-e $fullname)
       
   858           {
       
   859           push @extracted, $name;
       
   860           print "Extracted: $name\n" if $self->{args}->{'debug'};
       
   861           $size += -s $fullname;
       
   862 
       
   863           # Get root
       
   864           if ($name =~ /info.plist$/i && $name =~ /^([^\/\\]+)[\/\\]/)
       
   865             {
       
   866             $root = $1;
       
   867             }
       
   868           }
       
   869         else
       
   870           {
       
   871           warn "WARNING: Failed to find extracted file $fullname";
       
   872           }
       
   873         }
       
   874       }
       
   875     closedir DIR;
       
   876     }
       
   877 
       
   878   return ( $root, \@extracted, $size );
       
   879   }
       
   880 
       
   881 ## see http://www.loc.gov/standards/iso639-2/php/code_list.php
       
   882 ## see http://www.loc.gov/standards/iso639-2/faq.html#2
       
   883 sub getLocalisedStringByLangCode
       
   884   {
       
   885   my ( $self, $dir, $strName, $langCode ) = @_;
       
   886   my $localised;
       
   887 
       
   888   # Generate the name of the file containing localised strings for this language
       
   889   my $locfile = catfile($dir, "$langCode.lproj", "InfoPlist.strings");
       
   890   if (-e $locfile)
       
   891         {
       
   892     # Open the file
       
   893     print "Found $langCode language translations in $locfile\n" if $verbose;
       
   894     open LOC, $locfile or die "Failed to open $locfile: $!";
       
   895 
       
   896     # Get the byte order mark from the start of the file
       
   897     my $bom;
       
   898     $bom = unpack("S", $bom) if (read(LOC, $bom, 2) == 2);
       
   899     if ($bom)
       
   900       {
       
   901       if ($bom == 0xEFBB)
       
   902         {
       
   903         # Skip utf8 bom
       
   904         seek LOC, 3, 0;
       
   905         }
       
   906       elsif ($bom != 0xFFFE && $bom != 0xFEFF)
       
   907         {
       
   908         seek LOC, 0, 0;
       
   909         undef $bom;
       
   910         }
       
   911       }
       
   912     else
       
   913       {
       
   914       # go back to start of file if no bom
       
   915       seek LOC, 0, 0;
       
   916       undef $bom;
       
   917       }
       
   918 
       
   919     while(my $line = <LOC>)
       
   920       {
       
   921       # Do unicode conversion
       
   922       my $ustr;
       
   923       if ($bom)
       
   924         {
       
   925         $ustr = utf16($line);
       
   926         $ustr->byteswap if $bom != 0xFFFE;
       
   927         }
       
   928       else
       
   929         {
       
   930         $ustr = utf8($line);
       
   931         }
       
   932 
       
   933       # Find the string we're looking for
       
   934       if ($ustr->utf8 =~ /(?:^|\s)$strName\s*=\s*\"([^\"]*)\"/)
       
   935         {
       
   936         print "\t...$strName => $1\n" if $debug;
       
   937         $localised = utf8($1);
       
   938         }
       
   939       }
       
   940     close LOC;
       
   941     }
       
   942     return $localised;
       
   943   }
       
   944 
       
   945 # Get localised version of strings if they exist
       
   946 sub getLocalisedStrings
       
   947   {
       
   948   my ( $self, $dir, $strName ) = @_;
       
   949   return if (!$self->{'langmapping'});
       
   950 
       
   951   # Iterate through all the languages we know about
       
   952   my %result;
       
   953   for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++)
       
   954     {
       
   955     my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] );
       
   956 
       
   957     my $localised = $self->getLocalisedStringByLangCode($dir, $strName, $langname);
       
   958     $result{$langid} = $localised if $localised;
       
   959     }
       
   960 
       
   961   return \%result if keys %result;
       
   962   }
       
   963 
       
   964 # Find and execute a command
       
   965 sub findCmd
       
   966   {
       
   967   my $cmd = shift;
       
   968   return fixFilename("./$cmd") if -e $cmd;
       
   969 
       
   970   # PATH separator differs on Windows and Linux
       
   971   my $sep = $^O =~ /MSWin32/ ? ';' : ':';
       
   972 
       
   973   # Search each entry in the PATH
       
   974   my @paths = split /$sep/, $ENV{PATH};
       
   975   push @paths, dirname($0);
       
   976   foreach my $path ( @paths )
       
   977     {
       
   978     my $fullcmd = fixFilename(catfile($path, $cmd));
       
   979     return $fullcmd if -e $fullcmd;
       
   980     }
       
   981   }
       
   982 
       
   983 # Make INI file describing widget - this is passed to widgetregfiles.exe
       
   984 sub makeIni
       
   985   {
       
   986   my ( $self, $data, $file ) = @_;
       
   987   open INI, ">$file" or die "Failed to open $file for writing: $!";
       
   988   binmode INI, ":utf8" if $] >= 5.008;
       
   989 
       
   990   # Get directory where mbm should go
       
   991   my $dir = $self->regFileName($data->{'DriveName'});
       
   992 
       
   993   print INI "[app_registration_info]\n";
       
   994   print INI sprintf("uid=%08x\n", $data->{'Uid'});
       
   995   print INI "app_file=$data->{'MainHTML'}\n";
       
   996   print INI "caption=$data->{'BundleDisplayName'}\n";
       
   997   print INI "drive_name=$data->{'DriveName'}\n";
       
   998   print INI "results_dir=$dir\n";
       
   999   
       
  1000   if( $w3c_widget )
       
  1001   {
       
  1002     print INI "app_type=200267DC\n";
       
  1003     print " WGT Widget:: app_type added to ini of widgetregfiles.exe \n" if $debug;
       
  1004   }
       
  1005   
       
  1006 
       
  1007   # Add language stuff if we have the mapping
       
  1008   if ($data->{'LocBundleDisplayName'})
       
  1009     {
       
  1010     my @langList;
       
  1011     foreach my $langid ( sort { $a <=> $b } keys %{ $data->{'LocBundleDisplayName'} } )
       
  1012       {
       
  1013       my $symid = sprintf("%02d", $langid);
       
  1014       push @langList, $symid;
       
  1015       print INI "caption$symid=", $data->{'LocBundleDisplayName'}->{$langid}->utf8, "\n";
       
  1016       }
       
  1017     print INI "languages=", join(' ', @langList), "\n";
       
  1018     }
       
  1019 
       
  1020   close INI;
       
  1021   convert2Unicode($file);
       
  1022   }
       
  1023 
       
  1024  sub findfreeUid
       
  1025   {
       
  1026   my ( $self, $data ) = @_;
       
  1027   my $appfile = lc $data->{'MainHTML'};
       
  1028   my $uid;
       
  1029   my $size;
       
  1030     if($w3c_widget)     #CWRT Widget
       
  1031     {
       
  1032       # pick the next free CWRT Internal UID
       
  1033       if(isInternal($data->{'DriveName'}))
       
  1034       {
       
  1035         print "\nInternal CWRT UID";
       
  1036         $size = scalar @staticUidCwrtIntList;
       
  1037         print " Static UID :: @staticUidCwrtIntList Length -- $size \n" if($size);
       
  1038         for(my $i=0; $i<$size; $i++)
       
  1039         {
       
  1040 		  #skip looping if freeUid found
       
  1041           if( $self->{'freeuidcwrtint'} lt $staticUidCwrtIntList[$i] ) {last};
       
  1042           
       
  1043           if($self->{'freeuidcwrtint'} == $staticUidCwrtIntList[$i]) 
       
  1044           { 
       
  1045             $self->{'freeuidcwrtint'}++; 
       
  1046           }
       
  1047         }
       
  1048         $uid = $self->{'freeuidcwrtint'}++;   # Assign and then set next free UID
       
  1049       } 
       
  1050       else
       
  1051       {
       
  1052         # pick the next free CWRT External UID
       
  1053         print "\nExternal CWRT UID ";
       
  1054         $size = scalar @staticUidCwrtExtList;
       
  1055         print "Static UID :: @staticUidCwrtExtList Length -- $size \n";
       
  1056         
       
  1057         for(my $i=0; $i<$size; $i++)
       
  1058         {
       
  1059           if( $self->{'freeuidcwrtext'} lt $staticUidCwrtExtList[$i] ) {last};
       
  1060           
       
  1061           if($self->{'freeuidcwrtext'} == $staticUidCwrtExtList[$i]) 
       
  1062           { 
       
  1063             $self->{'freeuidcwrtext'}++; 
       
  1064           }
       
  1065         }
       
  1066         $uid = $self->{'freeuidcwrtext'}++;   # Assign and then set next free UID
       
  1067       }
       
  1068     }
       
  1069     else      #WRT widget
       
  1070     {
       
  1071       # pick the next free WRT Internal UID
       
  1072       if(isInternal($data->{'DriveName'}))
       
  1073       {
       
  1074         # pick the next free CWRT Internal UID
       
  1075         if(isInternal($data->{'DriveName'}))
       
  1076         {
       
  1077           print "\nInternal WRT UID ";
       
  1078           $size = scalar @staticUidWrtIntList;
       
  1079           print " STATIC UID :: @staticUidWrtIntList Length -- $size\n";
       
  1080                  
       
  1081           for(my $i=0; $i<$size; $i++)
       
  1082           {
       
  1083             if( $self->{'freeuidwrtint'} lt $staticUidWrtIntList[$i] ) {last};
       
  1084             
       
  1085             if($self->{'freeuidwrtint'} == $staticUidWrtIntList[$i]) 
       
  1086             { 
       
  1087               $self->{'freeuidwrtint'}++; 
       
  1088             }
       
  1089           }
       
  1090           $uid = $self->{'freeuidwrtint'}++;   # Assign and then set next free UID
       
  1091         }
       
  1092       }
       
  1093       else
       
  1094       {
       
  1095         # pick the next free WRT External UID
       
  1096         print "\nExternal WRT UID ";
       
  1097         $size = scalar @staticUidWrtExtList;
       
  1098         print "STATIC UID :: @staticUidWrtExtList Length -- $size\n";
       
  1099         
       
  1100         for(my $i=0; $i<$size; $i++)
       
  1101         {
       
  1102           if( $self->{'freeuidwrtext'} lt $staticUidWrtExtList[$i] ) {last};
       
  1103           
       
  1104           if($self->{'freeuidwrtext'} == $staticUidWrtExtList[$i]) 
       
  1105           { 
       
  1106             $self->{'freeuidwrtext'}++; 
       
  1107           }
       
  1108         }
       
  1109         $uid = $self->{'freeuidwrtext'}++;   # Assign and then set next free UID
       
  1110       }
       
  1111     }
       
  1112   print sprintf(" Generated UID: hex->0x%08x dec->$uid\n \n",$uid);
       
  1113   return $uid;
       
  1114   }
       
  1115 
       
  1116 # Fix slash problems in a filename
       
  1117 sub fixFilename
       
  1118   {
       
  1119   my $filename = shift;
       
  1120   $filename =~ s/([\\\/])[\\\/]/$1/g;
       
  1121   return catfile(split(/[\\\/]/, $filename));
       
  1122   }
       
  1123 
       
  1124 # Get install location
       
  1125 sub destLocation
       
  1126   {
       
  1127   my ( $self, $drive ) = @_;
       
  1128   my $letter = uc(substr($drive, 0, 1));
       
  1129   
       
  1130   # Was any destination location specified in the config file?
       
  1131   if ($self->{destination} && $self->{destination}->{$letter})
       
  1132     {
       
  1133     return catfile($self->{'args'}->{'epocroot'}, $self->{destination}->{$letter});
       
  1134     }
       
  1135     
       
  1136   # No destination specified - use emulator location
       
  1137   return catfile($self->{'args'}->{'epocroot'}, $letter eq 'Z' ? ROM_DEST : sprintf(DRIVE_DEST, $letter));
       
  1138   }
       
  1139   
       
  1140 # Get the destination for REG/LOC/MBM file
       
  1141 sub regFileName
       
  1142   {
       
  1143   my ( $self, $drive, $filename ) = @_;
       
  1144   my $result = catfile($self->destLocation($drive), DESTINATION, $filename);
       
  1145   return fixFilename($result);
       
  1146   }
       
  1147 
       
  1148 # Widget install directory
       
  1149 sub installDir
       
  1150   {
       
  1151   my ( $self, $drive, $id ) = @_;
       
  1152   my $result ;
       
  1153   $hashval = hashpjw($id);
       
  1154   if( $w3c_widget )
       
  1155   {
       
  1156   	my $widget_uid;
       
  1157     if($non_nokia_widget)
       
  1158 	{
       
  1159 		$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
  1160 	}
       
  1161 	else
       
  1162 	{
       
  1163 		$widget_uid = CWRT_WIDGET_UI_UID;
       
  1164 	}
       
  1165     if($isSharedLibrary)
       
  1166     {
       
  1167     	$result = catfile($self->destLocation($drive), 'Private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", "lib",$sharedFolderName);
       
  1168     }
       
  1169     else
       
  1170     {
       
  1171         $result = catfile($self->destLocation($drive), 'Private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", $hashval);
       
  1172     }
       
  1173   }
       
  1174   else
       
  1175       {
       
  1176 	  	if ($isSecureWidget){
       
  1177 	   		print "Installing secure WGZ Widget\n";
       
  1178 	    	$result = catfile($self->destLocation($drive), 'private', sprintf("%08x", SWIDGET_UI_UID), $id);
       
  1179 	  	} else {
       
  1180 	   		print "Installing WGZ Widget\n";
       
  1181         	$result = catfile($self->destLocation($drive), 'private', sprintf("%08x", WIDGET_UI_UID), $id);
       
  1182 	  	}
       
  1183       }    
       
  1184   return fixFilename($result);
       
  1185   }
       
  1186 
       
  1187 # Determines whether a drive should be considered internal or not
       
  1188 sub isInternal
       
  1189   {
       
  1190   my $drive = shift;
       
  1191   die "Invalid drive format: $drive" if $drive !~ /^[a-zA-Z]:/;
       
  1192   return 1 if $drive =~ /^[zcZC]/;
       
  1193   }
       
  1194 
       
  1195 # Parse these awful PLIST files
       
  1196 sub parsePList
       
  1197   {
       
  1198   my $file = shift;
       
  1199 
       
  1200   # Create parser object
       
  1201   our ($key, $val, $plisthash ) = ('', '', {});
       
  1202   my $parser = new XML::Parser;
       
  1203   $parser->setHandlers('Doctype' => \&docT, 'Start' => \&startH, 'End' => \&endH, 'Char' => \&dataH);
       
  1204 
       
  1205   # Parse the file
       
  1206   open XML, $file or die "Couldn't open $file";
       
  1207 
       
  1208   # Skip the UTF8 BOM - perl 5.6 can't handle it
       
  1209   my $bom;
       
  1210   read XML, $bom, 3;
       
  1211   $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom)));
       
  1212   print "Testing the following for BOM: $bom\n" if $debug;
       
  1213   seek(XML, 0, 0) if $bom ne 'EFBBBF';
       
  1214 
       
  1215   $parser->parse(*XML);
       
  1216   close XML;
       
  1217 
       
  1218   # Check required fields exist
       
  1219   die "Widget MainHTML unknown" if !$plisthash->{'MainHTML'};
       
  1220   die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'};
       
  1221   die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'};
       
  1222 
       
  1223   # Return result
       
  1224   return $plisthash;
       
  1225 
       
  1226   # Called on a start tag
       
  1227   sub startH
       
  1228     {
       
  1229     my ($p, $el, %atts) = @_;
       
  1230     undef $key if ($el =~ /^key$/i);
       
  1231     $val = '';
       
  1232     }
       
  1233 
       
  1234   # Receives document type
       
  1235   sub docT
       
  1236     {
       
  1237     my ($expat, $name, $sysid, $pubid, $internal ) = @_;
       
  1238     die "PLIST format looks wrong!" if lc($name) ne 'plist';
       
  1239     $plisthash->{'NokiaWidget'} = ( $pubid =~ m[^-//Nokia//DTD PLIST]i ) ? 1 : 0;
       
  1240     }
       
  1241 
       
  1242   # Receives character data
       
  1243   sub dataH
       
  1244     {
       
  1245     my ($p, $s) = @_;
       
  1246     $val .= $s;
       
  1247     }
       
  1248 
       
  1249   # Called on an end tag
       
  1250   sub endH
       
  1251     {
       
  1252     my ($p, $el) = @_;
       
  1253     if ($el =~ /^key$/i)
       
  1254       {
       
  1255       $key = $val;
       
  1256       }
       
  1257     elsif ($key)
       
  1258       {
       
  1259       $val = 1 if $el =~ /^true$/i;
       
  1260       $val = 0 if $el =~ /^false$/i;
       
  1261 
       
  1262       # Fix stuff so it's in the correct format
       
  1263       $key =~ s/^CF//;
       
  1264       $key = 'BundleIdentifier' if $key =~ /^Identifier$/i;
       
  1265       $key = 'BundleDisplayName' if $key =~ /^DisplayName$/i;
       
  1266       $key = 'BundleVersion' if $key =~ /^Version$/i;
       
  1267 
       
  1268       $plisthash->{$key} = $val;
       
  1269       undef $key;
       
  1270       }
       
  1271     $val = ''
       
  1272     }
       
  1273   }
       
  1274 
       
  1275 
       
  1276 sub parseConfXml
       
  1277   {
       
  1278     my ( $file , $language ) = @_;
       
  1279 
       
  1280   our ($key, $val, $plisthash, $localizationValue,$localizationIconValue, $lang,$langIcon) = ('', '', {}, '','', {},{});
       
  1281   our ($featureCount, $paramCount, $accessCount) = (1,1,1);
       
  1282   our ($attributeMap, $featureMap, $featureParamMap, $accessMap)=('','','','');
       
  1283   
       
  1284   # Create parser object
       
  1285   my $parser = new XML::Parser;
       
  1286   $parser->setHandlers( 'Start' => \&startC, 'End' => \&endC, 'Char' => \&dataC);
       
  1287    
       
  1288   # Parse the file
       
  1289   open XML,$file or die "Couldn't open $file";
       
  1290   # Skip the UTF8 BOM - perl 5.6 can't handle it
       
  1291   my $bom;
       
  1292   read XML, $bom, 3;
       
  1293   $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom)));
       
  1294   print "Testing the following for BOM: $bom\n" if $debug;
       
  1295   seek(XML, 0, 0) if $bom ne 'EFBBBF';
       
  1296     $plisthash->{'NokiaWidget'} = 2 ;
       
  1297     $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1" ;
       
  1298   
       
  1299   $parser->parse(*XML);
       
  1300   close XML;
       
  1301 
       
  1302     if( $language )
       
  1303         {
       
  1304          if($lang->{$language})
       
  1305          { 
       
  1306           $plisthash->{'BundleDisplayName'} = $lang->{$language};
       
  1307          }
       
  1308          if($langIcon->{$language})
       
  1309          {
       
  1310           $plisthash->{'IconPath'} = $langIcon->{$language};
       
  1311          }
       
  1312         }
       
  1313   die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'};
       
  1314   die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'};
       
  1315   
       
  1316    $attributeMap = $attributeMap.WIDGET_NAME.KEY_VALUE_SEPERATOR.$plisthash->{'BundleDisplayName'}.KEY_VALUE_PAIR_SEPERATOR;
       
  1317 
       
  1318    if($non_nokia_widget)
       
  1319    {
       
  1320        $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267D6".KEY_VALUE_PAIR_SEPERATOR;
       
  1321    }
       
  1322    else
       
  1323    {
       
  1324        $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267C0".KEY_VALUE_PAIR_SEPERATOR;
       
  1325    }
       
  1326 
       
  1327     if($attributeMap)
       
  1328     {      
       
  1329         $plisthash->{'AttributeList'} = $attributeMap;
       
  1330         print "\n AttributeList::$plisthash->{'AttributeList'}\n"
       
  1331     }
       
  1332 
       
  1333   # Return result
       
  1334   return $plisthash;
       
  1335 
       
  1336   # Called on a start tag
       
  1337   sub startC
       
  1338     {
       
  1339     my ($p, $el, %atts) = @_;
       
  1340     
       
  1341     if($el eq "widget")
       
  1342         {
       
  1343          if ( $atts{"id"} )
       
  1344              {
       
  1345             $plisthash->{'BundleIdentifier'} = $atts{"id"};
       
  1346             $attributeMap = $attributeMap.WIDGET_ID.KEY_VALUE_SEPERATOR.$atts{"id"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1347             
       
  1348              }
       
  1349          if ( $atts{"version"} )
       
  1350              {
       
  1351             $plisthash->{'BundleVersion'} = $atts{"version"};
       
  1352             $attributeMap = $attributeMap.WIDGET_VERSION.KEY_VALUE_SEPERATOR.$atts{"version"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1353              }
       
  1354          if ( $atts{"viewmodes"} && $atts{"viewmodes"} eq "all" )
       
  1355              {
       
  1356             $plisthash->{'MiniViewEnabled'} = 1;
       
  1357              }
       
  1358          $attributeMap = $attributeMap.WIDGET_HEIGHT.KEY_VALUE_SEPERATOR.$atts{"height"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1359          $attributeMap = $attributeMap.WIDGET_WIDTH.KEY_VALUE_SEPERATOR.$atts{"width"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1360         }
       
  1361       elsif ($el eq "icon")
       
  1362           {
       
  1363            if ( $atts{"xml:lang"} )
       
  1364              {
       
  1365               $localizationIconValue = lc($atts{"xml:lang"}) ;
       
  1366              }
       
  1367            if ( $atts{"src"} )
       
  1368              {
       
  1369             $plisthash->{'IconPath'} = $atts{"src"};
       
  1370                  }
       
  1371           }
       
  1372       elsif ($el eq "content")
       
  1373           {
       
  1374            $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;	
       
  1375            if ( $atts{"src"} )
       
  1376              {
       
  1377             $plisthash->{'MainHTML'} = $atts{"src"};
       
  1378             $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_ATTR_SEPERATOR."src".KEY_VALUE_SEPERATOR.$atts{"src"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1379              }
       
  1380           }
       
  1381       elsif ($el eq "name")
       
  1382           {
       
  1383            if ( $atts{"xml:lang"} )
       
  1384              {
       
  1385               $localizationValue = lc($atts{"xml:lang"}) ;
       
  1386              }
       
  1387           }
       
  1388       elsif ($el eq "feature")
       
  1389           {
       
  1390            $featureMap = WIDGET_FEATURE . $featureCount;
       
  1391            $attributeMap = $attributeMap.$featureMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1392            
       
  1393            if ( $atts{"name"} )
       
  1394              {
       
  1395               $attributeMap = $attributeMap.$featureMap. KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1396               my $jilFeature = "http://jil.org/jil";
       
  1397               if($atts{"name"}=~ m/^$jilFeature/i)
       
  1398               {
       
  1399                 $plisthash->{'WidgetPackagingFormat'} = "jil";
       
  1400               }
       
  1401              }
       
  1402          if ( $atts{"required"} )
       
  1403              {
       
  1404               $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."required".KEY_VALUE_SEPERATOR.$atts{"required"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1405              }
       
  1406          }
       
  1407        elsif($el eq "param")
       
  1408           {
       
  1409               $featureParamMap = $featureMap. WIDGET_FEATURE_PARAM . $paramCount;
       
  1410               $attributeMap = $attributeMap.$featureParamMap. KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1411               if ($atts{"name"}) 
       
  1412               {
       
  1413                   $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1414               }
       
  1415               if ($atts{"value"})
       
  1416               {
       
  1417                   $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."value".KEY_VALUE_SEPERATOR.$atts{"value"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1418               }
       
  1419           }
       
  1420        elsif ($el eq "access" || $el eq "jil:access")
       
  1421           {
       
  1422               $accessMap = WIDGET_ACCESS . $accessCount;
       
  1423               $attributeMap = $attributeMap.$accessMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1424            
       
  1425               if ( $atts{"network"} )
       
  1426              {
       
  1427                 $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."network".KEY_VALUE_SEPERATOR.$atts{"network"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1428              }
       
  1429             if ( $atts{"remotescripts"} )
       
  1430              {
       
  1431                 $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."remotescripts".KEY_VALUE_SEPERATOR.$atts{"remotescripts"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1432              }
       
  1433              if ( $atts{"localfs"} )
       
  1434              {
       
  1435                 $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."localfs".KEY_VALUE_SEPERATOR.$atts{"localfs"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1436              }
       
  1437              if ( $atts{"origin"} )
       
  1438              {
       
  1439                 $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."origin".KEY_VALUE_SEPERATOR.$atts{"origin"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1440              }
       
  1441              if ( $atts{"subdomains"} )
       
  1442              {
       
  1443                 $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."subdomains".KEY_VALUE_SEPERATOR.$atts{"subdomains"}.KEY_VALUE_PAIR_SEPERATOR;
       
  1444              }
       
  1445         }
       
  1446         elsif ($el eq "NOKIA:sharedlibrary")
       
  1447         {
       
  1448             print " \n\n ^^^^^^^^^^^^^^^^^^^^^^^NOKIA:sharedlibrary ^^^^^^^^^^^^^^^^^^^^ \n\n";
       
  1449             $isSharedLibrary = 1;
       
  1450             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
       
  1451         }
       
  1452      $val = '';    
       
  1453      }
       
  1454     
       
  1455 sub docC{}
       
  1456 # Receives character data
       
  1457   sub dataC
       
  1458     {
       
  1459     my ($p, $s) = @_;
       
  1460     $val .= $s;
       
  1461     }
       
  1462 
       
  1463   # Called on an end tag
       
  1464   sub endC
       
  1465     {
       
  1466     my ($p, $el) = @_;
       
  1467     if ($el eq "name")
       
  1468         {
       
  1469        if( $localizationValue )
       
  1470            {
       
  1471             chomp($val);
       
  1472             $lang->{$localizationValue} = $val;
       
  1473             $localizationValue = '';
       
  1474              }
       
  1475          else
       
  1476              {
       
  1477               chomp($val);
       
  1478               $plisthash->{'BundleDisplayName'} = $val;
       
  1479              }   
       
  1480       }
       
  1481       elsif ($el eq "icon")
       
  1482       {
       
  1483         if( $localizationIconValue )
       
  1484            {
       
  1485             $langIcon->{$localizationIconValue} = $plisthash->{'IconPath'};
       
  1486             print "\n %%%%%%%%%%%  $localizationIconValue  :: $plisthash->{'IconPath'}%%%%%%%%%%%%%\n";
       
  1487             $localizationIconValue = '';
       
  1488            }
       
  1489       }
       
  1490     elsif($el eq "feature")
       
  1491       {
       
  1492           $featureCount++;
       
  1493           $paramCount = 0;
       
  1494       }
       
  1495     elsif($el eq "param")
       
  1496       {
       
  1497           $paramCount++;
       
  1498       }
       
  1499       elsif($el eq "access" || $el eq "jil:access")
       
  1500       {
       
  1501           $accessCount++;
       
  1502       } 
       
  1503       elsif ($el eq "NOKIA:folder")
       
  1504         {
       
  1505             chomp($val);
       
  1506             $sharedFolderName = $val;
       
  1507             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_FOLDER.KEY_VALUE_SEPERATOR.$sharedFolderName.KEY_VALUE_PAIR_SEPERATOR;
       
  1508         }
       
  1509     elsif ($el eq "NOKIA:widget")
       
  1510         {
       
  1511             chomp($val);
       
  1512             if( lc($val) eq "true" )
       
  1513             {
       
  1514                 $isSharedWidget = 1;
       
  1515             }
       
  1516             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_WIDGET.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR;
       
  1517         }
       
  1518     elsif ($el eq "NOKIA:icon")
       
  1519         {
       
  1520             chomp($val);
       
  1521             if( lc($val) eq "true" )
       
  1522             {
       
  1523                 $isSharedIcon = 1;
       
  1524             }
       
  1525             $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_ICON.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR;
       
  1526         }
       
  1527     $val = ''
       
  1528     }
       
  1529 
       
  1530   }
       
  1531 
       
  1532 
       
  1533 # Stores the details of files to be added to "rom"
       
  1534 sub addToRomList
       
  1535   {
       
  1536   my ( $self, $drive, $file, $localised ) = @_;
       
  1537   $file = fixFilename($file);
       
  1538 
       
  1539   # All files should be under epoc32 somewhere - need to drop a bit of the path for the rom destination
       
  1540   my $localpath = $self->destLocation($drive);
       
  1541 
       
  1542   my $dest = fixFilename($file);
       
  1543   $dest =~ s/^\Q$localpath\E//i;
       
  1544 
       
  1545   # Add the file to the list for the rom
       
  1546   # It may be localised - in which it'll be put in a different IBY file
       
  1547   $localised = $localised ? '_rsc' : '';
       
  1548   $self->{"installedFiles${localised}"}->{$drive}->{$file} = $dest;
       
  1549   }
       
  1550 
       
  1551 # Make the IBY file
       
  1552 sub makeIBY
       
  1553   {
       
  1554   my ( $self, $drive, $localised ) = @_;
       
  1555 
       
  1556   # Generate the file name for the IBY file
       
  1557   $localised = $localised ? '_rsc' : '';
       
  1558   my $name = $drive =~ /^[zZ]/ ? "preinstalledwidgets${localised}.iby" : sprintf("preinstalledwidgets_drive%s${localised}.iby", substr($drive, 0, 1));
       
  1559   my $iby = fixFilename(catfile($self->{'args'}->{'epocroot'}, 'epoc32', 'rom', 'include', $name));
       
  1560   print "Generating: $iby\n";
       
  1561 
       
  1562   mkpath dirname($iby);
       
  1563   open IBY, ">$iby" or die "Failed to open $iby for writing: $!";
       
  1564   $name =~ s/\./_/g; $name = uc($name);
       
  1565   print IBY "// GENERATED FILE: EDIT WITH CARE\n\#ifndef __${name}__\n\#define __${name}__\n\n";
       
  1566   foreach my $file ( sort keys %{ $self->{"installedFiles${localised}"}->{$drive} } )
       
  1567     {
       
  1568     my $dest = $self->{"installedFiles${localised}"}->{$drive}->{$file};
       
  1569 
       
  1570     # Quote filenames as they may contain spaces!
       
  1571     print IBY "data=\"$file\"\t\"$dest\"\n";
       
  1572     }
       
  1573   print IBY "\#endif\n";
       
  1574   close IBY;
       
  1575   }
       
  1576 
       
  1577 # Unregister (with Apparc) existing Widgets
       
  1578 sub unregisterWidgets
       
  1579 {
       
  1580   my ( $self, $drive ) = @_;
       
  1581     
       
  1582     my $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY));
       
  1583   # If the WRT registry already exists, remove apparc registry info for those widgets
       
  1584   # This should avoid problems with unregistered widget icons in the emulator?
       
  1585     if (-e $registry)
       
  1586     {
       
  1587         print("\n			UNREGISTERING WGZ WIDGETS       \n");
       
  1588         
       
  1589       my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } );
       
  1590     foreach my $entry ( @{ $ref->{entry} } )
       
  1591       {
       
  1592       my $uid = $entry->{prop}->{Uid}->{val}->{content};
       
  1593 
       
  1594       print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose;
       
  1595       my $dest = $self->regFileName($drive);
       
  1596       my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid));
       
  1597       my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) );
       
  1598       unlink $mbm, $reg, $loc;
       
  1599     
       
  1600       # We also have to delete the widget directory otherwise it'll be re-registered
       
  1601       my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content};
       
  1602       $w3c_widget = 0;
       
  1603       my $dir = $self->installDir($drive, $id);
       
  1604       rmtree $dir;
       
  1605       }
       
  1606     }
       
  1607     
       
  1608   $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY));
       
  1609 
       
  1610   # If the CWRT registry already exists, remove apparc registry info for those widgets
       
  1611   # This should avoid problems with unregistered widget icons in the emulator?
       
  1612   if (-e $registry)
       
  1613     {
       
  1614         print("\n			UNREGISTERING WGT WIDGETS       \n");
       
  1615         
       
  1616           my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } );
       
  1617         foreach my $entry ( @{ $ref->{entry} } )
       
  1618       {
       
  1619           my $uid = $entry->{prop}->{Uid}->{val}->{content};
       
  1620     
       
  1621           print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose;
       
  1622           my $dest = $self->regFileName($drive);
       
  1623             my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid));
       
  1624           my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) );
       
  1625           unlink $mbm, $reg, $loc;
       
  1626        
       
  1627           # We also have to delete the widget directory otherwise it'll be re-registered
       
  1628           my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content};
       
  1629           print " Unregistering $id ";
       
  1630           my $basepath = $entry->{prop}->{BasePath}->{val}->{content};
       
  1631           $w3c_widget = 1;
       
  1632           my $sharedLib = "lib";          #BasePath will have lib only if the widget is shared Library
       
  1633           
       
  1634           if($basepath =~ m/$sharedLib/)
       
  1635           {
       
  1636               $isSharedLibrary = 1;
       
  1637           }
       
  1638           
       
  1639           if($basepath =~ m/\\200267d6\\/i)
       
  1640           {
       
  1641           	$non_nokia_widget = 1;	
       
  1642           }
       
  1643            #sharedFolderName TBD
       
  1644           my $dir = $self->installDir($drive, $id);
       
  1645                 rmtree $dir;
       
  1646                 
       
  1647           print("BasePath:$basepath \nIs Non-Nokia? $non_nokia_widget		Is SharedLibrary? $isSharedLibrary \nDirectory:$dir \n");
       
  1648     
       
  1649             $dir =~ s/widgets_21D_4C7/data/;
       
  1650           rmtree $dir;
       
  1651         }
       
  1652     }
       
  1653     #delete CWRT webapp DB if exists
       
  1654     my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY);
       
  1655     if($cwrtdbPath)
       
  1656     {
       
  1657     	print "Deleting CWRT_WEBAPP_REGISTRY \n";
       
  1658     	rmtree $cwrtdbPath;
       
  1659     }
       
  1660   }
       
  1661 
       
  1662 # Make the registry
       
  1663 sub makeRegistry
       
  1664   {
       
  1665   my ($self, $drive, $installed, $w3c) = @_;
       
  1666   
       
  1667   my ($registry);
       
  1668   if($w3c)
       
  1669     {
       
  1670     $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY));
       
  1671     }
       
  1672   else
       
  1673     {
       
  1674     $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY));
       
  1675     }
       
  1676     
       
  1677   print "\nGenerating: $registry\n";
       
  1678 
       
  1679   # Write the file
       
  1680   mkpath dirname($registry);
       
  1681   open OUT, ">$registry" or die "Failed to open WidgetEntryStore.xml: $!";
       
  1682 
       
  1683   print OUT "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\" ?>\n<widgetregistry>\n";
       
  1684   binmode OUT, ":utf8" if $] >= 5.008;
       
  1685   foreach my $pList ( @$installed )
       
  1686     {
       
  1687     $self->dumpPList(\*OUT, $pList, $w3c);
       
  1688     }
       
  1689   print OUT "</widgetregistry>\n";
       
  1690   close OUT;
       
  1691 
       
  1692   # Convert the file to unicode
       
  1693   convert2Unicode($registry);
       
  1694 
       
  1695   # Return the generated file
       
  1696   return $registry;
       
  1697   }
       
  1698 
       
  1699 # Converts a file to Unicode
       
  1700 sub convert2Unicode
       
  1701   {
       
  1702   my $file = shift;
       
  1703 
       
  1704   my @lines;
       
  1705   open IN, $file or die "Failed to open $file: $!";
       
  1706   binmode IN;
       
  1707   while(<IN>)
       
  1708     {
       
  1709     my $u = utf8($_);
       
  1710     $u->byteswap;
       
  1711     push @lines, $u->utf16;
       
  1712     }
       
  1713   close IN;
       
  1714 
       
  1715   open OUT, ">$file" or die "Failed to open $file for writing: $!";
       
  1716   binmode OUT;
       
  1717   print OUT pack("CC", 0xff, 0xfe);
       
  1718   print OUT @lines;
       
  1719   close OUT;
       
  1720   }
       
  1721 
       
  1722 sub hashpjw {
       
  1723   my $s = shift;
       
  1724   my $hashval = 0;
       
  1725   my $g;
       
  1726 
       
  1727   for ( split //, $s ) {
       
  1728     $hashval = ( $hashval << 4 ) + ord $_; 
       
  1729     
       
  1730     if ($g = $hashval & 0xf0000000) {
       
  1731       $hashval ^= $g >> 23;
       
  1732     }
       
  1733     $hashval &= ~$g;
       
  1734   }
       
  1735   #print "$hashval \n";
       
  1736   return $hashval;
       
  1737 } 
       
  1738 
       
  1739 # Dumps a single PList hash object
       
  1740 sub dumpPList
       
  1741   {
       
  1742   my ($self, $fh, $data, $w3c) = @_;
       
  1743   my @regProperties = (
       
  1744     [ 'PropertyListVersion', 'int' ],
       
  1745     [ 'BundleIdentifier', 'string' ],
       
  1746     [ 'BundleName', 'string' ],
       
  1747     [ 'BundleDisplayName', 'string' ],
       
  1748     [ 'MainHTML', 'string' ],
       
  1749     [ 'BundleVersion', 'string' ],
       
  1750  #  [ 'Height', 'int' ],
       
  1751  #  [ 'Width', 'int' ],
       
  1752     [ 'AllowNetworkAccess', 'int' ],
       
  1753     [ 'DriveName', 'string' ],
       
  1754     [ 'BasePath', 'string' ],
       
  1755     [ 'IconPath', 'string' ],
       
  1756     [ 'FileSize', 'int' ],
       
  1757     [ 'Uid', 'int' ],
       
  1758     [ 'NokiaWidget', 'int' ],
       
  1759     [ 'MiniViewEnabled', 'int' ],
       
  1760     [ 'ProcessUid', 'int' ],
       
  1761     [ 'MimeType', 'string'],
       
  1762     [ 'WidgetPackagingFormat', 'string'],
       
  1763     [ 'DBIconPath', 'string'],
       
  1764     [ 'AttributeList', 'string'],
       
  1765     [ 'BlanketPermissionGranted', 'int' ],
       
  1766     [ 'PreInstalled', 'int' ],
       
  1767   );
       
  1768     
       
  1769   print $fh "<entry>\n";
       
  1770   my $encodeddata = {};
       
  1771   foreach my $prop ( @regProperties )
       
  1772     {
       
  1773     my ( $key, $type ) = @$prop;
       
  1774     if($key ne "DBIconPath" && $key ne "WidgetPackagingFormat" && $key ne "AttributeList" && $key ne "BlanketPermissionGranted" && $key ne "PreInstalled")
       
  1775     {
       
  1776         print $fh "<prop>$key<val>$data->{$key}<type>$type</type></val></prop>\n" if defined $data->{$key};
       
  1777     }
       
  1778     
       
  1779     if( $w3c )
       
  1780       {
       
  1781       $encodeddata->{$key} = encodeChar($data->{$key}) if defined $data->{$key};
       
  1782       }
       
  1783     else
       
  1784     {
       
  1785     	if($key eq "BlanketPermissionGranted" || $key eq "PreInstalled")
       
  1786     	{
       
  1787     	 print $fh "<prop>$key<val>$data->{$key}<type>$type</type></val></prop>\n" if defined $data->{$key};
       
  1788     	}
       
  1789     }
       
  1790     }
       
  1791   print $fh "</entry>\n";
       
  1792   print "\n Is a w3c widget? -- $w3c\n";
       
  1793   if( $w3c )
       
  1794     {
       
  1795   my $dbPath = fixFilename(catfile($self->destLocation('C'), CWRT_WEBAPP_REGISTRY));
       
  1796     mkpath dirname($dbPath);
       
  1797     die "ERROR: Can't find CWRTWebAppRegistry.exe in PATH" if !(my $cmd = findCmd('CWRTWebAppRegistry.exe'));
       
  1798     my $regCmd;
       
  1799     
       
  1800     if($encodeddata->{'AttributeList'})
       
  1801     {
       
  1802         print "\n AttributeList argument sent to DB\n";
       
  1803         $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'} $encodeddata->{'AttributeList'}";
       
  1804     }
       
  1805     else
       
  1806    {
       
  1807         print "\n AttributeList argument not sent to DB\n";
       
  1808         $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'}";
       
  1809     }
       
  1810     print "\n regCmd : $regCmd \n\n";
       
  1811     system($regCmd);
       
  1812     }
       
  1813   }
       
  1814 
       
  1815 #encode the space character
       
  1816 sub encodeChar  
       
  1817   {
       
  1818     my  ($encoded) = @_;
       
  1819 
       
  1820     $encoded =~ s/%/%10/g;
       
  1821     $encoded =~ s/\s/%40/g;
       
  1822     $encoded =~ s/\'/%apos/g;   
       
  1823     $encoded =~ s/&/%amp/g;
       
  1824     $encoded =~ s/</%lt/g;
       
  1825     $encoded =~ s/>/%gt/g;
       
  1826     $encoded =~ s/\"/%quot/g;
       
  1827     return $encoded;
       
  1828   }
       
  1829   
       
  1830   
       
  1831 # Make secssion
       
  1832 sub makeSecSession
       
  1833     {
       
  1834   my ($self, $drive) = @_;
       
  1835   my $secSession;
       
  1836   my $widget_uid;
       
  1837   if($non_nokia_widget)
       
  1838 	{
       
  1839 		$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
       
  1840 	}
       
  1841 	else
       
  1842 	{
       
  1843   	$widget_uid = CWRT_WIDGET_UI_UID;
       
  1844   }
       
  1845 
       
  1846   if($isSharedLibrary)
       
  1847   {
       
  1848       $secSession = fixFilename(catfile($self->destLocation($drive), 'Private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName,"secsession"));
       
  1849   }
       
  1850   else
       
  1851   {
       
  1852       $secSession = fixFilename(catfile($self->destLocation($drive), 'Private', sprintf("%08X", $widget_uid),"data", $hashval,"secsession"));
       
  1853   }
       
  1854   print "\nGenerating: $secSession\n\n";
       
  1855   
       
  1856   # Write the file
       
  1857   mkpath dirname($secSession);
       
  1858   open OUT, ">$secSession" or die "Failed to open SecSession.xml: $!";
       
  1859 
       
  1860   print OUT "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n<accesspolicy>\n";
       
  1861   if($non_nokia_widget)
       
  1862   {
       
  1863   	print OUT "<domain name=\"Operator\">\n";
       
  1864   }
       
  1865   else
       
  1866   {
       
  1867   	print OUT "<domain name=\"TrustedWidgets\">\n";
       
  1868   }
       
  1869   
       
  1870   if(CWRT_ACCESS_POLICY_PATH) {
       
  1871       my $accesspolicypath = findCmd(CWRT_ACCESS_POLICY_PATH);   
       
  1872         # Copy Secsession capabilities from browser_access_policy.xml if it exists
       
  1873       if (-e $accesspolicypath) {
       
  1874           print "Browser Access Policy File exists :: ",$accesspolicypath,"\n" ;
       
  1875           my $accesspolicy = XMLin($accesspolicypath, keyattr => {domain => 'name'}, forcearray =>['domain'] );
       
  1876             my $domainName;
       
  1877             
       
  1878             if($non_nokia_widget)
       
  1879             {
       
  1880             	$domainName = $accesspolicy->{domain}->{Operator};
       
  1881             }
       
  1882             else
       
  1883             {
       
  1884             	$domainName = $accesspolicy->{domain}->{TrustedWidgets};
       
  1885             }
       
  1886           
       
  1887           my $xml = XMLout($domainName, keeproot => 1);
       
  1888           print OUT $xml;
       
  1889       }
       
  1890       #browser_access_policy.xml does not exist in the path
       
  1891       else {      
       
  1892           print "\n Browser Access policy file '$accesspolicypath' does not exist in the given path\n";
       
  1893           if(!$non_nokia_widget)
       
  1894           {
       
  1895           	print OUT "   <capability name=\"Download\"/>\n   <capability name=\"ApplicationManagement\"/>\n   <capability name=\"WebAppUpdate\"/>\n   <capability name=\"DeviceConfiguration\"/>\n   <capability name=\"NokiaAccount\"/>\n   <capability name=\"ConnectionManagement\"/>\n   <capability name=\"ApplicationManagement.Launch\"/>\n   <capability name=\"SecureStorage\"/>\n   <capability name=\"EventsAndMessaging\"/>\n   <capability name=\"Vibra\"/>\n   <capability name=\"RuntimeInfo\"/>\n   <capability name=\"OviMessagingBus\"/>\n   <capability name=\"NativeUpdate\"/>\n   <capability name=\"LocalConnectivity\"/>\n   <capability name=\"Network\"/>\n   <capability name=\"Cryptographic\"/>\n   <capability name=\"pim.*\"/>\n   <capability name=\"devicestatus.*\"/>\n   <capability name=\"message.*\"/>\n   <capability name=\"sensor.*\"/>\n   <capability name=\"landmark.*\"/>\n   <capability name=\"camera.*\"/>\n   <capability name=\"commlog.*\"/>\n   <capability name=\"media.*\"/>\n   <capability name=\"io.file.*\"/>\n   <capability name=\"player.*\"/>\n   <capability name=\"location.position\"/>\n   <capability name=\"telephony.voicecall\"/>\n   <capability name=\"NokiaAdEnabler\"/>\n";
       
  1896           }
       
  1897         }
       
  1898     }
       
  1899     #Access policy path not defined
       
  1900   else {
       
  1901       print "\n Browser Access policy path not defined \n";
       
  1902       if(!$non_nokia_widget)
       
  1903       {
       
  1904       	print OUT "   <capability name=\"Download\"/>\n   <capability name=\"ApplicationManagement\"/>\n   <capability name=\"WebAppUpdate\"/>\n   <capability name=\"DeviceConfiguration\"/>\n   <capability name=\"NokiaAccount\"/>\n   <capability name=\"ConnectionManagement\"/>\n   <capability name=\"ApplicationManagement.Launch\"/>\n   <capability name=\"SecureStorage\"/>\n   <capability name=\"EventsAndMessaging\"/>\n   <capability name=\"Vibra\"/>\n   <capability name=\"RuntimeInfo\"/>\n   <capability name=\"OviMessagingBus\"/>\n   <capability name=\"NativeUpdate\"/>\n   <capability name=\"LocalConnectivity\"/>\n   <capability name=\"Network\"/>\n   <capability name=\"Cryptographic\"/>\n   <capability name=\"pim.*\"/>\n   <capability name=\"devicestatus.*\"/>\n   <capability name=\"message.*\"/>\n   <capability name=\"sensor.*\"/>\n   <capability name=\"landmark.*\"/>\n   <capability name=\"camera.*\"/>\n   <capability name=\"commlog.*\"/>\n   <capability name=\"media.*\"/>\n   <capability name=\"io.file.*\"/>\n   <capability name=\"player.*\"/>\n   <capability name=\"location.position\"/>\n   <capability name=\"telephony.voicecall\"/>\n   <capability name=\"NokiaAdEnabler\"/>\n";
       
  1905       }
       
  1906   }
       
  1907    
       
  1908     print OUT "</domain>\n";
       
  1909     print OUT "</accesspolicy>\n";
       
  1910     close OUT;
       
  1911 
       
  1912   # Return the generated file
       
  1913   return $secSession;
       
  1914   }
       
  1915 __END__
       
  1916 
       
  1917 =head1 NAME
       
  1918 
       
  1919 installwidgets.pl - A script for generating all the files needed to install Widgets
       
  1920 
       
  1921 =head1 SYNOPSIS
       
  1922 
       
  1923 installwidgets.pl [-h] [-ver] [-v] [-debug] [-e <dir>] [-l <lang_code|lproj.xml>] config.ini
       
  1924 
       
  1925  Options:
       
  1926    -help|h                        Show this help
       
  1927    -version|ver                   Show version number
       
  1928    -verbose|v                     Show verbose output
       
  1929    -debug                         Show debug output
       
  1930    -epocroot|e                    Override value of EPOCROOT
       
  1931    -localization|l                lproj_dir
       
  1932 
       
  1933 A script for generating all the files needed to preinstall Widgets.
       
  1934 
       
  1935  Example:
       
  1936    perl installwidgets.pl -l fr config.ini       Install widgets listed in config.ini using French localization
       
  1937 
       
  1938  Author:
       
  1939    peter.harper@sosco.com
       
  1940 
       
  1941 =head1 DESCRIPTION
       
  1942 
       
  1943 This tool can be used to pre-generate all the files needed to install Widgets. The tool and its dependencies can be placed anywhere on your PATH.
       
  1944 It generates the results in the epoc32 folder - in the appropriate locations for the emulator.
       
  1945 It finds the epoc32 folder using the EPOCROOT environment variable which can be overridden via the -e command line option.
       
  1946 
       
  1947 =head2 CONFIG FILE
       
  1948 
       
  1949 The preferred way to run the tool is via a configuration INI file.
       
  1950 You can list the widgets to install on each drive. You can specify the exact location of the Widget, otherwise it will try and find the Widget via EPOCROOT.
       
  1951 
       
  1952 You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename
       
  1953 This will set the BlanketPermissionGranted attribute in the registry.
       
  1954 Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated.
       
  1955 
       
  1956     # Widgets to be pre-installed for the ROM
       
  1957     [drive-z]
       
  1958     \somepath\foo.wgz
       
  1959     \somepath\bar.wgz
       
  1960 
       
  1961     # Widgets for the internal disk
       
  1962     [drive-c]
       
  1963     \somepath\widget1.wdgt.zip [HomeScreen]
       
  1964 
       
  1965     # Widgets for the removable disk
       
  1966     [drive-e]
       
  1967     \somepath\widget2.wdgt.zip
       
  1968 
       
  1969     # Commands to run at the end
       
  1970     [run-commands]
       
  1971     dostuff.pl
       
  1972     domorestuff.exe
       
  1973 
       
  1974 =head2 DEPENDENCIES
       
  1975 
       
  1976 The tool has some dependencies which must exist for it to work.
       
  1977 
       
  1978 =over
       
  1979 
       
  1980 =item 1
       
  1981 
       
  1982 png2mbm.pl - A script to generate an MBM file from a PNG
       
  1983 
       
  1984 =item 2
       
  1985 
       
  1986 WidgetRegFiles.exe - an EXE which can generate Symbian REG and LOC files for registering non-native Widget apps.
       
  1987 This tool is built with "SymPort" a native tools port of basic Symbian OS services.
       
  1988 
       
  1989 =item 3
       
  1990 
       
  1991 7z/unzip - For extracting files from the Widget archive.
       
  1992 7Zip will be used in preference to unzip if it's found on your path because it handles Unicode a better.
       
  1993 
       
  1994 =item 4
       
  1995 
       
  1996 GD.pm - Perl support for the GD graphics library for PNG support, see http://www.libgd.org .
       
  1997 
       
  1998 =back
       
  1999 
       
  2000 =head3 INSTALLING GD
       
  2001 
       
  2002 You can install GD automatically with a simple command - however the command you need to use differs depending on the version of Perl you have installed.
       
  2003 At the time of writing Symbian requires Perl version 5.6 - although in my experience Perl 5.8 works okay. To find out which version of Perl you have type "perl -v" on the command line.
       
  2004 
       
  2005 To install the GD library:
       
  2006 
       
  2007 =over
       
  2008 
       
  2009 =item *
       
  2010 
       
  2011 For Perl v5.6: "ppm install http://theoryx5.uwinnipeg.ca/ppmpackages/GD.ppd "
       
  2012 
       
  2013 =item *
       
  2014 
       
  2015 For Perl v5.8: "ppm install http://theoryx5.uwinnipeg.ca/ppms/GD.ppd "
       
  2016 
       
  2017 =back
       
  2018 
       
  2019 =head2 WIDGET INSTALL PROCESS
       
  2020 
       
  2021 Here's a detailed breakdown of what the script does.
       
  2022 
       
  2023 =over
       
  2024 
       
  2025 =item 1
       
  2026 
       
  2027 It gets the lists of Widgets from the config.ini file passed on the command line.
       
  2028 This process is repeated for all Widgets and all drives listed in the config file.
       
  2029 
       
  2030 =item 2
       
  2031 
       
  2032 Any existing Widgets listed in "private\10282f06\WidgetEntryStore.xml" are deleted from the epoc32 tree.
       
  2033 This ensures that there are no problems when testing Widgets in the emulator.
       
  2034 
       
  2035 =item 3
       
  2036 
       
  2037 All the compressed files in the Widget are extracted to a temporary folder.
       
  2038 
       
  2039 =item 4
       
  2040 
       
  2041 The details for the Widget are loaded from its "Info.plist" file.
       
  2042 
       
  2043 =item 5
       
  2044 
       
  2045 A UID is chosen for the widget. This differs depending on whether installation is for an internal drive (z: or c:) or an external drive (e: etc).
       
  2046 
       
  2047 =item 5
       
  2048 
       
  2049 A Symbian MBM file is generated from the "Icon.png" file supplied by the Widgets.
       
  2050 Three different sized icons are generated "88x88", "32x32" and "24x24".
       
  2051 The MBM file is placed in "private/10003a3f/import/apps/NonNative/Resource/[<UID>].mbm".
       
  2052 
       
  2053 =item 6
       
  2054 
       
  2055 "WidgetRegFiles.exe" is executed to generate REG and LOC resource files used to register the Widget as an app in Symbian OS.
       
  2056 These files are placed in "private/10003a3f/import/apps/NonNative/Resource".
       
  2057 
       
  2058 =item 7
       
  2059 
       
  2060 All the widgets files are copied to a folder under "private\10282822".
       
  2061 The Widget's bundle identifier is used to create a unique folder under here for the Widget.
       
  2062 
       
  2063 =item 8
       
  2064 
       
  2065 The Widget registry is generated in "private\10282f06\WidgetEntryStore.xml"
       
  2066 
       
  2067 =item 9
       
  2068 
       
  2069 If Widgets are being preinstalled for ROM an IBY file is created in "epoc32\rom\include\preinstalledwidgets.iby".
       
  2070 A separate IBY file is generated for the localised parts of a Widget "epoc32\rom\include\preinstalledwidgets_rsc.iby".
       
  2071 Separate IBY files (per drive) are generated for Widgets preinstalled to UDA, e.g. preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby.
       
  2072 These IBY files can be used to add all the Widgets to ROM, ROFS or UDA.
       
  2073 
       
  2074 =back
       
  2075 
       
  2076 =head3 INSTALLING ON HARDWARE USING iMaker
       
  2077 
       
  2078 =over
       
  2079 
       
  2080 =item 1
       
  2081 
       
  2082 Create the following folder structure at the root level.
       
  2083 
       
  2084 X:\variants\content
       
  2085 
       
  2086 =item 2
       
  2087 
       
  2088 Copy the files specified in the generated ibys (preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby) to X:\variants\content. Preserve the dir structure. (Note, this step will be automated in the future)
       
  2089 
       
  2090 For example if you want the following file on UDA (User Disk Area, C drive on phone) at the following location C:\private\10282f06\WidgetEntryStore.xml
       
  2091 
       
  2092 Drop the file under X:\variants\content\private\10282f06\WidgetEntryStore.xml 
       
  2093 
       
  2094 =item 3
       
  2095 
       
  2096 Run the foll command to generate UDA
       
  2097 
       
  2098 B<Gadget:>
       
  2099 X:\epoc32\tools>imaker -f /epoc32/rom/s60_makefiles/image_conf_sp_rnd_gadget.mk VARIANT_DIR=/variants variantuda
       
  2100 
       
  2101 B<Tube:>
       
  2102 Y:\epoc32\tools>imaker -f /epoc32/rom/config/ncp52/tube/image_conf_tube_ui.mk VARIANT_DIR=/variants variantuda 
       
  2103 
       
  2104 =item 4
       
  2105 
       
  2106 Flash the fpsx file generated under X:\epoc32\rombuild\gadget\uda for Gadget and Y:\epoc32\rombuild\tube\uda for Tube to your device.
       
  2107 
       
  2108 Note: More info on iMaker tool at: L<http://configurationtools.nmp.nokia.com/imaker/wiki/iMakerUserGuide>
       
  2109 
       
  2110 =back
       
  2111 
       
  2112 =head3 LOCALISATION
       
  2113 
       
  2114 Widget handles localization by providing localized resources in various language project directories(lproj_dir), one level deep than the root directory. In order to specify a language variant for pre-installing widget, you need to provide the language project directory name, e.g. 'en' for english, 'fr' for French.
       
  2115 
       
  2116 A list of Nokia supported languages can be found in Widget_lproj.xml or at L<http://wiki.forum.nokia.com/index.php/Web_Runtime_localisation_support>. If the widget does not provide the localized resource for the variant you specified, the default resources in widget's home directory will be used instead. 
       
  2117 
       
  2118 =head3 NOTES
       
  2119 
       
  2120 =over
       
  2121 
       
  2122 =item 1
       
  2123 
       
  2124 The location of the private folder is in the appropriate place for the files to appear in the emulator.
       
  2125 This is different depending on the intended destination drive (see -dd command line option) for the Widget.
       
  2126 e.g. "epoc32/release/winscw/udeb/z/", "epoc32/winscw/c" or "epoc32/winscw/e"
       
  2127 
       
  2128 =item 2
       
  2129 
       
  2130 Files are extracted to epoc32 on the current drive relative to the EPOCROOT environment variable or the value given for -epocroot (-e) on the command line.
       
  2131 
       
  2132 =item 3
       
  2133 
       
  2134 A different IBY file is generated for each drive.
       
  2135 
       
  2136 =over
       
  2137 
       
  2138 =item *
       
  2139 
       
  2140 Z: - \epoc32\rom\include\preinstalledwidgets.iby
       
  2141 
       
  2142 =item *
       
  2143 
       
  2144 C: - \epoc32\rom\include\preinstalledwidgets_driveC.iby
       
  2145 
       
  2146 =item *
       
  2147 
       
  2148 E: - \epoc32\rom\include\preinstalledwidgets_driveE.iby
       
  2149 
       
  2150 =back
       
  2151 
       
  2152 There are separate resource files for localised resources e.g. preinstalledwidgets_rsc.iby.
       
  2153 
       
  2154 =cut