widgettools/wrtwidgetpreinstaller/src/installwidgets.pl
branchRCL_3
changeset 18 04b7640f6fb5
child 19 60c10715f092
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/widgettools/wrtwidgetpreinstaller/src/installwidgets.pl	Wed Sep 01 12:32:13 2010 +0100
@@ -0,0 +1,2156 @@
+#
+# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+use strict;
+use warnings;
+use File::Spec::Functions;
+use Getopt::Long;
+use Pod::Usage;
+
+# Version of the script - just use the date
+$main::VERSION = '12-July-2010';
+
+# New getopt::long provides this - but old version doesn't?
+sub version
+  {
+  print sprintf("$0: $main::VERSION\n$^X: %vd\nos: $^O", $^V);
+  exit;
+  }
+
+# Get arguments
+my ( $help, $version, $verbose, $debug, $epocroot, $l10n );
+GetOptions( "help" => \$help, "version|ver" => \$version,
+      "verbose|v" => \$verbose,  "debug" => \$debug,
+      "epocroot|e=s" => \$epocroot, "localization|l=s" => \$l10n )
+  or pod2usage('Invalid parameters');
+
+# Handle help and version
+pod2usage({ verbose => 1, exitval => 0}) if $help;
+version() if $version;
+
+# Interpret arguments
+$verbose = 1 if $debug;
+$verbose = $verbose ? '-v' : '';
+$epocroot = $ENV{EPOCROOT} if !$epocroot;
+
+# Interpret localization l10n argument
+
+# There are two modes.  In one mode you specify the location of a
+# lproj.xml file and the code computes l10n files for all languages so
+# that runtime locale selection should work.  In the other mode you
+# specify a language code (example, fr for French) and the code
+# computes l10n just for that language.
+$l10n = '' if !$l10n;
+my $lproj = '';
+if ($l10n =~ /lproj\.xml$/i)
+  {
+  $lproj = $l10n;
+  $l10n = '';
+  }
+
+my ($configini, @unnecessary) = @ARGV;
+
+if ($configini)
+  {
+  # There shouldn't be any need for any other arguments
+  pod2usage('Unnecessary arguments supplied.') if @unnecessary;
+
+  # Now do the installation
+  my $installer = WidgetInstaller->new('verbose' => $verbose, 'debug' => $debug, 'epocroot' => $epocroot, 'lproj' => $lproj, 'l10n' => $l10n);
+  $installer->installConfig($configini);
+  }
+else
+  {
+  pod2usage('Missing config.ini argument.');
+  }
+
+# ***
+# Package for installing Widgets
+#
+
+package WidgetInstaller;
+
+use File::Spec::Functions;
+use File::Path;
+use File::Basename;
+use Unicode::String qw(utf8 utf16);
+use File::Temp qw/tempdir/;
+use File::Copy;
+use XML::Parser;
+use Data::Dumper;
+use XML::Simple;
+
+# CONSTANTS
+use constant ICON_SIZES => "88,32,24";      # Size of icons to generate in the MBM file
+#use constant INTERNAL_UID_LOWER => 0x2000DAD2; # Lower UID bound for midlets installed to internal drives and rom
+#use constant EXTERNAL_UID_LOWER => 0x2000DCC6; # Lower UID bound for midlets installed to removable cards
+use constant INTERNAL_UID_LOWER_WRT => 0x2000DAD2;  # Lower UID bound for WRT widgets installed to internal drives and rom
+use constant INTERNAL_UID_LOWER_CWRT => 0x2000DBCC; # Lower UID bound for CWRT widgets installed to internal drives and rom
+use constant EXTERNAL_UID_LOWER_WRT => 0x2000DCC6;  # Lower UID bound for WRT widgets installed to removable cards
+use constant EXTERNAL_UID_LOWER_CWRT => 0x2000DDC0; # Lower UID bound for CWRT widgets installed to removable cards
+use constant WIDGET_UI_UID => 0x10282822;   # UID of the widget app
+use constant CWRT_WIDGET_UI_UID => 0x200267C0;    # UID of the cwrt widget app
+use constant SWIDGET_UI_UID => 0x102829A0;	# UID of the securewidget app
+use constant CWRT_WIDGET_UI_NON_NOKIA_UID => 0x200267D6;    # UID of the cwrt widget app
+
+# Folder paths
+use constant DESTINATION => 'private/10003a3f/import/apps/NonNative/Resource';
+use constant ROM_DEST => 'epoc32/release/winscw/udeb/Z/';
+use constant DRIVE_DEST => 'epoc32/winscw/%s';
+use constant WIDGET_REGISTRY => 'private/10282f06/WidgetEntryStore.xml';
+use constant CWRT_WIDGET_REGISTRY => 'private/10282f06/CWRTWidgetEntryStore.xml';
+use constant CWRT_WEBAPP_REGISTRY => 'private/200267D9/webapp_registry.db';
+use constant CWRT_ACCESS_POLICY_PATH => 'browser_access_policy.xml';
+use constant WIDGET_NAME => 'en-gb/widget/name';
+use constant WIDGET_PROCESSUID => 'processUid';
+use constant WIDGET_ID => 'widget/id';
+use constant WIDGET_VERSION => 'widget/version';
+use constant WIDGET_CONTENT => 'widget/content';
+use constant WIDGET_FEATURE => 'widget/feature/';
+use constant WIDGET_FEATURE_PARAM => '/param/';
+use constant WIDGET_ACCESS => 'widget/access/';
+use constant WIDGET_HEIGHT => 'widget/height';
+use constant WIDGET_WIDTH => 'widget/width';
+use constant WIDGET_NOKIA_SHAREDLIB => 'widget/NOKIA:sharedlibrary';
+use constant WIDGET_NOKIA_SHAREDLIB_FOLDER => 'widget/NOKIA:sharedlibrary/NOKIA:folder';
+use constant WIDGET_NOKIA_SHAREDLIB_WIDGET => 'widget/NOKIA:sharedlibrary/NOKIA:widget';
+use constant WIDGET_NOKIA_SHAREDLIB_ICON => 'widget/NOKIA:sharedlibrary/NOKIA:icon';
+use constant KEY_VALUE_SEPERATOR => ',';
+use constant KEY_VALUE_PAIR_SEPERATOR => ';';
+use constant KEY_ATTR_SEPERATOR => ':';
+
+our $w3c_widget = 0 ;
+our $hashval;
+our $non_nokia_widget = 0;
+our ($isSharedLibrary, $sharedFolderName ,$isSharedWidget, $isSharedIcon)= (0,'',0,0);
+our (@staticUidWrtIntList,@staticUidCwrtIntList,@staticUidWrtExtList,@staticUidCwrtExtList) = ({},{},{},{});
+our $isSecureWidget = 0;
+
+# Create a new object
+sub new
+  {
+  my $invocant = shift;
+  my $self = bless({}, ref $invocant || $invocant);
+
+  my %args = @_;
+  $self->{'args'} = \%args;
+  $self->{'args'}->{'verbose'} = $self->{'args'}->{'verbose'} ? '-v' : '';
+
+  $self->{'installedFiles'} = ();
+  $self->{'freeuidwrtint'} = INTERNAL_UID_LOWER_WRT;
+  $self->{'freeuidwrtext'} = EXTERNAL_UID_LOWER_WRT;
+  $self->{'freeuidcwrtint'} = INTERNAL_UID_LOWER_CWRT;
+  $self->{'freeuidcwrtext'} = EXTERNAL_UID_LOWER_CWRT;
+  $self->{'langmapping'} = $self->getLangMapping($self->{'args'}->{'lproj'}) unless $self->{'args'}->{'l10n'};
+  
+  #Check if localisation argument is land number ID; If true, get the lang Name using langmapping file - Widget_lproj.xml 
+  if ($l10n =~ /\d+$/)
+  {
+    print "\nLANG ID given as localisation argument :: $l10n \n";
+    $self->{'langmapping'} = $self->getLangMapping();
+    
+    if($self->{'langmapping'})
+    {
+      # Iterate through all the languages we know about
+      for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++)
+      {
+        my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] );
+        if($l10n == $langid)
+        {
+          print "Setting argument to LangName - $langname \n";
+          $self->{'args'}->{'l10n'} = lc($langname);
+          last;
+        }
+      }
+    }
+  }
+
+  return $self;
+  }
+  
+# Gets the language mapping from the Widget_lproj.xml file
+sub getLangMapping
+  {
+  my ( $self, $lproj ) = @_;
+
+  # Get the LPROJ file which specifies lang id mappings
+  if (!$lproj)
+    {
+    (my $EPOCROOT = $ENV{EPOCROOT}) =~ s/[\/\\]+$//;
+    $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/winscw/c/private/10282f06/Widget_lproj.xml");
+    $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/winscw/c/private/10282f06/Widget_lproj.xml") if !-e $lproj;
+    $lproj = WidgetInstaller::fixFilename("${epocroot}epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj;
+    $lproj = WidgetInstaller::fixFilename("$EPOCROOT/epoc32/data/Z/private/10282f06/Widget_lproj.xml") if !-e $lproj;
+    $lproj = WidgetInstaller::fixFilename("${epocroot}S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj;
+    $lproj = WidgetInstaller::fixFilename("$EPOCROOT/S60/mw/web/WebEngine/WidgetRegistry/Data/Widget_lproj.xml") if !-e $lproj;
+    $lproj = WidgetInstaller::findCmd('Widget_lproj.xml') if !-e $lproj;
+    $lproj = WidgetInstaller::findCmd('internal/Widget_lproj.xml') if !-e $lproj;
+    undef $lproj if !-e $lproj;
+
+    # Display a warning if localisation can't be performed
+    warn "WARNING: Can't find Widget_lproj.xml - localisation is disabled.\n" if !$lproj;
+    }
+
+  # Load the mapping file
+  if ($lproj)
+    {
+    die "Can't find $lproj file." if !-e $lproj;
+    print "Localisation support enabled using config: $lproj\n" if $verbose;
+    my $mapping = XMLin($lproj);
+    print "Found ", scalar(@{ $mapping->{'LangID'} }), " language mappings.\n" if $verbose;
+    return $mapping;
+    }
+  }
+
+# Install Widgets listed in config file
+# Format is as follows where "drive-z" specifies widgets for drive z: etc...
+# Comments are okay - they start with a # character
+# If the file doesn't exist as given then EPOCROOT is prepended to the filename to try and find it
+#
+# You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename
+# This will set the BlanketPermissionGranted attribute in the registry.
+# Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated.
+#
+# You can specify commands to run before exit after a [run-commands] or [homescreen-processor] 
+#
+# [drive-z]
+# \path\widget1.wgz
+# widget2.wdgt.zip [HomeScreen]
+#
+# [drive-e]
+# widget3.wgz
+#
+# [run-commands]
+# dostuff.pl
+#
+
+sub installConfig
+  {
+  my ( $self, $file ) = @_;
+  $self->{'installedFiles'} = ();
+
+  my ( %installData, $sectionName );
+  open CONFIG, $file or die "Failed to open config file $file: $!";
+  
+  # Loop for gathering STATIC UIDs allocated for widgets in config INI file
+  while(my $line = <CONFIG>)
+  {
+    # Ignore comments
+    $line =~ s/\#.*$//;
+    
+    if ($line =~ /^\[([^\]]+)\]/)
+      {
+      $sectionName = lc $1;
+      next;
+      }
+
+    # Process sections after this point
+    next if !$sectionName;
+    chomp $line;
+
+    # Have we found a list of widgets?
+    if ($sectionName =~ /^drive-([a-z])/)
+    {
+      my $drive = uc($1);
+      #Assuming Static UID given in ini are within int/ext/wgt/wgz specified ranges
+      # Add Static UID to the respective list
+      if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i)
+      {
+        if ($3)
+        {
+          my $uid = hex($3);
+          
+          if ($drive =~ /^[zcZC]/)
+          {
+            if(($uid >= INTERNAL_UID_LOWER_WRT) && ($uid < INTERNAL_UID_LOWER_CWRT))
+            {
+              push(@staticUidWrtIntList,$uid) ;
+            }
+            else
+            {
+              push(@staticUidCwrtIntList,$uid);
+            }
+          }
+          else
+          {
+            if(($uid >= EXTERNAL_UID_LOWER_WRT) && ($uid < EXTERNAL_UID_LOWER_CWRT))
+            {
+              push(@staticUidWrtExtList,$uid) ;
+            }
+            else
+            {
+              push(@staticUidCwrtExtList,$uid) ;
+            }
+          }
+        }
+      }
+    }
+  }
+  close CONFIG;
+  @staticUidWrtIntList = sort(@staticUidWrtIntList);
+  print "SORTED WRT INTERNAL STATIC UID  @staticUidWrtIntList \n";
+  @staticUidCwrtIntList = sort(@staticUidCwrtIntList);
+  print "SORTED CWRT INTERNAL STATIC UID  @staticUidCwrtIntList \n";
+  @staticUidWrtExtList = sort(@staticUidWrtExtList);
+  print "SORTED WRT EXTERNAL STATIC UID @staticUidWrtExtList \n";
+  @staticUidCwrtExtList = sort(@staticUidCwrtExtList);
+  print "SORTED CWRT EXTERNAL STATIC UID @staticUidCwrtExtList \n";
+  
+  open CONFIG, $file or die "Failed to open config file $file: $!";
+  # Main loop which reads the config INI line by line and installs widgets[wgz/wgt] in respective drives
+  while(my $line = <CONFIG>)
+    {
+    # Ignore comments
+    $line =~ s/\#.*$//;
+
+    if ($line =~ /^\[([^\]]+)\]/)
+      {
+      $sectionName = lc $1;
+      
+      # Remember destination if any specified
+      if ($sectionName =~ /^drive-([a-z])=(.+)$/)
+        {
+        $self->{'destination'}->{uc($1)} = $2;
+        }
+      next;
+      }
+
+    # Process sections after this point
+    next if !$sectionName;
+    chomp $line;
+
+    # Have we found a list of widgets?
+    if ($sectionName =~ /^drive-([a-z])/)
+      {
+      my $drive = uc($1);
+      
+      # Add to the list of Widget files
+      if ($line =~ /^(.+?\.(?:wdgt\.zip|wgz|wgt))\s*(\[HomeScreen\])?\s*(0x[a-fA-F0-9]{8})?\s*(\[Operator\])?\s*$/i)
+        {
+        my $widget = $1;
+        $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget;
+        die "Can't find widget $widget" if !-e $widget;
+        $self->{'homescreen'}{lc $widget} = 1 if $2; # Intended for the homescreen?
+        $self->{'staticUID'}{lc $widget} = hex($3) if $3;
+        $self->{'secure'}{lc $widget} = 0;
+        $self->{'operator'}{lc $widget} = 1 if $4;
+        print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'};
+        push @{ $installData{"$drive:"} }, $widget;
+        }
+      elsif ($line =~ /^(.+?\.(?:wdgt\.zip|wgz))\s*(\[Secure\])?\s*(0x[a-fA-F0-9]{8})?\s*$/i)
+        {
+          my $widget = $1;
+          $widget = fixFilename(catfile($self->{'args'}->{'epocroot'}, $1)) if !-e $widget;
+          die "Can't find widget $widget" if !-e $widget;
+          $self->{'secure'}{lc $widget} = 1 if $2; # Intended for a secure widget handling?
+          $self->{'staticUID'}{lc $widget} = hex($3) if $3;
+          print "Widget for drive $drive: $widget\n" if $self->{'args'}->{'verbose'};
+          push @{ $installData{"$drive:"} }, $widget;
+        }
+      else
+      	{
+      		my $widget = $1;
+      		$self->{'secure'}{lc $widget} = 0;
+        }	
+      }
+    # Retrieve the command to execute before exit
+    elsif ($sectionName =~ /^(run-commands|homescreen-processor)$/i && $line)
+      {
+      push @{ $self->{'exitcmds'} }, $line;
+      }
+    }
+  close CONFIG;
+
+  # Now intall the widgets for each drive specified in the config file
+  foreach my $drive ( keys %installData )
+    {
+    $self->installFiles($drive, $installData{$drive} );
+    $self->makeIBY($drive);
+    $self->makeIBY($drive, 'localised') unless $self->{'args'}->{'l10n'};
+    }
+  
+  # Exit commands at the end of the process
+  if ($self->{'exitcmds'})
+    {
+    foreach my $cmd ( @{ $self->{'exitcmds'} } )
+      {
+      print "Executing: $cmd\n" if $self->{'args'}->{'verbose'};
+      warn "WARNING: error running $cmd" if system($cmd) != 0;
+      }
+    }
+  }
+
+# ***
+# Installs files to a drive
+#
+sub installFiles
+  {
+  my ( $self, $drive, $fileList ) = @_;
+  my $startsrc ;
+    my $iconsrc ;
+  
+   $isSharedLibrary = 0;
+   $isSharedWidget = 0;
+   $isSharedIcon = 0;
+   $sharedFolderName ='';
+   $isSecureWidget = 0;
+    
+  print "Installing files for drive $drive\n" if $self->{'args'}->{'verbose'};
+
+  # Unregister any existing widgets as otherwise when the registry is rewritten their icons will appear in the emulator but they won't work
+  $self->unregisterWidgets($drive);
+
+  print "\n			INSTALLING FILES FOR DRIVE $drive				\n"; 
+  # Process each widget in turn
+  my ( @installedProps );
+  my ( @installedCWRTProps );
+  foreach my $filename ( @$fileList )
+    {
+    # Check the file exists
+    die "Can't find $filename" if !-e $filename;
+
+    # Create a temporary folder
+    print "\nInstalling $filename\n";
+    my $tempdir = tempdir ( DIR => '.', CLEANUP => !$self->{args}->{'debug'});
+
+    # Prefer to use 7zip rather than unzip because it's better behaved wrt Unicode
+    if (findCmd('7z.exe'))
+      {
+      $self->un7zipWidget($filename, $tempdir);
+      }
+    else
+      {
+      $self->unzipWidget($filename, $tempdir);
+      }
+        my $widgetdata ;
+        
+        $isSharedLibrary = 0;
+        $isSharedWidget = 0;
+        $isSharedIcon = 0;
+        $sharedFolderName ='';
+    
+    my ( $root, $extracted, $size ) = $self->getFiles($tempdir);
+    die "No files extracted from $filename" if !@$extracted;
+    
+    if ($self->{'operator'}{lc $filename})
+		{
+    	print "\n NON NOKIA WGT \n";
+    	$non_nokia_widget = 1;
+    }
+    else
+    {
+    	print "\n NOKIA WGT \n";
+    	$non_nokia_widget = 0;
+    }
+    
+    
+    if (($filename =~ /.wgz/ )&& (my $plist = catfile($tempdir, $root, 'Info.plist')))
+      {
+          print ("S60 widget \n");
+          
+          $w3c_widget = 0;
+          # Parse the XML file into a hash
+              $widgetdata = parsePList($plist);
+      }
+    elsif (($filename =~ /.wgt/ ) && ( my $confxml = catfile($tempdir, $root, 'config.xml')))
+      {
+        print (" W3C widget \n"); 
+      
+          # Parse the XML file into a hash
+            $widgetdata = parseConfXml($confxml,$self->{'args'}->{'l10n'});
+            $w3c_widget = 1;
+      }
+    else
+      {
+      die "Can't find $root/Info.plist , $root/config.xml file";
+      }       
+		
+	  if ($self->{'secure'}{lc $filename}){
+		$isSecureWidget = 1;
+	  } else {
+	  	$isSecureWidget = 0;
+	  }
+
+    if( $w3c_widget )
+    { 
+      if( $widgetdata->{'MainHTML'} )
+        {
+        $startsrc = $widgetdata->{'MainHTML'};
+        }
+      else
+        {
+        $startsrc = 'index.html';
+        }
+      if( $widgetdata->{'IconPath'} )
+        {
+        $iconsrc = $widgetdata->{'IconPath'};
+        }
+      else
+        {
+        $iconsrc = 'icon.png';   
+        }
+        
+  		if($non_nokia_widget)
+  		{
+  			$widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_NON_NOKIA_UID;
+  		}
+  		else
+  		{
+      		$widgetdata->{'ProcessUid'} = CWRT_WIDGET_UI_UID;
+      	}
+      
+      $widgetdata->{'MimeType'} = "application/widget";
+    }         
+
+    print "Identifier: $widgetdata->{'BundleIdentifier'}\n" if $self->{args}->{'verbose'};
+    
+    # Set widget package properties
+    $widgetdata->{'FileName'} = $filename;
+    $widgetdata->{'FileSize'} = $size;
+
+    # Load the language translations for BundleDisplayName
+    if ($self->{'args'}->{'l10n'})
+      {
+      my $localised = $self->getLocalisedStringByLangCode(catfile($tempdir, $root), 'DisplayName', $self->{'args'}->{'l10n'});
+      $widgetdata->{'BundleDisplayName'} = $localised if $localised;
+      }
+    else
+      {
+      $widgetdata->{'LocBundleDisplayName'} = $self->getLocalisedStrings(catfile($tempdir, $root), 'DisplayName');
+      }
+
+    # Fix up some of the fields
+    $widgetdata->{'BundleName'} = $widgetdata->{'BundleDisplayName'} if !$widgetdata->{'BundleName'};
+    $widgetdata->{'AllowNetworkAccess'} = $widgetdata->{'AllowFullAccess'} if !$widgetdata->{'AllowNetworkAccess'};
+    $widgetdata->{'DriveName'} = $drive;
+    
+    if( $w3c_widget )
+      {
+      $widgetdata->{'PropertyListVersion'} = 4;
+      my $widget_uid;
+      
+      if($non_nokia_widget)
+  		{
+  			$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
+  		}
+  		else
+  		{
+      	$widget_uid = CWRT_WIDGET_UI_UID;
+      }
+      
+      if($isSharedLibrary)
+      {
+        #In case of NOKIA:sharedlibrary, the extracted widget contents and data source are stored under private\<uid>\..\lib\<sharedfoldername>\
+        $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08X\\%s\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7","lib",$sharedFolderName);
+        $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08X\\%s\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" ,"lib" ,$sharedFolderName);
+      }
+      else
+      {
+        $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08X\\%s\\%s\\', $widgetdata->{'DriveName'}, $widget_uid, "widgets_21D_4C7", hashpjw($widgetdata->{'BundleIdentifier'}));
+        $widgetdata->{'IconPath'} = sprintf('%s\\private\\%08X\\%s\\%s\\',$widgetdata->{'DriveName'}, $widget_uid, "data" , hashpjw($widgetdata->{'BundleIdentifier'}));
+      }
+      $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$startsrc";
+      $widgetdata->{'AllowNetworkAccess'} = 1;
+      
+      }
+    else
+      {
+      $widgetdata->{'PropertyListVersion'} = 1;
+      $widgetdata->{'BasePath'} = sprintf('%s\\private\\%08x\\%s\\', $widgetdata->{'DriveName'}, WIDGET_UI_UID, $widgetdata->{'BundleIdentifier'});
+      $widgetdata->{'MainHTML'} = "$widgetdata->{'BasePath'}$root\\$widgetdata->{'MainHTML'}";
+      $widgetdata->{'IconPath'} = "$widgetdata->{'BasePath'}$root\\";
+      }
+      
+    $widgetdata->{'BlanketPermissionGranted'} = 0 if( ! $widgetdata->{'BlanketPermissionGranted'} );
+    $widgetdata->{'MiniViewEnabled'} = 0  if( ! $widgetdata->{'MiniViewEnabled'} );
+    
+    # Indicate that the widget was pre-installed
+    $widgetdata->{'PreInstalled'} = 1;
+    
+    # Set BlanketPermissionGranted flag if Widget is listed as a homescreen widget in the INI file
+    # Error if MiniViewEnabled isn't set
+    if ($self->{'homescreen'}{lc $filename})
+      {
+      $widgetdata->{'BlanketPermissionGranted'} = 1;
+      die "ERROR: $filename - MiniViewEnabled not set for homescreen widget" if !$widgetdata->{'MiniViewEnabled'};
+      }
+
+    # Defining UID  
+    if($self->{'staticUID'}{lc $filename})
+      {
+      print "Using Static UID from INI file\n";
+      $widgetdata->{'Uid'} = $self->{'staticUID'}{lc $filename};
+      }
+    else
+      {
+      # Find the next free UID to use
+      $widgetdata->{'Uid'} = $self->findfreeUid($widgetdata);
+      }
+    print sprintf("Using UID for midlet: 0x%08X\n", $widgetdata->{'Uid'}) if $self->{args}->{'verbose'};
+
+    # Make sure the destination exists
+    my $dest = $self->regFileName($drive);
+    mkpath $dest;
+
+    my $icon;
+    if($w3c_widget)
+    {
+      my $locate = $self->{'args'}->{'l10n'};
+      my $seperator ='-';
+      my $position = -1;
+      my $found = 0 ;
+      if ($self->{'args'}->{'l10n'})
+          {
+            do
+               {
+                my $searchdir = '.\\'.$tempdir.'\\locales\\'.$locate;
+                if( opendir(DIR, $searchdir))
+                    {
+                    my @files = grep(/$iconsrc$/,readdir(DIR));
+                    closedir(DIR);
+                    if(@files)
+                       {
+                        $iconsrc = 'locales\\'.$locate.'\\'.$iconsrc ;
+                        $found = 1;
+                       }
+                    }  
+                if(($position = rindex($locate,$seperator)) > 0 )
+                    {
+                    $locate = substr($locate,0,$position);
+                    }
+               } while (!$found && $position > 0);
+          }
+          if ($iconsrc)
+          {
+            $icon = catfile($tempdir, $root, $iconsrc);    
+          }
+            
+          if(-e $icon)
+          {
+             $widgetdata->{'DBIconPath'}= "$widgetdata->{'BasePath'}$iconsrc";
+             print "Icon found -- $widgetdata->{'DBIconPath'} \n";
+          }
+          else
+          {
+              $icon = findCmd('default_widget_icon.png');
+              print "default_widget_icon.png used \n";    
+              $widgetdata->{'DBIconPath'}= ":/resource/default_widget_icon.png";
+          }
+      }
+    else
+    {
+      $icon = catfile($tempdir, $root, 'Icon.png');
+            die "ERROR: Widget bundle must include an Icon.png file in $root directory.\n" unless -e $icon;
+    }
+    
+    # Create the MBM file icon - in case of sharedlibrary, create only if NOKIA:widget is true
+    my $mbm;
+    
+    print("\nIs shared library - $isSharedLibrary \nIs sharedlib widget - $isSharedWidget \nIs Secure WGZ - $self->{'secure'}{lc $filename}\n");
+    
+		if( ((!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget)) && (!$self->{'secure'}{lc $filename}))
+    {
+    	  print "Creating mbm !!!\n";
+        die "ERROR: Can't find PNG2MBM command in PATH." if !(my $cmd = findCmd('png2mbm.exe'));
+        $mbm = $self->regFileName($drive, sprintf("[%08x].mbm", $widgetdata->{'Uid'}));
+        print "Generating: $mbm\n";
+                    die "Failed to create MBM $mbm " if system("$cmd $self->{args}->{'verbose'} -in \"$icon\" -out $mbm -sizes ".ICON_SIZES) != 0;
+    
+        # Add the mbm to the list of files
+        $self->addToRomList($drive, $mbm);
+    
+        # Create the INI file which defines the registry info
+        my $ini = catfile($tempdir, 'reg.ini');
+        $self->makeIni($widgetdata, $ini);
+        unlink 'debug.ini'; copy($ini, 'debug.ini') if $debug;
+        print "Generated INI file: $ini\n" if $self->{args}->{'verbose'};
+    
+        # Generate the registry files
+        die "ERROR: Can't find WidgetRegFiles.exe command in PATH." if !($cmd = findCmd('WidgetRegFiles.exe'));
+        die "Failed to generate registry files" if system("$cmd $ini") != 0;
+        my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $widgetdata->{'Uid'})), catfile($dest, sprintf("%08x_loc.rsc", $widgetdata->{'Uid'})) );
+        die "Failed to generate REG file: $!" if !-e $reg;
+        $self->addToRomList($drive, $reg);
+        die "Failed to generate LOC file: $!" if !-e $loc;
+        if ($self->{'args'}->{'l10n'})
+          {
+              $self->addToRomList($drive, $loc);
+          }
+        else
+          {
+              $self->addToRomList($drive, $loc, 'localised');
+          }
+        }
+        
+    # Create install folder
+    my $dir = $self->installDir($drive, $widgetdata->{'BundleIdentifier'});
+    mkpath $dir;
+
+    # Now copy the widget files to the right place
+    print "Install Directory: $dir\n";
+    foreach my $widgetfile ( @$extracted )
+    {
+      my ( $sourceFile, $destFile ) = ( catfile($tempdir, $widgetfile), catfile($dir, $widgetfile) );
+      print "Copying $sourceFile to $destFile\n" if $self->{args}->{'debug'};
+
+      # Create the directory if it doesn't exist already
+      my $dir = dirname($destFile);
+      if (!-d $dir)
+        {
+        mkpath ($dir) or die "Failed to create $dir $!";
+        }
+      unlink $destFile;
+      if (!copy($sourceFile, $destFile))
+        {
+        warn "WARNING: Failed to copy $sourceFile to $destFile: $!";
+        }
+      #else
+        {
+        $self->addToRomList($drive, $destFile);
+        }
+    }
+
+    # Copy the MBM file into the widget install directory
+    # because native installation does and uses it after
+    # installation to manage UID consistency.
+    if( (!$isSharedLibrary) || ($isSharedLibrary && $isSharedWidget))
+    {
+        my $mbmName = sprintf("[%08x].mbm", $widgetdata->{'Uid'});
+        my $destFile;
+        if($w3c_widget)
+        {
+            my $dataDir;
+            
+            my $widget_uid;
+      
+			      if($non_nokia_widget)
+			  		{
+			  			$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
+			  		}
+			  		else
+			  		{
+			      	$widget_uid = CWRT_WIDGET_UI_UID;
+			      }
+            
+            # NOKIA:sharedlibrary check
+            if($isSharedWidget)
+            {
+                $dataDir = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName));
+            }
+            else
+            {
+                #in case of WGT copy .mbm to \epoc32\winscw\C\private\200267c0\data\hash<BundleId>\
+                $dataDir = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data", $hashval));
+            }
+            mkpath $dataDir;
+            $destFile = catfile($dataDir,$mbmName);
+        }
+        else
+        {
+           $destFile = catfile($dir, $root, $mbmName);
+        }
+    		# Exclude securewidget from making a mbm file
+			if (!$self->{'secure'}{lc $filename}){
+            print "Copying $mbm to $destFile\n" if $self->{args}->{'debug'};
+            copy $mbm, $destFile or die "Failed to copy $mbm to $destFile: $!";
+            $self->addToRomList($drive, $destFile);
+          	}
+        }
+        
+    # Remember the data for the registry
+    if( $w3c_widget )
+      {
+      push @installedCWRTProps, $widgetdata;
+      }
+    else
+      {
+	    if (!$self->{'secure'}{lc $filename}){
+      		push @installedProps, $widgetdata;
+      	}
+      }
+
+    if (!$debug)
+      {
+      # Perl v5.6 can't delete files with unicode in their name on Windows
+      if ($] < 5.008 && $^O =~ /MSWin32/)
+        {
+        system("rmdir /s /q $tempdir");
+        }
+      else
+        {
+        rmtree $tempdir;
+        }
+      }
+    #Generate the secsession for .wgt widgets
+    if( $w3c_widget ) 
+      {
+      $self->addToRomList($drive, $self->makeSecSession($drive));
+      }
+  }
+
+  my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY);
+  $self->addToRomList($drive, $cwrtdbPath);
+  
+  # Generate the registry and IBY file
+  $self->addToRomList($drive, $self->makeRegistry($drive, \@installedProps, 0));
+  $self->addToRomList($drive, $self->makeRegistry($drive, \@installedCWRTProps, 1));
+    
+
+  print "\n\n %%%%%          WIDGET PRE-INSTALLATION completed for Drive $drive          %%%%% \n\n";
+  }
+
+sub un7zipWidget
+  {
+  my ( $self, $filename, $tempdir ) = @_;
+
+  # Unzip the file
+  die "Can't find 7z.exe tool on PATH." if !findCmd('7z.exe');
+  die "Failed to extract widget contents using 7zip: $!" if (system("7z x -aoa -o$tempdir \"$filename\" >nul 2>&1") != 0);
+  }
+
+sub unzipWidget
+  {
+  my ( $self, $filename, $tempdir ) = @_;
+
+  # Unzip the file
+  die "Can't find unzip.exe tool on PATH." if !findCmd('unzip.exe');
+  die "Failed to extract widget contents using zip: $!" if (system("unzip.exe \"$filename\" -d $tempdir >nul 2>&1") != 0);
+  }
+
+# Recursively get list of files in a folder
+sub getFiles
+  {
+  my ( $self, $tempdir ) = @_;
+
+  my $root = '.';
+  my @extracted;
+  my $size =0;
+  
+  my @dirs = '.';
+  foreach my $dir ( @dirs )
+    {
+    opendir DIR, catfile($tempdir, $dir) or die "Failed to opendir $dir: $!";
+    foreach ( grep !/^\.{1,2}$/, readdir DIR )
+      {
+      my $name = catfile($dir, $_);
+      my $fullname = catfile($tempdir, $name);
+      if (-d $fullname)
+        {
+        push @dirs, $name;
+        }
+      else
+        {
+        # Remember total size for later
+        if (-e $fullname)
+          {
+          push @extracted, $name;
+          print "Extracted: $name\n" if $self->{args}->{'debug'};
+          $size += -s $fullname;
+
+          # Get root
+          if ($name =~ /info.plist$/i && $name =~ /^([^\/\\]+)[\/\\]/)
+            {
+            $root = $1;
+            }
+          }
+        else
+          {
+          warn "WARNING: Failed to find extracted file $fullname";
+          }
+        }
+      }
+    closedir DIR;
+    }
+
+  return ( $root, \@extracted, $size );
+  }
+
+## see http://www.loc.gov/standards/iso639-2/php/code_list.php
+## see http://www.loc.gov/standards/iso639-2/faq.html#2
+sub getLocalisedStringByLangCode
+  {
+  my ( $self, $dir, $strName, $langCode ) = @_;
+  my $localised;
+
+  # Generate the name of the file containing localised strings for this language
+  my $locfile = catfile($dir, "$langCode.lproj", "InfoPlist.strings");
+  if (-e $locfile)
+        {
+    # Open the file
+    print "Found $langCode language translations in $locfile\n" if $verbose;
+    open LOC, $locfile or die "Failed to open $locfile: $!";
+
+    # Get the byte order mark from the start of the file
+    my $bom;
+    $bom = unpack("S", $bom) if (read(LOC, $bom, 2) == 2);
+    if ($bom)
+      {
+      if ($bom == 0xEFBB)
+        {
+        # Skip utf8 bom
+        seek LOC, 3, 0;
+        }
+      elsif ($bom != 0xFFFE && $bom != 0xFEFF)
+        {
+        seek LOC, 0, 0;
+        undef $bom;
+        }
+      }
+    else
+      {
+      # go back to start of file if no bom
+      seek LOC, 0, 0;
+      undef $bom;
+      }
+
+    while(my $line = <LOC>)
+      {
+      # Do unicode conversion
+      my $ustr;
+      if ($bom)
+        {
+        $ustr = utf16($line);
+        $ustr->byteswap if $bom != 0xFFFE;
+        }
+      else
+        {
+        $ustr = utf8($line);
+        }
+
+      # Find the string we're looking for
+      if ($ustr->utf8 =~ /(?:^|\s)$strName\s*=\s*\"([^\"]*)\"/)
+        {
+        print "\t...$strName => $1\n" if $debug;
+        $localised = utf8($1);
+        }
+      }
+    close LOC;
+    }
+    return $localised;
+  }
+
+# Get localised version of strings if they exist
+sub getLocalisedStrings
+  {
+  my ( $self, $dir, $strName ) = @_;
+  return if (!$self->{'langmapping'});
+
+  # Iterate through all the languages we know about
+  my %result;
+  for(my $i = 0; $i < scalar(@{ $self->{'langmapping'}->{LangID} }); $i++)
+    {
+    my ( $langid, $langname ) = ( $self->{'langmapping'}->{LangID}->[$i], $self->{'langmapping'}->{LangDir}->[$i] );
+
+    my $localised = $self->getLocalisedStringByLangCode($dir, $strName, $langname);
+    $result{$langid} = $localised if $localised;
+    }
+
+  return \%result if keys %result;
+  }
+
+# Find and execute a command
+sub findCmd
+  {
+  my $cmd = shift;
+  return fixFilename("./$cmd") if -e $cmd;
+
+  # PATH separator differs on Windows and Linux
+  my $sep = $^O =~ /MSWin32/ ? ';' : ':';
+
+  # Search each entry in the PATH
+  my @paths = split /$sep/, $ENV{PATH};
+  push @paths, dirname($0);
+  foreach my $path ( @paths )
+    {
+    my $fullcmd = fixFilename(catfile($path, $cmd));
+    return $fullcmd if -e $fullcmd;
+    }
+  }
+
+# Make INI file describing widget - this is passed to widgetregfiles.exe
+sub makeIni
+  {
+  my ( $self, $data, $file ) = @_;
+  open INI, ">$file" or die "Failed to open $file for writing: $!";
+  binmode INI, ":utf8" if $] >= 5.008;
+
+  # Get directory where mbm should go
+  my $dir = $self->regFileName($data->{'DriveName'});
+
+  print INI "[app_registration_info]\n";
+  print INI sprintf("uid=%08x\n", $data->{'Uid'});
+  print INI "app_file=$data->{'MainHTML'}\n";
+  print INI "caption=$data->{'BundleDisplayName'}\n";
+  print INI "drive_name=$data->{'DriveName'}\n";
+  print INI "results_dir=$dir\n";
+  
+  if( $w3c_widget )
+  {
+    print INI "app_type=200267DC\n";
+    print " WGT Widget:: app_type added to ini of widgetregfiles.exe \n" if $debug;
+  }
+  
+
+  # Add language stuff if we have the mapping
+  if ($data->{'LocBundleDisplayName'})
+    {
+    my @langList;
+    foreach my $langid ( sort { $a <=> $b } keys %{ $data->{'LocBundleDisplayName'} } )
+      {
+      my $symid = sprintf("%02d", $langid);
+      push @langList, $symid;
+      print INI "caption$symid=", $data->{'LocBundleDisplayName'}->{$langid}->utf8, "\n";
+      }
+    print INI "languages=", join(' ', @langList), "\n";
+    }
+
+  close INI;
+  convert2Unicode($file);
+  }
+
+ sub findfreeUid
+  {
+  my ( $self, $data ) = @_;
+  my $appfile = lc $data->{'MainHTML'};
+  my $uid;
+  my $size;
+    if($w3c_widget)     #CWRT Widget
+    {
+      # pick the next free CWRT Internal UID
+      if(isInternal($data->{'DriveName'}))
+      {
+        print "\nInternal CWRT UID";
+        $size = scalar @staticUidCwrtIntList;
+        print " Static UID :: @staticUidCwrtIntList Length -- $size \n" if($size);
+        for(my $i=0; $i<$size; $i++)
+        {
+		  #skip looping if freeUid found
+          if( $self->{'freeuidcwrtint'} lt $staticUidCwrtIntList[$i] ) {last};
+          
+          if($self->{'freeuidcwrtint'} == $staticUidCwrtIntList[$i]) 
+          { 
+            $self->{'freeuidcwrtint'}++; 
+          }
+        }
+        $uid = $self->{'freeuidcwrtint'}++;   # Assign and then set next free UID
+      } 
+      else
+      {
+        # pick the next free CWRT External UID
+        print "\nExternal CWRT UID ";
+        $size = scalar @staticUidCwrtExtList;
+        print "Static UID :: @staticUidCwrtExtList Length -- $size \n";
+        
+        for(my $i=0; $i<$size; $i++)
+        {
+          if( $self->{'freeuidcwrtext'} lt $staticUidCwrtExtList[$i] ) {last};
+          
+          if($self->{'freeuidcwrtext'} == $staticUidCwrtExtList[$i]) 
+          { 
+            $self->{'freeuidcwrtext'}++; 
+          }
+        }
+        $uid = $self->{'freeuidcwrtext'}++;   # Assign and then set next free UID
+      }
+    }
+    else      #WRT widget
+    {
+      # pick the next free WRT Internal UID
+      if(isInternal($data->{'DriveName'}))
+      {
+        # pick the next free CWRT Internal UID
+        if(isInternal($data->{'DriveName'}))
+        {
+          print "\nInternal WRT UID ";
+          $size = scalar @staticUidWrtIntList;
+          print " STATIC UID :: @staticUidWrtIntList Length -- $size\n";
+                 
+          for(my $i=0; $i<$size; $i++)
+          {
+            if( $self->{'freeuidwrtint'} lt $staticUidWrtIntList[$i] ) {last};
+            
+            if($self->{'freeuidwrtint'} == $staticUidWrtIntList[$i]) 
+            { 
+              $self->{'freeuidwrtint'}++; 
+            }
+          }
+          $uid = $self->{'freeuidwrtint'}++;   # Assign and then set next free UID
+        }
+      }
+      else
+      {
+        # pick the next free WRT External UID
+        print "\nExternal WRT UID ";
+        $size = scalar @staticUidWrtExtList;
+        print "STATIC UID :: @staticUidWrtExtList Length -- $size\n";
+        
+        for(my $i=0; $i<$size; $i++)
+        {
+          if( $self->{'freeuidwrtext'} lt $staticUidWrtExtList[$i] ) {last};
+          
+          if($self->{'freeuidwrtext'} == $staticUidWrtExtList[$i]) 
+          { 
+            $self->{'freeuidwrtext'}++; 
+          }
+        }
+        $uid = $self->{'freeuidwrtext'}++;   # Assign and then set next free UID
+      }
+    }
+  print sprintf("Generated UID: hex->0x%08X dec->$uid\n \n",$uid);
+  return $uid;
+  }
+
+# Fix slash problems in a filename
+sub fixFilename
+  {
+  my $filename = shift;
+  $filename =~ s/([\\\/])[\\\/]/$1/g;
+  return catfile(split(/[\\\/]/, $filename));
+  }
+
+# Get install location
+sub destLocation
+  {
+  my ( $self, $drive ) = @_;
+  my $letter = uc(substr($drive, 0, 1));
+  
+  # Was any destination location specified in the config file?
+  if ($self->{destination} && $self->{destination}->{$letter})
+    {
+    return catfile($self->{'args'}->{'epocroot'}, $self->{destination}->{$letter});
+    }
+    
+  # No destination specified - use emulator location
+  return catfile($self->{'args'}->{'epocroot'}, $letter eq 'Z' ? ROM_DEST : sprintf(DRIVE_DEST, $letter));
+  }
+  
+# Get the destination for REG/LOC/MBM file
+sub regFileName
+  {
+  my ( $self, $drive, $filename ) = @_;
+  my $result = catfile($self->destLocation($drive), DESTINATION, $filename);
+  return fixFilename($result);
+  }
+
+# Widget install directory
+sub installDir
+  {
+  my ( $self, $drive, $id ) = @_;
+  my $result ;
+  $hashval = hashpjw($id);
+  if( $w3c_widget )
+  {
+  	my $widget_uid;
+    if($non_nokia_widget)
+	{
+		$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
+	}
+	else
+	{
+		$widget_uid = CWRT_WIDGET_UI_UID;
+	}
+    if($isSharedLibrary)
+    {
+    	$result = catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", "lib",$sharedFolderName);
+    }
+    else
+    {
+        $result = catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"widgets_21D_4C7", $hashval);
+    }
+  }
+  else
+      {
+	  	if ($isSecureWidget){
+	   		print "Installing secure WGZ Widget\n";
+	    	$result = catfile($self->destLocation($drive), 'private', sprintf("%08x", SWIDGET_UI_UID), $id);
+	  	} else {
+	   		print "Installing WGZ Widget\n";
+        	$result = catfile($self->destLocation($drive), 'private', sprintf("%08x", WIDGET_UI_UID), $id);
+	  	}
+      }    
+  return fixFilename($result);
+  }
+
+# Determines whether a drive should be considered internal or not
+sub isInternal
+  {
+  my $drive = shift;
+  die "Invalid drive format: $drive" if $drive !~ /^[a-zA-Z]:/;
+  return 1 if $drive =~ /^[zcZC]/;
+  }
+
+# Parse these awful PLIST files
+sub parsePList
+  {
+  my $file = shift;
+
+  # Create parser object
+  our ($key, $val, $plisthash ) = ('', '', {});
+  my $parser = new XML::Parser;
+  $parser->setHandlers('Doctype' => \&docT, 'Start' => \&startH, 'End' => \&endH, 'Char' => \&dataH);
+
+  # Parse the file
+  open XML, $file or die "Couldn't open $file";
+
+  # Skip the UTF8 BOM - perl 5.6 can't handle it
+  my $bom;
+  read XML, $bom, 3;
+  $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom)));
+  print "Testing the following for BOM: $bom\n" if $debug;
+  seek(XML, 0, 0) if $bom ne 'EFBBBF';
+
+  $parser->parse(*XML);
+  close XML;
+
+  # Check required fields exist
+  die "Widget MainHTML unknown" if !$plisthash->{'MainHTML'};
+  die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'};
+  die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'};
+
+  # Return result
+  return $plisthash;
+
+  # Called on a start tag
+  sub startH
+    {
+    my ($p, $el, %atts) = @_;
+    undef $key if ($el =~ /^key$/i);
+    $val = '';
+    }
+
+  # Receives document type
+  sub docT
+    {
+    my ($expat, $name, $sysid, $pubid, $internal ) = @_;
+    die "PLIST format looks wrong!" if lc($name) ne 'plist';
+    $plisthash->{'NokiaWidget'} = ( $pubid =~ m[^-//Nokia//DTD PLIST]i ) ? 1 : 0;
+    }
+
+  # Receives character data
+  sub dataH
+    {
+    my ($p, $s) = @_;
+    $val .= $s;
+    }
+
+  # Called on an end tag
+  sub endH
+    {
+    my ($p, $el) = @_;
+    if ($el =~ /^key$/i)
+      {
+      $key = $val;
+      }
+    elsif ($key)
+      {
+      $val = 1 if $el =~ /^true$/i;
+      $val = 0 if $el =~ /^false$/i;
+
+      # Fix stuff so it's in the correct format
+      $key =~ s/^CF//;
+      $key = 'BundleIdentifier' if $key =~ /^Identifier$/i;
+      $key = 'BundleDisplayName' if $key =~ /^DisplayName$/i;
+      $key = 'BundleVersion' if $key =~ /^Version$/i;
+
+      $plisthash->{$key} = $val;
+      undef $key;
+      }
+    $val = ''
+    }
+  }
+
+
+sub parseConfXml
+  {
+    my ( $file , $language ) = @_;
+
+  our ($key, $val, $plisthash, $localizationValue,$localizationIconValue, $lang,$langIcon) = ('', '', {}, '','', {},{});
+  our ($featureCount, $paramCount, $accessCount) = (1,1,1);
+  our ($attributeMap, $featureMap, $featureParamMap, $accessMap)=('','','','');
+  
+  # Create parser object
+  my $parser = new XML::Parser;
+  $parser->setHandlers( 'Start' => \&startC, 'End' => \&endC, 'Char' => \&dataC);
+   
+  # Parse the file
+  open XML,$file or die "Couldn't open $file";
+  # Skip the UTF8 BOM - perl 5.6 can't handle it
+  my $bom;
+  read XML, $bom, 3;
+  $bom = join('', map(sprintf('%X', $_), unpack("CCC", $bom)));
+  print "Testing the following for BOM: $bom\n" if $debug;
+  seek(XML, 0, 0) if $bom ne 'EFBBBF';
+    $plisthash->{'NokiaWidget'} = 2 ;
+    $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1" ;
+  
+  $parser->parse(*XML);
+  close XML;
+
+    if( $language )
+        {
+         if($lang->{$language})
+         { 
+          $plisthash->{'BundleDisplayName'} = $lang->{$language};
+         }
+         if($langIcon->{$language})
+         {
+          $plisthash->{'IconPath'} = $langIcon->{$language};
+         }
+        }
+  die "Widget BundleIdentifier unknown" if !$plisthash->{'BundleIdentifier'};
+  die "Widget BundleDisplayName unknown" if !$plisthash->{'BundleDisplayName'};
+  
+   $attributeMap = $attributeMap.WIDGET_NAME.KEY_VALUE_SEPERATOR.$plisthash->{'BundleDisplayName'}.KEY_VALUE_PAIR_SEPERATOR;
+
+   if($non_nokia_widget)
+   {
+       $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267D6".KEY_VALUE_PAIR_SEPERATOR;
+   }
+   else
+   {
+       $attributeMap = $attributeMap.WIDGET_PROCESSUID.KEY_VALUE_SEPERATOR."200267C0".KEY_VALUE_PAIR_SEPERATOR;
+   }
+
+    if($attributeMap)
+    {      
+        $plisthash->{'AttributeList'} = $attributeMap;
+        print "\nAttributeList::$plisthash->{'AttributeList'}\n"
+    }
+
+  # Return result
+  return $plisthash;
+
+  # Called on a start tag
+  sub startC
+    {
+    my ($p, $el, %atts) = @_;
+    
+    if($el eq "widget")
+        {
+         if ( $atts{"id"} )
+             {
+            $plisthash->{'BundleIdentifier'} = $atts{"id"};
+            $attributeMap = $attributeMap.WIDGET_ID.KEY_VALUE_SEPERATOR.$atts{"id"}.KEY_VALUE_PAIR_SEPERATOR;
+            
+             }
+         if ( $atts{"version"} )
+             {
+            $plisthash->{'BundleVersion'} = $atts{"version"};
+            $attributeMap = $attributeMap.WIDGET_VERSION.KEY_VALUE_SEPERATOR.$atts{"version"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+         if ( $atts{"viewmodes"} && $atts{"viewmodes"} eq "all" )
+             {
+            $plisthash->{'MiniViewEnabled'} = 1;
+             }
+         $attributeMap = $attributeMap.WIDGET_HEIGHT.KEY_VALUE_SEPERATOR.$atts{"height"}.KEY_VALUE_PAIR_SEPERATOR;
+         $attributeMap = $attributeMap.WIDGET_WIDTH.KEY_VALUE_SEPERATOR.$atts{"width"}.KEY_VALUE_PAIR_SEPERATOR;
+        }
+      elsif ($el eq "icon")
+          {
+           if ( $atts{"xml:lang"} )
+             {
+              $localizationIconValue = lc($atts{"xml:lang"}) ;
+             }
+           if ( $atts{"src"} )
+             {
+            $plisthash->{'IconPath'} = $atts{"src"};
+                 }
+          }
+      elsif ($el eq "content")
+          {
+           $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;	
+           if ( $atts{"src"} )
+             {
+            $plisthash->{'MainHTML'} = $atts{"src"};
+            $attributeMap = $attributeMap.WIDGET_CONTENT.KEY_ATTR_SEPERATOR."src".KEY_VALUE_SEPERATOR.$atts{"src"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+          }
+      elsif ($el eq "name")
+          {
+           if ( $atts{"xml:lang"} )
+             {
+              $localizationValue = lc($atts{"xml:lang"}) ;
+             }
+          }
+      elsif ($el eq "feature")
+          {
+           $featureMap = WIDGET_FEATURE . $featureCount;
+           $attributeMap = $attributeMap.$featureMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
+           
+           if ( $atts{"name"} )
+             {
+              $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR;
+              my $jilFeature = "http://jil.org/jil";
+              if($atts{"name"}=~ m/^$jilFeature/i)
+              {
+                $plisthash->{'WidgetPackagingFormat'} = "jil";
+              }
+             }
+         if ( $atts{"required"} )
+             {
+              $attributeMap = $attributeMap.$featureMap.KEY_ATTR_SEPERATOR."required".KEY_VALUE_SEPERATOR.$atts{"required"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+         }
+       elsif($el eq "param")
+          {
+              $featureParamMap = $featureMap. WIDGET_FEATURE_PARAM . $paramCount;
+              $attributeMap = $attributeMap.$featureParamMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
+              if ($atts{"name"}) 
+              {
+                  $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."name".KEY_VALUE_SEPERATOR.$atts{"name"}.KEY_VALUE_PAIR_SEPERATOR;
+              }
+              if ($atts{"value"})
+              {
+                  $attributeMap = $attributeMap.$featureParamMap.KEY_ATTR_SEPERATOR."value".KEY_VALUE_SEPERATOR.$atts{"value"}.KEY_VALUE_PAIR_SEPERATOR;
+              }
+          }
+       elsif ($el eq "access" || $el eq "jil:access")
+          {
+              $accessMap = WIDGET_ACCESS . $accessCount;
+              $attributeMap = $attributeMap.$accessMap.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
+           
+              if ( $atts{"network"} )
+             {
+                $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."network".KEY_VALUE_SEPERATOR.$atts{"network"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+            if ( $atts{"remotescripts"} )
+             {
+                $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."remotescripts".KEY_VALUE_SEPERATOR.$atts{"remotescripts"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+             if ( $atts{"localfs"} )
+             {
+                $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."localfs".KEY_VALUE_SEPERATOR.$atts{"localfs"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+             if ( $atts{"origin"} )
+             {
+                $attributeMap = $attributeMap.$accessMap.KEY_ATTR_SEPERATOR."origin".KEY_VALUE_SEPERATOR.$atts{"origin"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+             if ( $atts{"subdomains"} )
+             {
+                $attributeMap = $attributeMap.$accessMap. KEY_ATTR_SEPERATOR."subdomains".KEY_VALUE_SEPERATOR.$atts{"subdomains"}.KEY_VALUE_PAIR_SEPERATOR;
+             }
+        }
+        elsif ($el eq "NOKIA:sharedlibrary")
+        {
+            print " \n\n ^^^^^^^^^^^^^^^^^^^^^^^NOKIA:sharedlibrary ^^^^^^^^^^^^^^^^^^^^ \n\n";
+            $isSharedLibrary = 1;
+            $plisthash->{'WidgetPackagingFormat'} = "shared-library";
+            $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB.KEY_VALUE_SEPERATOR.KEY_VALUE_PAIR_SEPERATOR;
+        }
+     $val = '';    
+     }
+    
+sub docC{}
+# Receives character data
+  sub dataC
+    {
+    my ($p, $s) = @_;
+    $val .= $s;
+    }
+
+  # Called on an end tag
+  sub endC
+    {
+    my ($p, $el) = @_;
+    if ($el eq "name")
+        {
+       if( $localizationValue )
+           {
+            chomp($val);
+            $lang->{$localizationValue} = $val;
+            $localizationValue = '';
+             }
+         else
+             {
+              chomp($val);
+              $plisthash->{'BundleDisplayName'} = $val;
+             }   
+      }
+      elsif ($el eq "icon")
+      {
+        if( $localizationIconValue )
+           {
+            $langIcon->{$localizationIconValue} = $plisthash->{'IconPath'};
+            print "\n %%%%%%%%%%%  $localizationIconValue  :: $plisthash->{'IconPath'}%%%%%%%%%%%%%\n";
+            $localizationIconValue = '';
+           }
+      }
+    elsif($el eq "feature")
+      {
+          $featureCount++;
+          $paramCount = 0;
+      }
+    elsif($el eq "param")
+      {
+          $paramCount++;
+      }
+      elsif($el eq "access" || $el eq "jil:access")
+      {
+          $accessCount++;
+      } 
+      elsif ($el eq "NOKIA:folder")
+        {
+            chomp($val);
+            $sharedFolderName = $val;
+            $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_FOLDER.KEY_VALUE_SEPERATOR.$sharedFolderName.KEY_VALUE_PAIR_SEPERATOR;
+        }
+    elsif ($el eq "NOKIA:widget")
+        {
+            chomp($val);
+            if( lc($val) eq "true" )
+            {
+                $isSharedWidget = 1;
+                $plisthash->{'WidgetPackagingFormat'} = "w3c-partial-v1";
+            }
+            $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_WIDGET.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR;
+        }
+    elsif ($el eq "NOKIA:icon")
+        {
+            chomp($val);
+            if( lc($val) eq "true" )
+            {
+                $isSharedIcon = 1;
+            }
+            $attributeMap = $attributeMap.WIDGET_NOKIA_SHAREDLIB_ICON.KEY_VALUE_SEPERATOR.$val.KEY_VALUE_PAIR_SEPERATOR;
+        }
+    $val = ''
+    }
+
+  }
+
+
+# Stores the details of files to be added to "rom"
+sub addToRomList
+  {
+  my ( $self, $drive, $file, $localised ) = @_;
+  $file = fixFilename($file);
+
+  # All files should be under epoc32 somewhere - need to drop a bit of the path for the rom destination
+  my $localpath = $self->destLocation($drive);
+
+  my $dest = fixFilename($file);
+  $dest =~ s/^\Q$localpath\E//i;
+
+  # Add the file to the list for the rom
+  # It may be localised - in which it'll be put in a different IBY file
+  $localised = $localised ? '_rsc' : '';
+  $self->{"installedFiles${localised}"}->{$drive}->{$file} = $dest;
+  }
+
+# Make the IBY file
+sub makeIBY
+  {
+  my ( $self, $drive, $localised ) = @_;
+
+  # Generate the file name for the IBY file
+  $localised = $localised ? '_rsc' : '';
+  my $name = $drive =~ /^[zZ]/ ? "preinstalledwidgets${localised}.iby" : sprintf("preinstalledwidgets_drive%s${localised}.iby", substr($drive, 0, 1));
+  my $iby = fixFilename(catfile($self->{'args'}->{'epocroot'}, 'epoc32', 'rom', 'include', $name));
+  print "Generating: $iby\n";
+
+  mkpath dirname($iby);
+  open IBY, ">$iby" or die "Failed to open $iby for writing: $!";
+  $name =~ s/\./_/g; $name = uc($name);
+  print IBY "// GENERATED FILE: EDIT WITH CARE\n\#ifndef __${name}__\n\#define __${name}__\n\n";
+  foreach my $file ( sort keys %{ $self->{"installedFiles${localised}"}->{$drive} } )
+    {
+    my $dest = $self->{"installedFiles${localised}"}->{$drive}->{$file};
+
+    # Quote filenames as they may contain spaces!
+    print IBY "data=\"$file\"\t\"$dest\"\n";
+    }
+  print IBY "\#endif\n";
+  close IBY;
+  }
+
+# Unregister (with Apparc) existing Widgets
+sub unregisterWidgets
+{
+  my ( $self, $drive ) = @_;
+    
+    my $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY));
+  # If the WRT registry already exists, remove apparc registry info for those widgets
+  # This should avoid problems with unregistered widget icons in the emulator?
+    if (-e $registry)
+    {
+        print("\n			UNREGISTERING WGZ WIDGETS       \n");
+        
+      my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } );
+    foreach my $entry ( @{ $ref->{entry} } )
+      {
+      my $uid = $entry->{prop}->{Uid}->{val}->{content};
+
+      print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose;
+      my $dest = $self->regFileName($drive);
+      my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid));
+      my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) );
+      unlink $mbm, $reg, $loc;
+    
+      # We also have to delete the widget directory otherwise it'll be re-registered
+      my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content};
+      $w3c_widget = 0;
+      my $dir = $self->installDir($drive, $id);
+      rmtree $dir;
+      }
+    }
+    
+  $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY));
+
+  # If the CWRT registry already exists, remove apparc registry info for those widgets
+  # This should avoid problems with unregistered widget icons in the emulator?
+  if (-e $registry)
+    {
+        print("\n			UNREGISTERING WGT WIDGETS       \n");
+        
+          my $ref = XMLin($registry, 'forcearray' => [ 'entry' ], 'keyattr' => { 'prop' => 'content' } );
+        foreach my $entry ( @{ $ref->{entry} } )
+      {
+          my $uid = $entry->{prop}->{Uid}->{val}->{content};
+    
+          print "Unregistering existing Widget: $entry->{prop}->{BundleIdentifier}->{val}->{content}\n" if $verbose;
+          my $dest = $self->regFileName($drive);
+            my $mbm = catfile($dest, sprintf("[%08x].mbm", $uid));
+          my ( $reg, $loc ) = ( catfile($dest, sprintf("%08x_reg.rsc", $uid)), catfile($dest, sprintf("%08x_loc.rsc", $uid)) );
+          unlink $mbm, $reg, $loc;
+       
+          # We also have to delete the widget directory otherwise it'll be re-registered
+          my $id = $entry->{prop}->{BundleIdentifier}->{val}->{content};
+          print " Unregistering $id ";
+          my $basepath = $entry->{prop}->{BasePath}->{val}->{content};
+          $w3c_widget = 1;
+          my $sharedLib = "lib";          #BasePath will have lib only if the widget is shared Library
+          
+          if($basepath =~ m/$sharedLib/)
+          {
+              $isSharedLibrary = 1;
+          }
+          
+          if($basepath =~ m/\\200267d6\\/i)
+          {
+          	$non_nokia_widget = 1;	
+          }
+           #sharedFolderName TBD
+          my $dir = $self->installDir($drive, $id);
+          rmtree $dir;
+                
+          print("BasePath:$basepath \nIs Non-Nokia? $non_nokia_widget		Is SharedLibrary? $isSharedLibrary \nDirectory:$dir \n");
+    
+            $dir =~ s/widgets_21D_4C7/data/;
+          rmtree $dir;
+        }
+    }
+    #delete CWRT webapp DB if exists
+    my $cwrtdbPath = catfile($self->destLocation($drive), CWRT_WEBAPP_REGISTRY);
+    if($cwrtdbPath)
+    {
+    	print "Deleting CWRT_WEBAPP_REGISTRY \n";
+    	rmtree $cwrtdbPath;
+    }
+  }
+
+# Make the registry
+sub makeRegistry
+  {
+  my ($self, $drive, $installed, $w3c) = @_;
+  
+  my ($registry);
+  if($w3c)
+    {
+    $registry = fixFilename(catfile($self->destLocation($drive), CWRT_WIDGET_REGISTRY));
+    }
+  else
+    {
+    $registry = fixFilename(catfile($self->destLocation($drive), WIDGET_REGISTRY));
+    }
+    
+  print "\nGenerating: $registry\n";
+
+  # Write the file
+  mkpath dirname($registry);
+  open OUT, ">$registry" or die "Failed to open WidgetEntryStore.xml: $!";
+
+  print OUT "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone=\"yes\" ?>\n<widgetregistry>\n";
+  binmode OUT, ":utf8" if $] >= 5.008;
+  foreach my $pList ( @$installed )
+    {
+    $self->dumpPList(\*OUT, $pList, $w3c);
+    }
+  print OUT "</widgetregistry>\n";
+  close OUT;
+
+  # Convert the file to unicode
+  convert2Unicode($registry);
+
+  # Return the generated file
+  return $registry;
+  }
+
+# Converts a file to Unicode
+sub convert2Unicode
+  {
+  my $file = shift;
+
+  my @lines;
+  open IN, $file or die "Failed to open $file: $!";
+  binmode IN;
+  while(<IN>)
+    {
+    my $u = utf8($_);
+    $u->byteswap;
+    push @lines, $u->utf16;
+    }
+  close IN;
+
+  open OUT, ">$file" or die "Failed to open $file for writing: $!";
+  binmode OUT;
+  print OUT pack("CC", 0xff, 0xfe);
+  print OUT @lines;
+  close OUT;
+  }
+
+sub hashpjw {
+  my $s = shift;
+  my $hashval = 0;
+  my $g;
+
+  for ( split //, $s ) {
+    $hashval = ( $hashval << 4 ) + ord $_; 
+    
+    if ($g = $hashval & 0xf0000000) {
+      $hashval ^= $g >> 23;
+    }
+    $hashval &= ~$g;
+  }
+  #print "$hashval \n";
+  return $hashval;
+} 
+
+# Dumps a single PList hash object
+sub dumpPList
+  {
+  my ($self, $fh, $data, $w3c) = @_;
+  my @regProperties = (
+    [ 'PropertyListVersion', 'int' ],
+    [ 'BundleIdentifier', 'string' ],
+    [ 'BundleName', 'string' ],
+    [ 'BundleDisplayName', 'string' ],
+    [ 'MainHTML', 'string' ],
+    [ 'BundleVersion', 'string' ],
+ #  [ 'Height', 'int' ],
+ #  [ 'Width', 'int' ],
+    [ 'AllowNetworkAccess', 'int' ],
+    [ 'DriveName', 'string' ],
+    [ 'BasePath', 'string' ],
+    [ 'IconPath', 'string' ],
+    [ 'FileSize', 'int' ],
+    [ 'Uid', 'int' ],
+    [ 'NokiaWidget', 'int' ],
+    [ 'MiniViewEnabled', 'int' ],
+    [ 'ProcessUid', 'int' ],
+    [ 'MimeType', 'string'],
+    [ 'WidgetPackagingFormat', 'string'],
+    [ 'DBIconPath', 'string'],
+    [ 'AttributeList', 'string'],
+    [ 'BlanketPermissionGranted', 'int' ],
+    [ 'PreInstalled', 'int' ],
+  );
+    
+  print $fh "<entry>\n";
+  my $encodeddata = {};
+  foreach my $prop ( @regProperties )
+    {
+    my ( $key, $type ) = @$prop;
+    if($key ne "DBIconPath" && $key ne "WidgetPackagingFormat" && $key ne "AttributeList" && $key ne "BlanketPermissionGranted" && $key ne "PreInstalled")
+    {
+        print $fh "<prop>$key<val>$data->{$key}<type>$type</type></val></prop>\n" if defined $data->{$key};
+    }
+    
+    if( $w3c )
+      {
+      $encodeddata->{$key} = encodeChar($data->{$key}) if defined $data->{$key};
+      }
+    else
+    {
+    	if($key eq "BlanketPermissionGranted" || $key eq "PreInstalled")
+    	{
+    	 print $fh "<prop>$key<val>$data->{$key}<type>$type</type></val></prop>\n" if defined $data->{$key};
+    	}
+    }
+    }
+  print $fh "</entry>\n";
+  print "\n Is a w3c widget? -- $w3c\n";
+  if( $w3c )
+    {
+  my $dbPath = fixFilename(catfile($self->destLocation('C'), CWRT_WEBAPP_REGISTRY));
+    mkpath dirname($dbPath);
+    die "ERROR: Can't find CWRTWebAppRegistry.exe in PATH" if !(my $cmd = findCmd('CWRTWebAppRegistry.exe'));
+    my $regCmd;
+    
+    if($encodeddata->{'AttributeList'})
+    {
+        print "\n AttributeList argument sent to DB\n";
+        $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'} $encodeddata->{'AttributeList'}";
+    }
+    else
+   {
+        print "\n AttributeList argument not sent to DB\n";
+        $regCmd = "$cmd $dbPath $encodeddata->{'BundleIdentifier'} $encodeddata->{'Uid'} $encodeddata->{'BundleDisplayName'} $encodeddata->{'BasePath'} $encodeddata->{'DBIconPath'} $encodeddata->{'WidgetPackagingFormat'} $encodeddata->{'MainHTML'}";
+    }
+    print "\n regCmd : $regCmd \n\n";
+    system($regCmd);
+    }
+  }
+
+#encode the space character
+sub encodeChar  
+  {
+    my  ($encoded) = @_;
+
+    $encoded =~ s/%/%10/g;
+    $encoded =~ s/\s/%40/g;
+    $encoded =~ s/\'/%apos/g;   
+    $encoded =~ s/&/%amp/g;
+    $encoded =~ s/</%lt/g;
+    $encoded =~ s/>/%gt/g;
+    $encoded =~ s/\"/%quot/g;
+    return $encoded;
+  }
+  
+  
+# Make secssion
+sub makeSecSession
+    {
+  my ($self, $drive) = @_;
+  my $secSession;
+  my $widget_uid;
+  if($non_nokia_widget)
+	{
+		$widget_uid = CWRT_WIDGET_UI_NON_NOKIA_UID;
+	}
+	else
+	{
+  	$widget_uid = CWRT_WIDGET_UI_UID;
+  }
+
+  if($isSharedLibrary)
+  {
+      $secSession = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data","lib",$sharedFolderName,"secsession"));
+  }
+  else
+  {
+      $secSession = fixFilename(catfile($self->destLocation($drive), 'private', sprintf("%08X", $widget_uid),"data", $hashval,"secsession"));
+  }
+  print "\nGenerating: $secSession\n\n";
+  
+  # Write the file
+  mkpath dirname($secSession);
+  open OUT, ">$secSession" or die "Failed to open SecSession.xml: $!";
+
+  print OUT "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n<accesspolicy>\n";
+  if($non_nokia_widget)
+  {
+  	print OUT "<domain name=\"Operator\">\n";
+  }
+  else
+  {
+  	print OUT "<domain name=\"TrustedWidgets\">\n";
+  }
+  
+  if(CWRT_ACCESS_POLICY_PATH) {
+      my $accesspolicypath = findCmd(CWRT_ACCESS_POLICY_PATH);   
+        # Copy Secsession capabilities from browser_access_policy.xml if it exists
+      if (-e $accesspolicypath) {
+          print "Browser Access Policy File exists :: ",$accesspolicypath,"\n" ;
+          my $accesspolicy = XMLin($accesspolicypath, keyattr => {domain => 'name'}, forcearray =>['domain'] );
+            my $domainName;
+            
+            if($non_nokia_widget)
+            {
+            	$domainName = $accesspolicy->{domain}->{Operator};
+            }
+            else
+            {
+            	$domainName = $accesspolicy->{domain}->{TrustedWidgets};
+            }
+          
+          my $xml = XMLout($domainName, keeproot => 1);
+          print OUT $xml;
+      }
+      #browser_access_policy.xml does not exist in the path
+      else {      
+          print "\n Browser Access policy file '$accesspolicypath' does not exist in the given path\n";
+          if(!$non_nokia_widget)
+          {
+          	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";
+          }
+        }
+    }
+    #Access policy path not defined
+  else {
+      print "\n Browser Access policy path not defined \n";
+      if(!$non_nokia_widget)
+      {
+      	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";
+      }
+  }
+   
+    print OUT "</domain>\n";
+    print OUT "</accesspolicy>\n";
+    close OUT;
+
+  # Return the generated file
+  return $secSession;
+  }
+__END__
+
+=head1 NAME
+
+installwidgets.pl - A script for generating all the files needed to install Widgets
+
+=head1 SYNOPSIS
+
+installwidgets.pl [-h] [-ver] [-v] [-debug] [-e <dir>] [-l <lang_code|lproj.xml>] config.ini
+
+ Options:
+   -help|h                        Show this help
+   -version|ver                   Show version number
+   -verbose|v                     Show verbose output
+   -debug                         Show debug output
+   -epocroot|e                    Override value of EPOCROOT
+   -localization|l                lproj_dir
+
+A script for generating all the files needed to preinstall Widgets.
+
+ Example:
+   perl installwidgets.pl -l fr config.ini       Install widgets listed in config.ini using French localization
+
+ Author:
+   peter.harper@sosco.com
+
+=head1 DESCRIPTION
+
+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.
+It generates the results in the epoc32 folder - in the appropriate locations for the emulator.
+It finds the epoc32 folder using the EPOCROOT environment variable which can be overridden via the -e command line option.
+
+=head2 CONFIG FILE
+
+The preferred way to run the tool is via a configuration INI file.
+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.
+
+You can specify whether a widget is intended for the homescreen by adding the text [HomeScreen] after the filename
+This will set the BlanketPermissionGranted attribute in the registry.
+Widgets intended for the homescreen must have the MiniViewEnabled attribute set in its PLIST file otherwise an error is generated.
+
+    # Widgets to be pre-installed for the ROM
+    [drive-z]
+    \somepath\foo.wgz
+    \somepath\bar.wgz
+
+    # Widgets for the internal disk
+    [drive-c]
+    \somepath\widget1.wdgt.zip [HomeScreen]
+
+    # Widgets for the removable disk
+    [drive-e]
+    \somepath\widget2.wdgt.zip
+
+    # Commands to run at the end
+    [run-commands]
+    dostuff.pl
+    domorestuff.exe
+
+=head2 DEPENDENCIES
+
+The tool has some dependencies which must exist for it to work.
+
+=over
+
+=item 1
+
+png2mbm.pl - A script to generate an MBM file from a PNG
+
+=item 2
+
+WidgetRegFiles.exe - an EXE which can generate Symbian REG and LOC files for registering non-native Widget apps.
+This tool is built with "SymPort" a native tools port of basic Symbian OS services.
+
+=item 3
+
+7z/unzip - For extracting files from the Widget archive.
+7Zip will be used in preference to unzip if it's found on your path because it handles Unicode a better.
+
+=item 4
+
+GD.pm - Perl support for the GD graphics library for PNG support, see http://www.libgd.org .
+
+=back
+
+=head3 INSTALLING GD
+
+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.
+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.
+
+To install the GD library:
+
+=over
+
+=item *
+
+For Perl v5.6: "ppm install http://theoryx5.uwinnipeg.ca/ppmpackages/GD.ppd "
+
+=item *
+
+For Perl v5.8: "ppm install http://theoryx5.uwinnipeg.ca/ppms/GD.ppd "
+
+=back
+
+=head2 WIDGET INSTALL PROCESS
+
+Here's a detailed breakdown of what the script does.
+
+=over
+
+=item 1
+
+It gets the lists of Widgets from the config.ini file passed on the command line.
+This process is repeated for all Widgets and all drives listed in the config file.
+
+=item 2
+
+Any existing Widgets listed in "private\10282f06\WidgetEntryStore.xml" are deleted from the epoc32 tree.
+This ensures that there are no problems when testing Widgets in the emulator.
+
+=item 3
+
+All the compressed files in the Widget are extracted to a temporary folder.
+
+=item 4
+
+The details for the Widget are loaded from its "Info.plist" file.
+
+=item 5
+
+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).
+
+=item 5
+
+A Symbian MBM file is generated from the "Icon.png" file supplied by the Widgets.
+Three different sized icons are generated "88x88", "32x32" and "24x24".
+The MBM file is placed in "private/10003a3f/import/apps/NonNative/Resource/[<UID>].mbm".
+
+=item 6
+
+"WidgetRegFiles.exe" is executed to generate REG and LOC resource files used to register the Widget as an app in Symbian OS.
+These files are placed in "private/10003a3f/import/apps/NonNative/Resource".
+
+=item 7
+
+All the widgets files are copied to a folder under "private\10282822".
+The Widget's bundle identifier is used to create a unique folder under here for the Widget.
+
+=item 8
+
+The Widget registry is generated in "private\10282f06\WidgetEntryStore.xml"
+
+=item 9
+
+If Widgets are being preinstalled for ROM an IBY file is created in "epoc32\rom\include\preinstalledwidgets.iby".
+A separate IBY file is generated for the localised parts of a Widget "epoc32\rom\include\preinstalledwidgets_rsc.iby".
+Separate IBY files (per drive) are generated for Widgets preinstalled to UDA, e.g. preinstalledwidgets_driveC.iby and preinstalledwidgets_driveC_rsc.iby.
+These IBY files can be used to add all the Widgets to ROM, ROFS or UDA.
+
+=back
+
+=head3 INSTALLING ON HARDWARE USING iMaker
+
+=over
+
+=item 1
+
+Create the following folder structure at the root level.
+
+X:\variants\content
+
+=item 2
+
+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)
+
+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
+
+Drop the file under X:\variants\content\private\10282f06\WidgetEntryStore.xml 
+
+=item 3
+
+Run the foll command to generate UDA
+
+B<Gadget:>
+X:\epoc32\tools>imaker -f /epoc32/rom/s60_makefiles/image_conf_sp_rnd_gadget.mk VARIANT_DIR=/variants variantuda
+
+B<Tube:>
+Y:\epoc32\tools>imaker -f /epoc32/rom/config/ncp52/tube/image_conf_tube_ui.mk VARIANT_DIR=/variants variantuda 
+
+=item 4
+
+Flash the fpsx file generated under X:\epoc32\rombuild\gadget\uda for Gadget and Y:\epoc32\rombuild\tube\uda for Tube to your device.
+
+Note: More info on iMaker tool at: L<http://configurationtools.nmp.nokia.com/imaker/wiki/iMakerUserGuide>
+
+=back
+
+=head3 LOCALISATION
+
+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.
+
+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. 
+
+=head3 NOTES
+
+=over
+
+=item 1
+
+The location of the private folder is in the appropriate place for the files to appear in the emulator.
+This is different depending on the intended destination drive (see -dd command line option) for the Widget.
+e.g. "epoc32/release/winscw/udeb/z/", "epoc32/winscw/c" or "epoc32/winscw/e"
+
+=item 2
+
+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.
+
+=item 3
+
+A different IBY file is generated for each drive.
+
+=over
+
+=item *
+
+Z: - \epoc32\rom\include\preinstalledwidgets.iby
+
+=item *
+
+C: - \epoc32\rom\include\preinstalledwidgets_driveC.iby
+
+=item *
+
+E: - \epoc32\rom\include\preinstalledwidgets_driveE.iby
+
+=back
+
+There are separate resource files for localised resources e.g. preinstalledwidgets_rsc.iby.
+
+=cut