secureswitools/swisistools/source/makesislib/packageparser.cpp
changeset 0 ba25891c3a9e
child 23 09e5ea190d07
child 25 98b66e4fb0be
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 1997-2009 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 the License "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 * handles parsing of PKG file
       
    16 * Note: This file may contain code to generate corrupt files for test purposes.
       
    17 * Such code is excluded from production builds by use of compiler defines;
       
    18 * it is recommended that such code should be removed if this code is ever published publicly.
       
    19 * INCLUDES
       
    20 *
       
    21 */
       
    22 
       
    23 
       
    24 /**
       
    25  @file
       
    26  @internalComponent
       
    27  @released
       
    28 */
       
    29 
       
    30 #ifdef _MSC_VER
       
    31 #pragma warning (disable: 4786)
       
    32 #endif 
       
    33 
       
    34 #include <assert.h>
       
    35 #include <iostream>
       
    36 #include <stdio.h>
       
    37 #include <string>
       
    38 
       
    39 #include "packageparser.h"
       
    40 #include "utility_interface.h"
       
    41 #include "version.h"
       
    42 #include "utils.h"
       
    43 
       
    44 
       
    45 #define EOF_TOKEN			 0
       
    46 #define NUMERIC_TOKEN		 1
       
    47 #define ALPHA_TOKEN			 2
       
    48 #define QUOTED_STRING_TOKEN	 3
       
    49 #define AND_TOKEN			 4
       
    50 #define OR_TOKEN			 5
       
    51 #define NOT_TOKEN			 6
       
    52 #define EXISTS_TOKEN		 7
       
    53 #define DEVCAP_TOKEN		 8
       
    54 #define APPCAP_TOKEN		 9
       
    55 #define GE_TOKEN			 10
       
    56 #define LE_TOKEN			 11
       
    57 #define NE_TOKEN			 12
       
    58 #define IF_TOKEN			 13
       
    59 #define ELSEIF_TOKEN		 14
       
    60 #define ELSE_TOKEN			 15
       
    61 #define ENDIF_TOKEN			 16
       
    62 #define TYPE_TOKEN			 17
       
    63 #define KEY_TOKEN			 18
       
    64 #define VERSION_TOKEN		 19
       
    65 #define SUPPORTED_LANG_TOKEN 20
       
    66 #define LAST_TOKEN			 20
       
    67 
       
    68 
       
    69 
       
    70 TDuplicates CPackageParser::iSrcFiles;
       
    71 
       
    72 // ===========================================================================
       
    73 // CONSTANTS
       
    74 // ===========================================================================
       
    75 
       
    76 // Set up the cout stream so that we can use it with either narrow or wide
       
    77 // chars at build time
       
    78 
       
    79 #ifndef _UNICODE
       
    80 #error _UNICODE expected
       
    81 #endif // _UNICODE
       
    82 
       
    83 
       
    84 // Parse options lookups
       
    85 const SParseOpt KHeaderOptions[] =
       
    86 	{
       
    87 		{L"IU", EInstIsUnicode},
       
    88 		{L"SH", EInstShutdownApps},
       
    89 		{L"NC", EInstNoCompress},
       
    90 		{L"IUNICODE",		EInstIsUnicode},
       
    91 		{L"SHUTDOWNAPPS",	EInstShutdownApps},
       
    92 		{L"NOCOMPRESS",		EInstNoCompress},
       
    93 		{L"NR",				EInstNonRemovable},
       
    94 		{L"NONREMOVABLE",	EInstNonRemovable},
       
    95 		{L"RU",				EInstROMUpgrade},
       
    96  		{L"ROMUPGRADE",		EInstROMUpgrade},
       
    97  		{L"H",				EInstHide},
       
    98  		{L"HIDE",			EInstHide}
       
    99 
       
   100 	};
       
   101 #define NUMHEADEROPTIONS (sizeof(KHeaderOptions)/sizeof(SParseOpt))
       
   102 
       
   103 // Parse options lookups
       
   104 #define MAXTOKENLEN	30
       
   105 struct SParseToken
       
   106 	{
       
   107 	WCHAR pszOpt[MAXTOKENLEN];
       
   108 	DWORD dwOpt;
       
   109 	};
       
   110 
       
   111 const SParseToken KTokens[] =
       
   112 	{
       
   113 		{L"if",			IF_TOKEN},
       
   114 		{L"elseif",		ELSEIF_TOKEN},
       
   115 		{L"else",		ELSE_TOKEN},
       
   116 		{L"endif",		ENDIF_TOKEN},
       
   117 		{L"exists",		EXISTS_TOKEN},
       
   118 		{L"devcap",		DEVCAP_TOKEN},
       
   119 		{L"appcap",		APPCAP_TOKEN},
       
   120 		{L"package",	DEVCAP_TOKEN},
       
   121 		{L"appprop",	APPCAP_TOKEN},
       
   122 		{L"not",		NOT_TOKEN},
       
   123 		{L"and",		AND_TOKEN},
       
   124 		{L"or",			OR_TOKEN},
       
   125 		{L"type",		TYPE_TOKEN},
       
   126 		{L"key",		KEY_TOKEN},
       
   127 		{L"version",	VERSION_TOKEN},
       
   128 		{L"supported_language",SUPPORTED_LANG_TOKEN},
       
   129 
       
   130 	};
       
   131 #define NUMPARSETOKENS (sizeof(KTokens)/sizeof(SParseToken))
       
   132 
       
   133 // ===========================================================================
       
   134 // CPackageParser
       
   135 // ===========================================================================
       
   136 
       
   137 CPackageParser::CPackageParser(MParserObserver& aObserver) :
       
   138 				iValidSISFile(true),
       
   139 				iMakeStub(false),
       
   140 				iReportInterpretSisError(false),
       
   141 				iEnoughForStub(false),
       
   142 				iIsHeaderDefined(false),
       
   143 				iUniqueVendorName (false),
       
   144 				iLocalisedVendorNames (false),
       
   145 				iPkgChar(0),
       
   146 				iLineNo(0),	   		// The line we are currently on
       
   147 				iCurrentLang(0),	// If we are in a lang/lang file block - which lang are we processing
       
   148 				iToken(0),
       
   149 				iFileHandle(0),
       
   150 				iObserver(aObserver)
       
   151 	{
       
   152 	memset((void *)iSearchDir, 0x0000, PATHMAX * sizeof(wchar_t));
       
   153 	}
       
   154 
       
   155 void CPackageParser::SetSearchDirectory(LPCWSTR pszPath)
       
   156 // Purpose  : Sets the search directory
       
   157 // Inputs   : pszPath  - The directory path (including trailing backslash!)
       
   158 	{
       
   159 	wcsncpy(iSearchDir, pszPath, PATHMAX - 1);
       
   160 	DWORD len=wcslen(iSearchDir);
       
   161 	wchar_t *pBuffer = iSearchDir;
       
   162 	wchar_t *pCurrent = pBuffer;
       
   163 
       
   164 	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'\\')) != NULL)
       
   165 		{
       
   166 		*pCurrent = L'/';
       
   167 		pBuffer = pCurrent + 1;
       
   168 		} 
       
   169 
       
   170 	if(len>0 && iSearchDir[len - 1] != '/')
       
   171 		{
       
   172 		iSearchDir[len] = '/';
       
   173 		iSearchDir[len+1] = '\0';
       
   174 		}
       
   175 
       
   176 	}
       
   177 
       
   178 void CPackageParser::MakeSis(const wchar_t* aPkgFileName, const wchar_t* aSisFileName, bool aMakeStub, bool aReportInterpretSisError)
       
   179 	{
       
   180 	iMakeStub = aMakeStub;
       
   181 	iReportInterpretSisError = aReportInterpretSisError;
       
   182 	ParseL(aPkgFileName);
       
   183 	// Turn off line number output
       
   184 	iObserver.SetLineNumber(0);
       
   185 	
       
   186 	if (iMakeStub)
       
   187 		iObserver.DoVerbage(L"Generating SIS stub file...");
       
   188 	else
       
   189 		iObserver.DoVerbage(L"Generating SIS installation file...");
       
   190 	
       
   191 	if (iValidSISFile)
       
   192 		{
       
   193 		iSISXWriter.WriteSIS (aSisFileName);
       
   194 		}
       
   195 	}
       
   196 
       
   197 HANDLE CPackageParser::OpenPackageFile(const wchar_t* aPkgFileName)
       
   198 	{
       
   199 	bool fResult = true;
       
   200 	wchar_t pszTempSource [PATHMAX];
       
   201 	bool converted = true;
       
   202 	HANDLE hFile = 0;
       
   203 
       
   204 	TEncodingScheme encScheme;
       
   205 	if (!FileIsUnicode(aPkgFileName,encScheme))
       
   206 		{
       
   207 		if ( EUtf8 != encScheme )
       
   208 			iObserver.DoVerbage(L"Byte order marker not detected. Assuming UTF-8 encoding");
       
   209 		iObserver.DoVerbage(L"Encoding scheme: UTF8");
       
   210 		wcscpy(pszTempSource,ConvertFileToUnicode(aPkgFileName,encScheme));
       
   211 		}
       
   212 	else if (encScheme == EUcs2BE && sizeof(WCHAR) == 2)
       
   213 		{
       
   214 		iObserver.DoVerbage(L"Encoding scheme: UCS2 (BE)");
       
   215 		wcscpy(pszTempSource,ConvertUCS2FileToLittleEndianUnicode(aPkgFileName));
       
   216 		}
       
   217 	/*
       
   218 		Linux first needs conversion to little endian and then into ucs-4
       
   219 		Linux has wchar in 4 bytes and processing of .pkg file happens based on wchar
       
   220 		so need conversion here from ucs2 to ucs4
       
   221 	*/
       
   222 	else if (encScheme == EUcs2BE && sizeof(WCHAR) == 4)
       
   223 		{
       
   224 		iObserver.DoVerbage(L"Encoding scheme: UCS2 (BE)");
       
   225 		wcscpy(pszTempSource,ConvertUCS2FileToLittleEndianUnicode(aPkgFileName));
       
   226 		wcscpy(pszTempSource,ConvertUCS2FileToUCS4(pszTempSource));
       
   227 		}
       
   228 	else if (encScheme == EUcs2LE && sizeof(WCHAR) == 2)
       
   229 		{
       
   230 		iObserver.DoVerbage(L"Encoding scheme: UCS2 (LE)");
       
   231 		wcscpy(pszTempSource, aPkgFileName);
       
   232 		converted = false;
       
   233 		}
       
   234 	// Convert UCS2 file to UCS4 for Linux
       
   235 	else if (encScheme == EUcs2LE && sizeof(WCHAR) == 4)
       
   236 		{
       
   237 		iObserver.DoVerbage(L"Encoding scheme: UCS2 (LE)");
       
   238 		wcscpy(pszTempSource,ConvertUCS2FileToUCS4(aPkgFileName));
       
   239 		}
       
   240 	else
       
   241 		{
       
   242 		iObserver.DoVerbage(L"Encoding scheme not supported");
       
   243 		throw ErrCannotOpenFile;
       
   244 		}
       
   245 	
       
   246 	hFile = ::MakeSISOpenFile(pszTempSource,GENERIC_READ,OPEN_EXISTING);
       
   247 
       
   248 	if (hFile==INVALID_HANDLE_VALUE)
       
   249 		{
       
   250 		throw ErrCannotOpenFile;
       
   251 		}
       
   252 	
       
   253 	if(encScheme == EUtf8)
       
   254 		{
       
   255 		UnicodeMarker(hFile);
       
   256 		}
       
   257 
       
   258 	if(converted)
       
   259 		{
       
   260 		_wunlink(pszTempSource);
       
   261 		}
       
   262 	
       
   263 	return hFile;
       
   264 	}
       
   265 
       
   266 void CPackageParser::ParseL (const wchar_t* aPkgFileName)
       
   267 // Purpose  : Check the contents of an input line and defers parsing to the appropriate ParseXXXL()
       
   268 //			  method
       
   269 // Inputs   : m_pkgPtr - The line to process
       
   270 	{
       
   271 	iValidSISFile = true;
       
   272 	iFileHandle = OpenPackageFile(aPkgFileName);
       
   273 	assert(iFileHandle != INVALID_HANDLE_VALUE);
       
   274 
       
   275 	iEnoughForStub = false;
       
   276 	iSISXWriter.SetDefaultContent ();
       
   277 
       
   278 	iObserver.SetLineNumber(++iLineNo);
       
   279 
       
   280 	// Make sure we're at the beginning of the file
       
   281 	::SetFilePointer(iFileHandle, 0L, NULL, FILE_BEGIN);
       
   282 
       
   283 	GetNextChar();
       
   284 
       
   285 	// skip unicode marker if present
       
   286 	if(iPkgChar==0xFEFF) GetNextChar();
       
   287 
       
   288 	GetNextToken ();
       
   289 	while(iToken!=EOF_TOKEN && !(iMakeStub && iEnoughForStub))
       
   290 		{
       
   291 		ParseEmbeddedBlockL (iSISXWriter.InstallBlock ());
       
   292 		switch (iToken)
       
   293 			{
       
   294 			case '&':
       
   295 				// Pkg file keyword check is disabled here 
       
   296  				// to avoid conflicts with the language code 
       
   297  				// (e.g. "IF - International French").
       
   298  				GetNextToken (1);
       
   299 				ParseLanguagesL();
       
   300 				break;
       
   301 			case '#':
       
   302 				GetNextToken ();
       
   303 				ParseHeaderL();
       
   304 				break;
       
   305 			case '%':
       
   306 				GetNextToken ();
       
   307 				ParseVendorNameL();
       
   308 				break;
       
   309 			case '=':
       
   310 				GetNextToken ();
       
   311 				ParseLogoL();
       
   312 				break;
       
   313 			case '(':
       
   314 				GetNextToken ();
       
   315 				ParseDependencyL();
       
   316 				break;
       
   317 			case '*':
       
   318 				GetNextToken ();
       
   319 				ParseSignatureL();
       
   320 				break;
       
   321 			case ':':
       
   322 				GetNextToken ();
       
   323 				ParseVendorUniqueNameL();
       
   324 				break;
       
   325 			case '[':
       
   326 				GetNextToken ();
       
   327 				ParseTargetDeviceL();
       
   328 				break;
       
   329 			case EOF_TOKEN:
       
   330 				break;
       
   331 			default :
       
   332 				{
       
   333 				throw ErrUnknownLine;
       
   334 				}
       
   335 			}
       
   336 		}
       
   337 	if (! iUniqueVendorName && ! iLocalisedVendorNames)
       
   338 		{
       
   339 		iObserver.DoMsg(L"No vendor names found.\n");
       
   340 		}
       
   341 	else if (! iLocalisedVendorNames)
       
   342 		{
       
   343 		iObserver.DoMsg(L"Localised vendor names not found.\n");
       
   344 		}
       
   345 	else if (! iUniqueVendorName)
       
   346 		{
       
   347 		iObserver.DoMsg(L"Unique vendor name not found.\n");
       
   348 		}
       
   349 	
       
   350 	if (iFileHandle)
       
   351 		{
       
   352 		::CloseHandle(iFileHandle);
       
   353 		}
       
   354 	}
       
   355 
       
   356 void CPackageParser::ParseEmbeddedBlockL (CSISInstallBlock& aInstall)
       
   357 	{
       
   358 	while(iToken!=EOF_TOKEN)
       
   359 		{
       
   360 		switch (iToken)
       
   361 			{
       
   362 			case QUOTED_STRING_TOKEN:
       
   363 				ParseFileL (aInstall);
       
   364 				break;
       
   365 			case '@':
       
   366 				GetNextToken ();
       
   367 				ParsePackageL (aInstall);
       
   368 				break;
       
   369 			case '!':
       
   370 				GetNextToken ();
       
   371 				ParseOptionsBlockL();
       
   372 				break;
       
   373 			case '{':
       
   374 				GetNextToken ();
       
   375 				ParseLanguageBlockL (aInstall);
       
   376 				break;
       
   377 			case '+':
       
   378 				GetNextToken ();
       
   379 				ParsePropertyL ();
       
   380 				break;
       
   381 			case IF_TOKEN:
       
   382 				GetNextToken ();
       
   383 				ParseIfBlockL (aInstall);
       
   384 				break;
       
   385 			case ';' :
       
   386 				ParseCommentL ();
       
   387 				break;
       
   388 			default :
       
   389 				return;
       
   390 			}
       
   391 		}
       
   392 	}
       
   393 
       
   394 void CPackageParser::ParseLanguagesL()
       
   395 // Parses the language definition line
       
   396 // Updated to support "dialects"
       
   397 // Dialect definition syntax is: <language>["("<dialect-code>")"]
       
   398 
       
   399 	{
       
   400 	iObserver.DoVerbage(L"processing languages");
       
   401 
       
   402 	if (iSISXWriter.AreLanguagesSpecified ())
       
   403 		throw ErrLanguagesAlreadyDefined;
       
   404 
       
   405 	CSISLanguage::TDialect dialect (0);
       
   406 
       
   407 	while (true)
       
   408 		{
       
   409 		if (iToken==ALPHA_TOKEN)
       
   410 			{
       
   411 			dialect = CSISLanguage::IdentifyLanguage (iTokenValue.pszString);
       
   412 			if (dialect == CSISLanguage::ELangNone) throw ErrUnknownLanguagesId;
       
   413 			}
       
   414 		else if (iToken==NUMERIC_TOKEN && iTokenValue.dwNumber>=0 && iTokenValue.dwNumber<=1000)
       
   415 			{
       
   416 			dialect = static_cast <CSISLanguage::TDialect> (iTokenValue.dwNumber);
       
   417 			}
       
   418 		else
       
   419 			throw ErrUnknownLanguagesId;
       
   420 		GetNextToken ();
       
   421 		// Check if a dialect is defined
       
   422 		if (iToken == '(')
       
   423 			{
       
   424 			GetNumericToken();
       
   425 			// Modify the last added language code, combining it with dialect code
       
   426 			if (dialect) dialect = dialect + static_cast <CSISLanguage::TDialect> (iTokenValue.dwNumber);
       
   427 			GetNextToken ();
       
   428 			if (iToken != ')')
       
   429 				throw ErrUnexpectedToken;
       
   430 			GetNextToken ();
       
   431 			}
       
   432 		iSISXWriter.AddLanguage (dialect);
       
   433 		dialect=0;
       
   434 		if (iToken!=',')
       
   435 			return;
       
   436 		GetNextToken (1);
       
   437 		}
       
   438 	}
       
   439 
       
   440 
       
   441 void CPackageParser::ParseHeaderL()
       
   442 // Parses the pkg header line
       
   443 	{
       
   444 	iObserver.DoVerbage(L"processing header");
       
   445 
       
   446 	// Default type
       
   447 	std::wstring interpretType = L"SA";
       
   448 	bool isNonRemovable = false;
       
   449 
       
   450 	// By default the ROM Upgradeable flag (RU) is FALSE.
       
   451 	bool isROMUpgrade = false;
       
   452 
       
   453 	if (iIsHeaderDefined)
       
   454 		throw ErrHeaderAlreadyDefined;
       
   455 
       
   456 	if (! iSISXWriter.AreLanguagesSpecified ())
       
   457 		{
       
   458 		iObserver.DoVerbage (L"No languages defined, assuming English.");
       
   459 		}
       
   460 
       
   461 	// process application names
       
   462 	ExpectToken('{');
       
   463 	for (WORD wNumLangs = 0; wNumLangs < iSISXWriter.GetNoLanguages(); wNumLangs++)
       
   464 		{
       
   465 		GetNextToken ();
       
   466 		ExpectToken(QUOTED_STRING_TOKEN);
       
   467 		iSISXWriter.AddName (iTokenValue.pszString);
       
   468 		GetNextToken ();
       
   469 		if (wNumLangs < iSISXWriter.GetNoLanguages() -1 )
       
   470 			{
       
   471 			ExpectToken(',');
       
   472 			}
       
   473 		}
       
   474 	ExpectToken('}');
       
   475 	GetNextToken ();
       
   476 
       
   477 	DWORD dwFlags = 0;
       
   478 	DWORD dwType = 0;
       
   479 
       
   480 	ExpectToken(',');
       
   481 	GetNextToken ();
       
   482 	ExpectToken('(');
       
   483 	GetNextToken ();
       
   484 
       
   485 	ExpectToken(NUMERIC_TOKEN);
       
   486 	CSISUid::TUid uid = iTokenValue.dwNumber;
       
   487 	GetNextToken ();
       
   488 
       
   489 	ExpectToken(')');
       
   490 	GetNextToken ();
       
   491 	ExpectToken(',');
       
   492 	GetNextToken ();
       
   493 
       
   494 	ExpectToken(NUMERIC_TOKEN);
       
   495 	CSISVersion::TMajor major = iTokenValue.dwNumber;
       
   496 	GetNextToken ();
       
   497 	ExpectToken(',');
       
   498 	GetNextToken ();
       
   499 
       
   500 	ExpectToken(NUMERIC_TOKEN);
       
   501 	CSISVersion::TMinor minor = iTokenValue.dwNumber;
       
   502 	GetNextToken ();
       
   503 	ExpectToken(',');
       
   504 	GetNextToken ();
       
   505 
       
   506 	ExpectToken(NUMERIC_TOKEN);
       
   507 	CSISVersion::TBuild build = iTokenValue.dwNumber;
       
   508 	GetNextToken ();
       
   509 
       
   510 	ValidateVersion(major,minor,build);
       
   511 
       
   512 	// Parse any options
       
   513 	bool narrow=false;
       
   514 	while (iToken==',')
       
   515 		{
       
   516 		GetNextToken ();
       
   517 		if (iToken==TYPE_TOKEN)
       
   518 			{
       
   519 			GetNextToken ();
       
   520 			ExpectToken('=');
       
   521 			GetNextToken ();
       
   522 			interpretType = iTokenValue.pszString;
       
   523 			iSISXWriter.InterpretType (iTokenValue.pszString);
       
   524 			GetNextToken ();
       
   525 			}
       
   526 		else
       
   527 			{
       
   528 			DWORD option=ParseOption(KHeaderOptions,NUMHEADEROPTIONS,&dwFlags);
       
   529 			narrow=(option==0);
       
   530 
       
   531 			switch (option)
       
   532 				{
       
   533 
       
   534 			case EInstShutdownApps:
       
   535 				iSISXWriter.AddInstallFlag(CSISInfo::EInstFlagShutdownApps);
       
   536 				break;
       
   537 
       
   538 			case EInstNonRemovable:
       
   539 				isNonRemovable = true;
       
   540 				iSISXWriter.AddInstallFlag(CSISInfo::EInstFlagNonRemovable);
       
   541 				break;			
       
   542 				
       
   543 			case EInstROMUpgrade:
       
   544 				isROMUpgrade = true;
       
   545 				iSISXWriter.AddInstallFlag(CSISInfo::EInstFlagROMUpgrade);
       
   546 				break;
       
   547 				
       
   548 			case EInstHide:
       
   549 			#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK				
       
   550 				iSISXWriter.AddInstallFlag(CSISInfo::EInstFlagHide);
       
   551 			#endif				
       
   552 				break;
       
   553 				}			
       
   554 			}
       
   555 		}
       
   556 		
       
   557 	//ROM Upgrade is applicable only for SA, PU & SP, reject package file if RU is coupled 
       
   558  	//with anything other than these three install types. 
       
   559  	if(isROMUpgrade && ((interpretType != L"SA") && (interpretType != L"PU") && (interpretType != L"SP")))
       
   560  		{ 		
       
   561 		throw ErrInvalidInstallFlagOption;
       
   562  		}		
       
   563 
       
   564 	// Reject package types PA-PP if marked non-removable
       
   565 	if (isNonRemovable && (interpretType == L"PA" || interpretType == L"PP"))
       
   566 		{
       
   567 		throw ErrHeaderRejectPreInstalledNonRemovable;
       
   568 		}
       
   569 
       
   570 	if (InterpretSis() && (interpretType == L"PP"))
       
   571 		{
       
   572 		ReportInterpretSisError(ErrInvalidAppType);
       
   573 		}
       
   574 
       
   575 	// if narrow not explicitly set default to unicode
       
   576 	if (!narrow) dwFlags|=EInstIsUnicode;
       
   577 
       
   578    	iSISXWriter.SetVersionInfo (uid, TVersion (major, minor, build), dwType, dwFlags);
       
   579 	iIsHeaderDefined = true;
       
   580 	}
       
   581 
       
   582 void CPackageParser::ParseVendorNameL ()
       
   583 	{
       
   584 	iObserver.DoVerbage(L"processing vendor name");
       
   585 
       
   586 	ExpectToken('{');
       
   587 	for (WORD wNumLangs = 0; wNumLangs < iSISXWriter.GetNoLanguages(); wNumLangs++)
       
   588 		{
       
   589 		GetNextToken ();
       
   590 		ExpectToken(QUOTED_STRING_TOKEN);
       
   591 		iSISXWriter.AddVendorName (iTokenValue.pszString);
       
   592 		GetNextToken ();
       
   593 		if (wNumLangs < iSISXWriter.GetNoLanguages() -1 )
       
   594 			{
       
   595 			ExpectToken(',');
       
   596 			}
       
   597 		}
       
   598 	ExpectToken('}');
       
   599 	GetNextToken ();
       
   600 	iLocalisedVendorNames = true;
       
   601 	}
       
   602 
       
   603 void CPackageParser::ParseLogoL ()
       
   604 	{
       
   605 	iObserver.DoVerbage(L"processing logo");
       
   606 
       
   607 	ExpectToken (QUOTED_STRING_TOKEN);
       
   608 	std::wstring file (iTokenValue.pszString);
       
   609 
       
   610 	const wchar_t *pBuffer = file.c_str();
       
   611 	wchar_t *pCurrent = const_cast<wchar_t*>(pBuffer);
       
   612 	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'\\')) != NULL)
       
   613 		{
       
   614 		*pCurrent = L'/';
       
   615 		pBuffer = pCurrent + 1;
       
   616 		}
       
   617 
       
   618 	GetNextToken ();
       
   619 	ExpectToken(',');
       
   620 	GetNextToken ();
       
   621 	ExpectToken (QUOTED_STRING_TOKEN);
       
   622 	std::wstring mime (iTokenValue.pszString);
       
   623 
       
   624 	pBuffer = mime.c_str();
       
   625 	pCurrent = const_cast<wchar_t*>(pBuffer);
       
   626 	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'\\')) != NULL)
       
   627 		{
       
   628 		*pCurrent = L'/';
       
   629 		pBuffer = pCurrent + 1;
       
   630 		}
       
   631 
       
   632 	GetNextToken ();
       
   633 	std::wstring target;
       
   634 
       
   635 	if (iToken==',')
       
   636 		{
       
   637 		GetNextToken ();
       
   638 		ExpectToken (QUOTED_STRING_TOKEN);
       
   639 		target = iTokenValue.pszString;
       
   640 		}
       
   641 	iSISXWriter.SetLogo (file, mime, target);
       
   642 	const CSISLogo& logo = iSISXWriter.SISContent().Controller().Logo();
       
   643 	CSISFileDescription& fd = const_cast<CSISFileDescription&>(logo.FileDesc());
       
   644 	ComputeAndSetHash(fd);
       
   645 	GetNextToken ();
       
   646 	}
       
   647 
       
   648 void CPackageParser::ParseFileL (CSISInstallBlock& aInstall)
       
   649 // Parses a file definition line
       
   650 	{
       
   651 	iObserver.DoVerbage(L"processing file");
       
   652 	bool fileProblem = false;
       
   653 
       
   654 	if (! iIsHeaderDefined)
       
   655 		throw ErrHeaderNotDefined;
       
   656 
       
   657 	std::wstring sourceFile (iTokenValue.pszString);
       
   658 
       
   659 	// Linux and windows both support forward slashes so if source path is given '\' need to convert
       
   660 	// in forward slash for compatibility.
       
   661 	const wchar_t *pBuffer = sourceFile.c_str();
       
   662 	wchar_t *pCurrent = const_cast<wchar_t*>(pBuffer);
       
   663 	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'\\')) != NULL)
       
   664 		{
       
   665 		*pCurrent = L'/';
       
   666 		pBuffer = pCurrent + 1;
       
   667 		}
       
   668 
       
   669 	TUint64 size;
       
   670 	TUint64 compressedSize = 0;
       
   671 
       
   672 	bool isFileNameEmpty = sourceFile.empty ();
       
   673 	if(CSISContents::IsPreInstalledApp() && isFileNameEmpty)
       
   674 		{
       
   675 		fileProblem = true;
       
   676 		iObserver.DoMsg(L" Error : Source file is missing for PreInstalled APP : ");
       
   677 		CSISException::ThrowIf (fileProblem ,
       
   678 							CSISException::EFileProblem,
       
   679 							std::wstring (L"Source file is missing for PreInstalled APP "));
       
   680 		}
       
   681 
       
   682 	if(! isFileNameEmpty && ! DoesFileExist (sourceFile, size))
       
   683 		{
       
   684 		wchar_t msg[255];
       
   685 		wcscpy(msg, L"Cannot find file : ");
       
   686 		wcscat(msg, sourceFile.c_str());
       
   687 		wcsncat(msg, L"\n", 1);
       
   688 		iObserver.DoErrMsg(msg);
       
   689 		fileProblem = true;
       
   690 		}
       
   691 
       
   692 	CSISException::ThrowIf (fileProblem ,
       
   693 							CSISException::EFileProblem,
       
   694 							std::wstring (L"cannot find ") + sourceFile);
       
   695 
       
   696 	GetNextToken ();
       
   697 
       
   698 	ExpectToken('-');
       
   699 	GetNextToken ();
       
   700 
       
   701 	ExpectToken(QUOTED_STRING_TOKEN);
       
   702 
       
   703 	// BAW-5CQEA5 Check for invalid destination (i.e starts with ':')
       
   704 	if ((sourceFile.size () > 0) && (sourceFile [0] == ':'))
       
   705 		throw ErrBadDestinationPath;
       
   706 
       
   707 	std::wstring destinationFile (iTokenValue.pszString);
       
   708 
       
   709 	// SWI only supports backward slashesh so need to convert destination path in backward slash if
       
   710 	// user gives '/' in Linux.
       
   711 	pBuffer = destinationFile.c_str();
       
   712 	pCurrent = const_cast<wchar_t*>(pBuffer);
       
   713 	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'/')) != NULL)
       
   714 		{
       
   715 		*pCurrent = L'\\';
       
   716 		pBuffer = pCurrent + 1;
       
   717 		}
       
   718 
       
   719 	// SWI only supports backward slashesh so need to convert destination path in backward slash if
       
   720 	// user gives '/' in Linux.
       
   721 	pBuffer = destinationFile.c_str();
       
   722 	pCurrent = const_cast<wchar_t*>(pBuffer);
       
   723 	while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'/')) != NULL)
       
   724 		{
       
   725 		*pCurrent = L'\\';
       
   726 		pBuffer = pCurrent + 1;
       
   727 		} 	
       
   728 
       
   729 	bool bNewFile = true;
       
   730 	// CSisFileDescription is allocated on the heap, since the compiler does not support well
       
   731 	// its allocation on the stack combined with exceptions (DEF108815)
       
   732 	std::auto_ptr<CSISFileDescription> fd(new CSISFileDescription);
       
   733 	TUint32 fileIndex = Find((wchar_t*)sourceFile.c_str(),*fd);
       
   734 	if ( fileIndex == -1 )
       
   735 		{
       
   736 		aInstall.AddFileDescription ();
       
   737 		}
       
   738 	else
       
   739 		{
       
   740 		aInstall.AddFileDescription (*fd);
       
   741 		bNewFile = false;
       
   742 		}
       
   743 
       
   744 	if (! isFileNameEmpty)
       
   745 		{
       
   746 		if ( bNewFile )
       
   747 			{
       
   748 			TUint64 size = 0;
       
   749 			fileIndex = iSISXWriter.LoadFile (sourceFile, &size);
       
   750 			aInstall.SetFileIndex (fileIndex);
       
   751 			aInstall.ExtractCapabilities(sourceFile);
       
   752 			aInstall.SetLengths (size, iSISXWriter.CompressedSize ());
       
   753 			ComputeAndSetHash(aInstall.FileDescription());
       
   754 
       
   755 			Set(sourceFile,aInstall.FileDescription());
       
   756 			}
       
   757 		}
       
   758 
       
   759 	aInstall.SetTarget (destinationFile);
       
   760 
       
   761 	GetNextToken ();
       
   762 
       
   763 	if ( !bNewFile )
       
   764 		{
       
   765 		CSISFileDescription& fdLast = aInstall.FileDescription();
       
   766 		fdLast.SetOperation(0);
       
   767 		fdLast.SetOptions(0);
       
   768 		}
       
   769 
       
   770 	// Test for options
       
   771 	if (iToken!=',')
       
   772 		{
       
   773 		aInstall.SetOperation (CSISFileDescription::EOpInstall);
       
   774 		}
       
   775 	else
       
   776 		{
       
   777 		GetNextToken ();
       
   778 
       
   779 		CSISFileDescription::TSISInstOption type = aInstall.InterpretOption (iTokenValue.pszString);
       
   780 		GetNextToken ();
       
   781 		if (type == CSISFileDescription::EInstFileRunOptionByMimeType)
       
   782 			{
       
   783 			ExpectToken (',');
       
   784 			GetNextToken ();
       
   785 			ExpectToken (QUOTED_STRING_TOKEN);
       
   786 			aInstall.SetMimeType (iTokenValue.pszString);
       
   787 			GetNextToken ();
       
   788 			}
       
   789 		if (iToken==',')
       
   790 			{
       
   791 			do
       
   792 				{
       
   793    
       
   794 				GetNextToken ();
       
   795 				aInstall.InterpretOption (iTokenValue.pszString);
       
   796 
       
   797 				//if the next token is a comma , then continue.
       
   798 				GetNextToken ();
       
   799 
       
   800 				} while (iToken == ',');
       
   801 
       
   802 			}
       
   803 		}
       
   804 
       
   805 	}
       
   806 
       
   807 void CPackageParser::ParsePackageL (CSISInstallBlock& aInstall)
       
   808 // Parses a package (component SIS file) line
       
   809 	{
       
   810 	iObserver.DoVerbage(L"processing embedded package file");
       
   811 
       
   812 	if (InterpretSis())
       
   813 		{
       
   814 		ReportInterpretSisError(ErrEmbeddedSisNotSupported);
       
   815 		}
       
   816 
       
   817 	if (! iIsHeaderDefined)
       
   818 		throw ErrHeaderNotDefined;
       
   819 
       
   820 	ExpectToken(QUOTED_STRING_TOKEN);
       
   821 	WCHAR pszFile[MAX_STRING];
       
   822 	wcscpy(pszFile,iTokenValue.pszString);
       
   823 	std::wstring fileName;
       
   824 	std::wstring name;
       
   825 	//check whether search directory is specified.
       
   826 	if(iSearchDir[0] != '\0')
       
   827 		{
       
   828 		if ((wcslen (iSearchDir) + wcslen (pszFile)) < PATHMAX - 1)
       
   829 			{
       
   830 			WCHAR pszNewPath[PATHMAX];
       
   831 			wcscpy(pszNewPath, iSearchDir);
       
   832 			wcscat(pszNewPath, pszFile);
       
   833 			fileName.append(pszNewPath);
       
   834 			}
       
   835 		}
       
   836 	else
       
   837 		{
       
   838 		name = iTokenValue.pszString;
       
   839 		}
       
   840 
       
   841 
       
   842 	// Test that the file exists
       
   843 	GetNextToken ();
       
   844 
       
   845 	ExpectToken(',');
       
   846 	GetNextToken ();
       
   847 	ExpectToken('(');
       
   848 	GetNextToken ();
       
   849 	ExpectToken(NUMERIC_TOKEN);
       
   850 	CSISUid::TUid uid = iTokenValue.dwNumber;
       
   851 	GetNextToken ();
       
   852 	ExpectToken(')');
       
   853 	GetNextToken ();
       
   854 
       
   855 	if(iSearchDir[0] != '\0')
       
   856 		{
       
   857 		iSISXWriter.EmbedFile (fileName, uid, aInstall );
       
   858 		}
       
   859 	else
       
   860 		{
       
   861 		iSISXWriter.EmbedFile (name, uid, aInstall );
       
   862 		}
       
   863 	}
       
   864 
       
   865 TVersion CPackageParser::ParseVersion()
       
   866 // Parse version information for dependency lines
       
   867 	{
       
   868 
       
   869 	CSISVersion::TMajor major;
       
   870 	GetNextToken();
       
   871 	if (iToken == '*')
       
   872 		{
       
   873 		major = -1;
       
   874 		}
       
   875 	else
       
   876 		{
       
   877 		ExpectToken(NUMERIC_TOKEN);
       
   878 		major = iTokenValue.dwNumber;
       
   879 		}
       
   880 
       
   881 	GetNextToken();
       
   882 	ExpectToken(',');
       
   883 
       
   884 	CSISVersion::TMinor minor;
       
   885 	GetNextToken();
       
   886 	if (iToken == '*')
       
   887 		{
       
   888 		minor = -1;
       
   889 		}
       
   890 	else
       
   891 		{
       
   892 		ExpectToken(NUMERIC_TOKEN);
       
   893 		minor = iTokenValue.dwNumber;
       
   894 		}
       
   895 
       
   896 	GetNextToken();
       
   897 	ExpectToken(',');
       
   898 
       
   899 	CSISVersion::TBuild build;
       
   900 	GetNextToken();
       
   901 	if (iToken == '*')
       
   902 		{
       
   903 		build = -1;
       
   904 		}
       
   905 	else
       
   906 		{
       
   907 		ExpectToken(NUMERIC_TOKEN);
       
   908 		build = iTokenValue.dwNumber;
       
   909 		}
       
   910 
       
   911 	GetNextToken();
       
   912 
       
   913 	ValidateVersion(major, minor, build);
       
   914 	
       
   915 	return TVersion(major, minor, build);
       
   916 
       
   917 	}
       
   918 
       
   919 void CPackageParser::ParseDependencyL()
       
   920 // Parses a dependency line
       
   921 	{
       
   922 	iObserver.DoVerbage(L"processing dependency");
       
   923 
       
   924 	if (! iIsHeaderDefined)
       
   925 		throw ErrHeaderNotDefined;
       
   926 
       
   927 	ExpectToken(NUMERIC_TOKEN);
       
   928 	CSISUid::TUid uid = iTokenValue.dwNumber;
       
   929 	GetNextToken ();
       
   930 
       
   931 	ExpectToken(')');
       
   932 	GetNextToken ();
       
   933 	ExpectToken(',');
       
   934 
       
   935 	TVersion from = ParseVersion();
       
   936 	TVersion to(-1,-1,-1);
       
   937 
       
   938 	if (iToken == '~')
       
   939 		{
       
   940 		to = ParseVersion();
       
   941 		ExpectToken(',');
       
   942 		}
       
   943 	else if (iToken == ',')
       
   944 		{
       
   945 		to = TVersion(KIrrelevant, KIrrelevant, KIrrelevant);
       
   946 		}
       
   947 	else
       
   948 		{
       
   949 		iObserver.DoErrMsg(L"Expected '-' or ',' in dependency line");
       
   950 		throw ErrUnexpectedToken;
       
   951 		}
       
   952 
       
   953 
       
   954 	GetNextToken ();
       
   955 	ExpectToken('{');
       
   956 
       
   957 	iSISXWriter.AddDependency (uid, from, to);
       
   958 		// must do this before adding language strings
       
   959 
       
   960 	for (TUint16 numLangs = 0; numLangs < iSISXWriter.GetNoLanguages (); ++numLangs)
       
   961 		{
       
   962 		GetNextToken ();
       
   963 		ExpectToken(QUOTED_STRING_TOKEN);
       
   964 		iSISXWriter.AddDependencyName (iTokenValue.pszString);
       
   965 		GetNextToken ();
       
   966 		if (numLangs < (iSISXWriter.GetNoLanguages() - 1))
       
   967 			ExpectToken(',');
       
   968 		}
       
   969 	ExpectToken('}');
       
   970 	GetNextToken ();
       
   971 	}
       
   972 
       
   973 void CPackageParser::ParseTargetDeviceL()
       
   974 // Parses a target device line
       
   975 	{
       
   976 	iObserver.DoVerbage(L"processing target device");
       
   977 
       
   978 	if (! iIsHeaderDefined)
       
   979 		throw ErrHeaderNotDefined;
       
   980 
       
   981 	ExpectToken(NUMERIC_TOKEN);
       
   982 	CSISUid::TUid uid = iTokenValue.dwNumber;
       
   983 	GetNextToken ();
       
   984 
       
   985 	ExpectToken(']');
       
   986 	GetNextToken ();
       
   987 	ExpectToken(',');
       
   988 
       
   989 	TVersion from = ParseVersion();
       
   990 	TVersion to(-1,-1,-1);
       
   991 
       
   992 	if (iToken == '~')
       
   993 		{
       
   994 		to = ParseVersion();
       
   995 		ExpectToken(',');
       
   996 		}
       
   997 	else if (iToken == ',')
       
   998 		{
       
   999 		to = TVersion(KIrrelevant, KIrrelevant, KIrrelevant);
       
  1000 		}
       
  1001 	else
       
  1002 		{
       
  1003 		iObserver.DoErrMsg(L"Expected '-' or ',' in dependency line");
       
  1004 		throw ErrUnexpectedToken;
       
  1005 		}
       
  1006 
       
  1007 	GetNextToken ();
       
  1008 	ExpectToken('{');
       
  1009 
       
  1010 	iSISXWriter.AddTarget (uid, from, to);
       
  1011 		// must do this before adding language strings
       
  1012 
       
  1013 	for (TUint16 numLangs = 0; numLangs < iSISXWriter.GetNoLanguages (); ++numLangs)
       
  1014 		{
       
  1015 		GetNextToken ();
       
  1016 		ExpectToken(QUOTED_STRING_TOKEN);
       
  1017 		iSISXWriter.AddTargetName (iTokenValue.pszString);
       
  1018 		GetNextToken ();
       
  1019 		if (numLangs < (iSISXWriter.GetNoLanguages() - 1))
       
  1020 			ExpectToken(',');
       
  1021 		}
       
  1022 	ExpectToken('}');
       
  1023 	GetNextToken ();
       
  1024 	}
       
  1025 
       
  1026 void CPackageParser::ParseSignatureL()
       
  1027 {
       
  1028 	// Parses the package-signature
       
  1029 	iObserver.DoVerbage(L"processing signature");
       
  1030 
       
  1031 	// MAKESIS ignore the Signature,this option is deprecated.
       
  1032 	iObserver.DoMsg(L"Signature ignored,this option is deprecated...\n");
       
  1033 
       
  1034 	if (! iIsHeaderDefined)
       
  1035 		throw ErrHeaderNotDefined;
       
  1036 
       
  1037 	// If generating a stub file then once have signature line don't need to
       
  1038 	// process rest of PKG file
       
  1039 	iEnoughForStub=true;
       
  1040 
       
  1041 	ExpectToken(QUOTED_STRING_TOKEN);
       
  1042 
       
  1043 	GetNextToken ();
       
  1044 	ExpectToken(',');
       
  1045 	GetNextToken ();
       
  1046 
       
  1047 	ExpectToken(QUOTED_STRING_TOKEN);
       
  1048 	GetNextToken ();
       
  1049 
       
  1050 	//check for optional items (password)
       
  1051 	if (iToken==',')
       
  1052 		{
       
  1053 		GetNextToken ();
       
  1054 		if (iToken==KEY_TOKEN)
       
  1055 			{
       
  1056 			GetNextToken ();
       
  1057 			ExpectToken('=');
       
  1058 			GetNextToken ();
       
  1059 			ExpectToken(QUOTED_STRING_TOKEN);
       
  1060 			GetNextToken ();
       
  1061 			}
       
  1062 		}
       
  1063 
       
  1064 }
       
  1065 
       
  1066 
       
  1067 void CPackageParser::ParseVendorUniqueNameL()
       
  1068 {
       
  1069 	// Parses the package-signature
       
  1070 	iObserver.DoVerbage(L"processing unique vendor name");
       
  1071 
       
  1072 	ExpectToken(QUOTED_STRING_TOKEN);
       
  1073 	iSISXWriter.SetVendorUniqueName (iTokenValue.pszString);
       
  1074 	iUniqueVendorName = true;
       
  1075 	GetNextToken ();
       
  1076 }
       
  1077 
       
  1078 void CPackageParser::ParsePropertyL ()
       
  1079 // Parses a capability line
       
  1080 	{
       
  1081 	iObserver.DoVerbage(L"processing property");
       
  1082 
       
  1083 	CSISProperty::TKey key;
       
  1084 	CSISProperty::TValue value;
       
  1085 
       
  1086 	ExpectToken('(');
       
  1087 	do
       
  1088 		{
       
  1089 		GetNextToken ();
       
  1090 
       
  1091 		ExpectToken(NUMERIC_TOKEN);
       
  1092 		key = iTokenValue.dwNumber;
       
  1093 		GetNextToken ();
       
  1094 		ExpectToken('=');
       
  1095 		GetNextToken ();
       
  1096 		ExpectToken(NUMERIC_TOKEN);
       
  1097 		value = iTokenValue.dwNumber;
       
  1098 		iSISXWriter.AddProperty (key, value);
       
  1099 
       
  1100 		GetNextToken ();
       
  1101 		} while (iToken==',');
       
  1102 	ExpectToken(')');
       
  1103 	GetNextToken ();
       
  1104 	}
       
  1105 
       
  1106 void CPackageParser::ParseOptionsBlockL ()
       
  1107 // To parse an options block
       
  1108 	{
       
  1109 	WORD wNumLangs;
       
  1110 
       
  1111 	iObserver.DoVerbage(L"processing options block");
       
  1112 
       
  1113 	ExpectToken('(');
       
  1114 	GetNextToken ();
       
  1115 
       
  1116 	if (InterpretSis())
       
  1117 		{
       
  1118 		ReportInterpretSisError(ErrUserOptionsNotSupported);
       
  1119 		}
       
  1120 
       
  1121 	for (;;)
       
  1122 		{
       
  1123 		ExpectToken('{');
       
  1124 		GetNextToken ();
       
  1125 
       
  1126 		iSISXWriter.AddOption ();
       
  1127 
       
  1128 		wNumLangs = 0;
       
  1129 		while (wNumLangs < iSISXWriter.GetNoLanguages())
       
  1130 			{
       
  1131 			ExpectToken(QUOTED_STRING_TOKEN);
       
  1132 			iSISXWriter.AddOptionName (iTokenValue.pszString);
       
  1133 			GetNextToken ();
       
  1134 			if (wNumLangs < iSISXWriter.GetNoLanguages() - 1)
       
  1135 				{
       
  1136 				ExpectToken(',');
       
  1137 				GetNextToken ();
       
  1138 				}
       
  1139 			wNumLangs++;
       
  1140 			}
       
  1141 
       
  1142 		ExpectToken('}');
       
  1143 		GetNextToken ();
       
  1144 		if (iToken!=',') break;
       
  1145 		GetNextToken ();
       
  1146 		}
       
  1147 
       
  1148 	ExpectToken(')');
       
  1149 	GetNextToken ();
       
  1150 
       
  1151 	}
       
  1152 
       
  1153 void CPackageParser::ParseLanguageBlockL (CSISInstallBlock& aInstall)
       
  1154 // To parse the start of a language block
       
  1155 	{
       
  1156 	iObserver.DoVerbage(L"processing language block");
       
  1157 
       
  1158 	if (! iIsHeaderDefined)
       
  1159 		throw ErrHeaderNotDefined;
       
  1160 
       
  1161 	bool packages=(iToken=='@');
       
  1162 	unsigned languageCount = iSISXWriter.GetNoLanguages ();
       
  1163 	std::vector <unsigned> fileIndex (languageCount);
       
  1164 	std::vector <TUint64> fileSize (languageCount);
       
  1165 	std::vector <TUint64> compressedSize (languageCount);
       
  1166 	std::vector <CSISHash> hashes (languageCount);
       
  1167 
       
  1168 	for (DWORD iCurrentLang = 0; iCurrentLang < languageCount; iCurrentLang++)
       
  1169 		{
       
  1170 		if (iCurrentLang == 0)
       
  1171 			{
       
  1172 			aInstall.AddIf ();
       
  1173 			aInstall.If ().Expression ().SetLanguageComparision (iSISXWriter.Language (iCurrentLang));
       
  1174 			}
       
  1175 		else
       
  1176 			{
       
  1177 			aInstall.If ().AddElseIf ();
       
  1178 			aInstall.If ().ElseIf ().Expression ().SetLanguageComparision (iSISXWriter.Language (iCurrentLang));
       
  1179 		}
       
  1180 		if (packages)
       
  1181 			{
       
  1182 			ExpectToken ('@');
       
  1183 			GetNextToken ();
       
  1184 			if (iCurrentLang == 0)
       
  1185 				{
       
  1186 				iSISXWriter.EmbedPackage (aInstall.If ().InstallBlock (), iTokenValue.pszString, 0);
       
  1187 				}
       
  1188 			else
       
  1189 				{
       
  1190 				iSISXWriter.EmbedPackage (aInstall.If ().ElseIf ().InstallBlock (), iTokenValue.pszString, 0);
       
  1191 				}
       
  1192 			}
       
  1193 		else
       
  1194 			{
       
  1195 			CSISFileDescription fd;
       
  1196 			wchar_t *pBuffer = iTokenValue.pszString;
       
  1197             wchar_t *pCurrent = pBuffer;
       
  1198             while (pBuffer && *pBuffer && (pCurrent = wcschr(pBuffer,L'\\')) != NULL)
       
  1199 		    {
       
  1200       		*pCurrent = L'/';
       
  1201         	pBuffer = pCurrent + 1;
       
  1202 		    }
       
  1203 
       
  1204 			TUint32 index = Find(iTokenValue.pszString,fd);
       
  1205 			if ( index == -1 )
       
  1206 				{
       
  1207 				HANDLE  hFile = ::MakeSISOpenFile (iTokenValue.pszString, GENERIC_READ, OPEN_EXISTING);
       
  1208 				if (hFile == INVALID_HANDLE_VALUE)
       
  1209 				{
       
  1210 				// If we are using a search directory
       
  1211 			 	if(iSearchDir[0] != '\0')		
       
  1212 					{
       
  1213 					if (wcslen (iSearchDir) + wcslen (iTokenValue.pszString) < PATHMAX - 1)
       
  1214 						{
       
  1215 						WCHAR pszNewPath[PATHMAX];
       
  1216 						wcscpy(pszNewPath, iSearchDir);
       
  1217 						wcscat(pszNewPath, iTokenValue.pszString);
       
  1218 						HANDLE hFile = ::MakeSISOpenFile(pszNewPath, GENERIC_READ, OPEN_EXISTING);
       
  1219 						if (hFile != INVALID_HANDLE_VALUE) wcscpy(iTokenValue.pszString, pszNewPath);
       
  1220 						::CloseHandle(hFile);
       
  1221 						}
       
  1222 					}
       
  1223 				}
       
  1224 				::CloseHandle(hFile);
       
  1225 
       
  1226 				fileIndex [iCurrentLang] = iSISXWriter.LoadFile (iTokenValue.pszString, &fileSize [iCurrentLang]);
       
  1227 				compressedSize [iCurrentLang] = iSISXWriter.CompressedSize ();
       
  1228 
       
  1229 				fd.SetFileIndex(fileIndex[iCurrentLang]);
       
  1230 				fd.SetLengths (fileSize [iCurrentLang], compressedSize [iCurrentLang]);
       
  1231 				ComputeAndSetHash(fd);
       
  1232 
       
  1233 				hashes [iCurrentLang] = fd.Hash();
       
  1234 
       
  1235 				// Add new file to the map
       
  1236 				std::wstring newfile(iTokenValue.pszString);
       
  1237 				Set(newfile,fd);
       
  1238 				}
       
  1239 			else
       
  1240 				{
       
  1241 				fileIndex [iCurrentLang] = fd.FileIndex();
       
  1242 				fileSize [iCurrentLang] = fd.UncompressedLength();
       
  1243 				compressedSize [iCurrentLang] = fd.Length();
       
  1244 				hashes [iCurrentLang] = fd.Hash();
       
  1245 				}
       
  1246 			}
       
  1247 		GetNextToken ();
       
  1248 		}
       
  1249 
       
  1250 	ExpectToken('}');
       
  1251 	GetNextToken ();
       
  1252 
       
  1253 	if(!packages)
       
  1254 		{
       
  1255 		ExpectToken('-');
       
  1256 		GetNextToken ();
       
  1257 
       
  1258 		// Get the destination & options
       
  1259 		ExpectToken(QUOTED_STRING_TOKEN);
       
  1260 		CSISFileDescription file;
       
  1261 		file.SetTarget (iTokenValue.pszString);
       
  1262 
       
  1263 		GetNextToken ();
       
  1264 
       
  1265 		if (iToken==',')
       
  1266 			{
       
  1267 			GetNextToken ();
       
  1268 			CSISFileDescription::TSISInstOption type = file.InterpretOption (iTokenValue.pszString);
       
  1269 			GetNextToken();
       
  1270 			if (type == CSISFileDescription::EInstFileRunOptionByMimeType)
       
  1271 				{
       
  1272 				ExpectToken(',');
       
  1273 				GetNextToken ();
       
  1274 				ExpectToken(QUOTED_STRING_TOKEN);
       
  1275 				file.SetMimeType (iTokenValue.pszString);
       
  1276 				GetNextToken ();
       
  1277 				}
       
  1278 			else
       
  1279 			if (iToken==',')
       
  1280 				{
       
  1281 				do
       
  1282 					{
       
  1283 
       
  1284 					GetNextToken ();
       
  1285 					file.InterpretOption (iTokenValue.pszString);
       
  1286 					GetNextToken ();
       
  1287 
       
  1288 					} while (iToken == ',');
       
  1289 
       
  1290 				}
       
  1291 			}
       
  1292 
       
  1293 		for (unsigned index = 0; index < languageCount; index++)
       
  1294 			{
       
  1295 			if (index == 0)
       
  1296 				{
       
  1297 				aInstall.If ().InstallBlock ().AddFileDescription (file);
       
  1298 				aInstall.If ().InstallBlock ().SetFileIndex (fileIndex [index]);
       
  1299 				aInstall.If ().InstallBlock ().SetLengths (fileSize [index], compressedSize [index]);
       
  1300 				aInstall.If ().InstallBlock ().SetHash (hashes[index]);
       
  1301 				}
       
  1302 			else
       
  1303 				{
       
  1304 				aInstall.If ().ElseIf (index - 1).InstallBlock ().AddFileDescription (file);
       
  1305 				aInstall.If ().ElseIf (index - 1).InstallBlock ().SetFileIndex (fileIndex [index]);
       
  1306 				aInstall.If ().ElseIf (index - 1).InstallBlock ().SetLengths (fileSize [index], compressedSize [index]);
       
  1307 				aInstall.If ().ElseIf (index - 1).InstallBlock ().SetHash (hashes[index]);
       
  1308 				}
       
  1309 			}
       
  1310 		}
       
  1311 	else
       
  1312 		{
       
  1313 		ExpectToken(',');
       
  1314 		GetNextToken ();
       
  1315 		ExpectToken('(');
       
  1316 		GetNextToken ();
       
  1317 
       
  1318 		ExpectToken(NUMERIC_TOKEN);
       
  1319 		GetNextToken ();
       
  1320 
       
  1321 		ExpectToken(')');
       
  1322 		GetNextToken ();
       
  1323 
       
  1324 		}
       
  1325 	}
       
  1326 
       
  1327 void CPackageParser::ParseIfBlockL (CSISInstallBlock& aInstall)
       
  1328 	{
       
  1329 	iObserver.DoVerbage(L"processing IF block");
       
  1330 
       
  1331 	aInstall.AddIf ();
       
  1332 
       
  1333 	ParseLogicalOp (aInstall.If ().Expression ());
       
  1334 	ParseEmbeddedBlockL (aInstall.If ().InstallBlock ());
       
  1335 
       
  1336 	while (iToken==ELSEIF_TOKEN)
       
  1337 		{
       
  1338 		GetNextToken ();
       
  1339 		aInstall.If ().AddElseIf ();
       
  1340 		ParseLogicalOp (aInstall.If ().ElseIfExpression ());
       
  1341 		ParseEmbeddedBlockL (aInstall.If ().ElseIf ().InstallBlock ());
       
  1342 		}
       
  1343 
       
  1344 	if (iToken==ELSE_TOKEN)
       
  1345 		{
       
  1346 		GetNextToken ();
       
  1347 		aInstall.If ().AddElse ();
       
  1348 		// elseif true
       
  1349 		ParseEmbeddedBlockL(aInstall.If ().ElseIf ().InstallBlock ());
       
  1350 		}
       
  1351 
       
  1352 	ExpectToken(ENDIF_TOKEN);
       
  1353 	GetNextToken ();
       
  1354 	}
       
  1355 
       
  1356 void CPackageParser::ParseCommentL()
       
  1357 // Purpose  : Parses a comment line (Does nothing, just throws the line away)
       
  1358 // Inputs   : m_pkgPtr - The string to parse
       
  1359 // Returns  : Success or failure
       
  1360 	{
       
  1361 	iObserver.DoVerbage(L"processing comment");
       
  1362 
       
  1363 	// parse to end of line
       
  1364 	while (iPkgChar && (iPkgChar!='\n')) GetNextChar();
       
  1365 	GetNextToken ();
       
  1366 	}
       
  1367 
       
  1368 void CPackageParser::ParseLogicalOp (CSISExpression& aExpression)
       
  1369 	{
       
  1370 	CSISExpression left;
       
  1371 
       
  1372 	if (InterpretSis())
       
  1373 		{
       
  1374 		std::wstring aOption = iTokenValue.pszString;
       
  1375 		for(size_t i = 0; i < aOption.length(); ++i)
       
  1376 			aOption.at(i) = towupper(aOption.at(i));
       
  1377 
       
  1378 		if (aOption.find(L"OPTION",0) != std::string::npos)
       
  1379 			{
       
  1380 			ReportInterpretSisError(ErrUserOptionsNotSupported);
       
  1381 			}
       
  1382 		}
       
  1383 
       
  1384     ParseRelation (left);
       
  1385 	switch (iToken)
       
  1386 		{
       
  1387 		case AND_TOKEN:
       
  1388 		case OR_TOKEN:
       
  1389 			{
       
  1390 			if (iToken==AND_TOKEN)
       
  1391 				aExpression.SetOperator (CSISExpression::ELogOpAnd, left);
       
  1392 			else
       
  1393 				aExpression.SetOperator (CSISExpression::ELogOpOr, left);
       
  1394 			GetNextToken ();
       
  1395 			ParseLogicalOp (aExpression.RHS ());
       
  1396 			}
       
  1397 			break;
       
  1398 		default:
       
  1399 			aExpression = left;
       
  1400 			break;
       
  1401 		}
       
  1402 	}
       
  1403 
       
  1404 
       
  1405 void CPackageParser::ParseRelation(CSISExpression& aExpression)
       
  1406 	{
       
  1407 	CSISExpression left;
       
  1408     ParseUnary (left);
       
  1409 	switch (iToken)
       
  1410 		{
       
  1411 		case '=':
       
  1412 		case '>':
       
  1413 		case '<':
       
  1414 		case GE_TOKEN:
       
  1415 		case LE_TOKEN:
       
  1416 		case NE_TOKEN:
       
  1417 			{
       
  1418 			switch (iToken)
       
  1419 				{
       
  1420 				case '=':
       
  1421 					aExpression.SetOperator (CSISExpression::EBinOpEqual, left);
       
  1422 					break;
       
  1423 				case '>':
       
  1424 					aExpression.SetOperator (CSISExpression::EBinOpGreaterThan, left);
       
  1425 					break;
       
  1426 				case '<':
       
  1427 					aExpression.SetOperator (CSISExpression::EBinOpLessThan, left);
       
  1428 					break;
       
  1429 				case GE_TOKEN:
       
  1430 					aExpression.SetOperator (CSISExpression::EBinOpGreaterThanOrEqual, left);
       
  1431 					break;
       
  1432 				case LE_TOKEN:
       
  1433 					aExpression.SetOperator (CSISExpression::EBinOpLessThanOrEqual, left);
       
  1434 					break;
       
  1435 				case NE_TOKEN:
       
  1436 					aExpression.SetOperator (CSISExpression::EBinOpNotEqual, left);
       
  1437 					break;
       
  1438 				}
       
  1439 			GetNextToken ();
       
  1440 			ParseUnary (aExpression.RHS ());
       
  1441 			break;
       
  1442 			}
       
  1443 		default:
       
  1444 			aExpression = left;
       
  1445 			break;
       
  1446 		}
       
  1447 	}
       
  1448 
       
  1449 void CPackageParser::ParseUnary(CSISExpression& aExpression)
       
  1450 	{
       
  1451     switch (iToken)
       
  1452 		{
       
  1453 		case NOT_TOKEN:
       
  1454 			aExpression.SetOperator (CSISExpression::EUnaryOpNot);
       
  1455 			GetNextToken ();
       
  1456 			ParseUnary (aExpression.RHS ());
       
  1457 			break;
       
  1458 		case APPCAP_TOKEN:
       
  1459 			{	// 2 arg function
       
  1460 			GetNextToken ();
       
  1461 			ExpectToken('(');
       
  1462 
       
  1463 			aExpression.SetOperator (CSISExpression::EFuncAppProperties);
       
  1464 			GetNextToken ();
       
  1465 			ParseUnary (aExpression.LHS ());
       
  1466 			ExpectToken(',');
       
  1467 			GetNextToken ();
       
  1468 			ParseUnary (aExpression.RHS ());
       
  1469 //			GetNextToken ();
       
  1470 
       
  1471 			ExpectToken(')');
       
  1472 			GetNextToken ();
       
  1473 			break;
       
  1474 			}
       
  1475 		case EXISTS_TOKEN:
       
  1476 		case DEVCAP_TOKEN:
       
  1477 			{	// 1 arg function
       
  1478 			TOKEN token=iToken;
       
  1479 			GetNextToken ();
       
  1480 			ExpectToken('(');
       
  1481 			GetNextToken ();
       
  1482 			if (token==EXISTS_TOKEN)
       
  1483 				{
       
  1484 				aExpression.SetOperator (CSISExpression::EFuncExists);
       
  1485 				ExpectToken(QUOTED_STRING_TOKEN);
       
  1486 				GetNextToken ();
       
  1487 				aExpression.SetValue (std::wstring (iTokenValue.pszString));
       
  1488 				}
       
  1489 			else
       
  1490 				{
       
  1491 				aExpression.SetOperator (CSISExpression::EFuncDevProperties);
       
  1492 				ParseUnary (aExpression.RHS ());
       
  1493 				}
       
  1494 			ExpectToken(')');
       
  1495 			GetNextToken ();
       
  1496 			break;
       
  1497 			}
       
  1498 		case VERSION_TOKEN:
       
  1499 			{
       
  1500 			/**
       
  1501 			CR1125 - VERSION() function to allow for the evaluation of installed package versions
       
  1502 
       
  1503 			The functions arguments are parsed and formatted into an argument string within 
       
  1504 			CPackageParser::ParseVersionArgs(). The SISString is then stored within the SISExpression
       
  1505 			using the CSISExpression::EFuncExists TOperator enumeration for compatibility with old
       
  1506 			versions of the SWI Server.
       
  1507 			**/  
       
  1508 			GetNextToken ();
       
  1509 			ExpectToken('(');
       
  1510 
       
  1511 			aExpression.SetOperator (CSISExpression::EFuncExists);
       
  1512 			GetNextToken ();
       
  1513 			aExpression.SetValue (ParseVersionArgs());
       
  1514 
       
  1515 			ExpectToken(')');
       
  1516 			GetNextToken ();
       
  1517 			break;
       
  1518 			}
       
  1519 			
       
  1520 		// Block to handle Supported_Language token used in package file
       
  1521 		// This block sets the SISExpression with the corresponding fields
       
  1522 		// like Operator = EFuncExists, Value = "/sys/install/supported_language/?10" 
       
  1523 		// (language ID for the example given below), 
       
  1524 		// Eg:supported_language = 10
       
  1525 		case SUPPORTED_LANG_TOKEN:
       
  1526 			{
       
  1527 			GetNextToken();
       
  1528 			ExpectToken('=');
       
  1529 			
       
  1530 			aExpression.SetOperator (CSISExpression::EFuncExists);
       
  1531 			GetNextToken ();
       
  1532 			aExpression.SetValue (ParseSupportedLangArgs());
       
  1533 			break;
       
  1534 			}
       
  1535 
       
  1536 			
       
  1537 		default:
       
  1538 			ParseFactor (aExpression);
       
  1539 			break;
       
  1540 		}
       
  1541 	}
       
  1542 
       
  1543 void CPackageParser::ParseFactor(CSISExpression& aExpression)
       
  1544 	{
       
  1545     switch (iToken) {
       
  1546 		case '(':
       
  1547 			{
       
  1548 			GetNextToken ();
       
  1549 			ParseLogicalOp (aExpression);
       
  1550 			ExpectToken(')');
       
  1551 			}
       
  1552 			break;
       
  1553 		case QUOTED_STRING_TOKEN:
       
  1554 		case ALPHA_TOKEN:
       
  1555 		case NUMERIC_TOKEN:
       
  1556 			{
       
  1557 			switch (iToken)
       
  1558 				{
       
  1559 				case QUOTED_STRING_TOKEN:
       
  1560 					aExpression.SetOperator (CSISExpression::EPrimTypeString);
       
  1561 					aExpression.SetValue (std::wstring (iTokenValue.pszString));
       
  1562 					break;
       
  1563 				case ALPHA_TOKEN:
       
  1564 					{
       
  1565 					if(!CompareNString(iTokenValue.pszString,L"option",6))
       
  1566 						{
       
  1567 						WCHAR *temp,*end;
       
  1568 						temp=&iTokenValue.pszString[6];
       
  1569 						DWORD optionNum = wcstol(temp, &end, 10);
       
  1570 						if (end==temp || errno==ERANGE)
       
  1571 							throw ErrUnknownVariable;
       
  1572 						aExpression.SetOperator (CSISExpression::EPrimTypeOption);
       
  1573 						aExpression.SetValue (optionNum);
       
  1574 						}
       
  1575 					else
       
  1576 						{
       
  1577 						aExpression.SetVariable (std::wstring (iTokenValue.pszString));
       
  1578 						}
       
  1579 					}
       
  1580 					break;
       
  1581 				case NUMERIC_TOKEN:
       
  1582 					aExpression.SetOperator (CSISExpression::EPrimTypeNumber);
       
  1583 					aExpression.SetValue (iTokenValue.dwNumber);
       
  1584 					break;
       
  1585 				}
       
  1586 			}
       
  1587 			break;
       
  1588 		default:
       
  1589 			throw ErrBadCondFormat;
       
  1590 		}
       
  1591 	GetNextToken ();
       
  1592 	}
       
  1593 
       
  1594 // Additional Functionality Provided By CR1125
       
  1595 std::wstring CPackageParser::ParseVersionArgs()
       
  1596 	{
       
  1597 	std::wstring agrsString;
       
  1598 	TInt32 vMaj = 0;
       
  1599 	TInt32 vMin = 0;
       
  1600 	TInt32 vBld = 0;
       
  1601 	wchar_t* relation;
       
  1602 	TVersion version;
       
  1603 
       
  1604 	ExpectToken(NUMERIC_TOKEN);
       
  1605 	CSISUid::TUid pUid = iTokenValue.dwNumber;
       
  1606 	GetNextToken ();
       
  1607 
       
  1608 	ExpectToken(',');
       
  1609 	GetNextToken ();
       
  1610 
       
  1611 	switch (iToken)
       
  1612 		{
       
  1613 		case '=':
       
  1614 			relation = L"ET";
       
  1615 			break;
       
  1616 		case '>':
       
  1617 			relation = L"GT";
       
  1618 			break;
       
  1619 		case '<':
       
  1620 			relation = L"LT";
       
  1621 			break;
       
  1622 		case GE_TOKEN:
       
  1623 			relation = L"GE";
       
  1624 			break;
       
  1625 		case LE_TOKEN:
       
  1626 			relation = L"LE";
       
  1627 			break;
       
  1628 		case NE_TOKEN:
       
  1629 			relation = L"NE";
       
  1630 			break;
       
  1631 		default:
       
  1632 			throw ErrVersionInvalidRelationalOperator;
       
  1633 		}
       
  1634 
       
  1635 	GetNextToken ();
       
  1636 	ExpectToken(',');
       
  1637 
       
  1638 	version = ParseVersion();
       
  1639 
       
  1640 	vMaj = version.Major();
       
  1641 	vMin = version.Minor();
       
  1642 	vBld = version.Build();
       
  1643 
       
  1644 	
       
  1645 	if(vMaj == -1 || vMin == -1 || vBld == -1)
       
  1646 		{
       
  1647 		// If a wildcard has been specified, throw a bad condition
       
  1648 		throw ErrVersionWildcardsNotSupported;
       
  1649 		}
       
  1650 	else if(vMaj < 0 || vMin < 0 || vBld < 0)
       
  1651 		{
       
  1652 		// If a negative version component has been specified, throw a bad condition
       
  1653 		throw ErrVersionNegativesNotSupported; 
       
  1654 		}
       
  1655 
       
  1656 	// Integer to String Conversions
       
  1657 	std::wstring pUidStr;
       
  1658 	pUidStr = ConvertToString(pUid,std::hex);	 
       
  1659 
       
  1660 	std::wstring vMajStr;
       
  1661 	vMajStr = ConvertToString(vMaj,std::dec);
       
  1662 
       
  1663 	std::wstring vMinStr;
       
  1664 	vMinStr = ConvertToString(vMin,std::dec);
       
  1665 
       
  1666 	std::wstring vBldStr;
       
  1667 	vBldStr = ConvertToString(vBld,std::dec);
       
  1668 
       
  1669 	// Construct the formatted argument string
       
  1670 	agrsString = L"\\sys\\install\\pkgversion\\?";
       
  1671 	agrsString += L"0x";
       
  1672 	agrsString += pUidStr;
       
  1673 	agrsString += L",";
       
  1674 	agrsString += relation;
       
  1675 	agrsString += L",";
       
  1676 	agrsString += vMajStr;
       
  1677 	agrsString += L",";
       
  1678 	agrsString += vMinStr;
       
  1679 	agrsString += L",";
       
  1680 	agrsString += vBldStr;
       
  1681 
       
  1682 	return agrsString;
       
  1683 	}
       
  1684 
       
  1685 // Function added to parse the supported language token(suppoted_language) and 
       
  1686 // provide the appropriate value string, which is set onto SISExpression.
       
  1687 // It returns a string like "\sys\install\supported_langauge\?01" if the parsed 
       
  1688 // token is like "(((01)))"
       
  1689 std::wstring CPackageParser::ParseSupportedLangArgs()
       
  1690 	{
       
  1691 	std::wstring argsString;
       
  1692 	TInt32 langId = 0;
       
  1693 	TInt32 parenthesisCount = 0;
       
  1694 	while ( iToken == '(' )
       
  1695 		{
       
  1696 		GetNextToken();
       
  1697 		parenthesisCount++;
       
  1698 		}
       
  1699 	
       
  1700 	ExpectToken(NUMERIC_TOKEN);
       
  1701 
       
  1702 	langId = iTokenValue.dwNumber;
       
  1703 	GetNextToken ();
       
  1704 	while ( iToken == ')' && parenthesisCount)
       
  1705 			{
       
  1706 			GetNextToken();
       
  1707 			parenthesisCount--;
       
  1708 			}
       
  1709 	if (!(0 == parenthesisCount))
       
  1710 		{
       
  1711 		throw ErrUnBalancedParenthesis;
       
  1712 		}
       
  1713 	std::wstring vLangIdStr;
       
  1714 	vLangIdStr = ConvertToString(langId,std::dec);
       
  1715 
       
  1716 	// Construct the formatted argument string
       
  1717 	argsString = L"\\sys\\install\\supportedlanguage\\?";
       
  1718 	argsString += vLangIdStr;
       
  1719 
       
  1720 	return argsString;
       
  1721 	}
       
  1722 
       
  1723 
       
  1724 std::wstring CPackageParser::ConvertToString(const TInt32 aValue, std::ios_base& (*aBase)(std::ios_base&))
       
  1725 	{
       
  1726 	std::wostringstream wOutStream;
       
  1727 
       
  1728 	if((wOutStream << aBase << aValue).fail())
       
  1729 		{
       
  1730 		throw ErrBadIntegerToStringConversion;
       
  1731 		};
       
  1732 
       
  1733 	return wOutStream.str();
       
  1734 	}
       
  1735 
       
  1736 DWORD CPackageParser::ParseOption(const SParseOpt* options, DWORD dwNumOptions, DWORD* pdwOptions)
       
  1737 // Parse the options part of an input line
       
  1738 	{
       
  1739 	DWORD option=0;
       
  1740 	ExpectToken(ALPHA_TOKEN);
       
  1741 	// Look for the option
       
  1742 	for(WORD wLoop = 0; wLoop < dwNumOptions; wLoop++)
       
  1743 		{
       
  1744 		if(CompareTwoString(iTokenValue.pszString,(wchar_t*) options[wLoop].pszOpt) == 0)
       
  1745 			{
       
  1746 			option=options[wLoop].dwOpt;
       
  1747 			break;
       
  1748 			}
       
  1749 		}
       
  1750 	if(wLoop == dwNumOptions)
       
  1751 		throw ErrBadOption;
       
  1752 	*pdwOptions |= option;
       
  1753 	GetNextToken ();
       
  1754 	return option;
       
  1755 	}
       
  1756 
       
  1757 void CPackageParser::ExpectToken(TOKEN aToken)
       
  1758 	{
       
  1759 	if (iToken!=aToken)
       
  1760 		{
       
  1761 		wchar_t msg[255]=L"Expected ";
       
  1762 		if (aToken<=LAST_TOKEN)
       
  1763 			wcsncat(msg,GetTokenText(aToken),wcslen(GetTokenText(aToken)));
       
  1764 		else
       
  1765 			{
       
  1766 			wchar_t tmp[2]={(wchar_t)aToken,0};
       
  1767 			wcsncat(msg,tmp,wcslen(tmp));
       
  1768 			}
       
  1769 		wcsncat(msg,L" read ",wcslen(L" read "));
       
  1770 		if (iToken<=LAST_TOKEN)
       
  1771 			wcsncat(msg,GetTokenText(iToken), wcslen(GetTokenText(iToken)));
       
  1772 		else
       
  1773 			{
       
  1774 			wchar_t tmp[2]={(wchar_t)iToken,0};
       
  1775 			wcsncat(msg,tmp,wcslen(tmp));
       
  1776 			}
       
  1777 		iObserver.DoErrMsg(msg);
       
  1778 		throw ErrUnexpectedToken;
       
  1779 		}
       
  1780 	}
       
  1781 
       
  1782 const _TCHAR* CPackageParser::GetTokenText(TOKEN aToken)
       
  1783 	{
       
  1784 	switch(aToken)
       
  1785 		{
       
  1786 		case NUMERIC_TOKEN:
       
  1787 			return L"numeric value";
       
  1788 		case ALPHA_TOKEN:
       
  1789 			return L"alphanumeric value";
       
  1790 		case QUOTED_STRING_TOKEN:
       
  1791 			return L"quoted string";
       
  1792 		case AND_TOKEN:
       
  1793 			return L"AND";
       
  1794 		case OR_TOKEN:
       
  1795 			return L"OR";
       
  1796 		case NOT_TOKEN:
       
  1797 			return L"NOT";
       
  1798 		case EXISTS_TOKEN:
       
  1799 			return L"EXISTS";
       
  1800 		case GE_TOKEN:
       
  1801 			return L">=";
       
  1802 		case LE_TOKEN:
       
  1803 			return L"<=";
       
  1804 		case NE_TOKEN:
       
  1805 			return L"<>";
       
  1806 		case IF_TOKEN:
       
  1807 			return L"IF";
       
  1808 		case ELSEIF_TOKEN:
       
  1809 			return L"ELSEIF";
       
  1810 		case ELSE_TOKEN:
       
  1811 			return L"ELSE";
       
  1812 		case ENDIF_TOKEN:
       
  1813 			return L"ENDIF";
       
  1814 		default:
       
  1815 			return L"?";
       
  1816 		}
       
  1817 	}
       
  1818 
       
  1819 void CPackageParser::GetNextToken (const TBool aDisablePkgKeywordCheck)
       
  1820 // lexical analyzer
       
  1821 	{
       
  1822 	// skip any white space & newLine's
       
  1823 	while (iPkgChar == '\n' || isspace(iPkgChar) || iPkgChar == 0xA0)
       
  1824 		{
       
  1825 		if (iPkgChar == '\n')
       
  1826 			{
       
  1827 			iObserver.SetLineNumber(++iLineNo);
       
  1828 			}
       
  1829 		GetNextChar();
       
  1830 		}
       
  1831 
       
  1832 	if (iPkgChar == '\0')
       
  1833 		iToken=EOF_TOKEN;
       
  1834 	else if (IsNumericToken())
       
  1835 		{
       
  1836 		GetNumericToken();
       
  1837 		iToken=NUMERIC_TOKEN;
       
  1838 		}
       
  1839 	else if (isalpha(iPkgChar))
       
  1840 		{ // have some alphanumeric text
       
  1841 		GetAlphaNumericToken();
       
  1842 		iToken=ALPHA_TOKEN;
       
  1843 		// check if it is a PKG keyword only when the keyword check is not 
       
  1844  		// disabled by setting the paramter "aDisablePkgKeywordCheck"
       
  1845 		if (!aDisablePkgKeywordCheck)
       
  1846 			{
       
  1847 			for(WORD wLoop = 0; wLoop < NUMPARSETOKENS; wLoop++)
       
  1848 				{
       
  1849 				if(CompareTwoString(iTokenValue.pszString, (wchar_t*)KTokens[wLoop].pszOpt) == 0)
       
  1850 					{
       
  1851 					iToken=KTokens[wLoop].dwOpt;
       
  1852 					break;
       
  1853 					}
       
  1854 				}
       
  1855 			}
       
  1856 		}
       
  1857 	else if (iPkgChar == '\"')
       
  1858 		{ // have a quoted string
       
  1859 		GetStringToken();
       
  1860 		iToken=QUOTED_STRING_TOKEN;
       
  1861 		}
       
  1862 	else if (iPkgChar == '>')
       
  1863 		{
       
  1864 		GetNextChar();
       
  1865 		if (iPkgChar == '=')
       
  1866 			{
       
  1867 			iToken=GE_TOKEN;
       
  1868 			GetNextChar();
       
  1869 			}
       
  1870 		else
       
  1871 			iToken='>';
       
  1872 		}
       
  1873 	else if (iPkgChar == '<')
       
  1874 		{
       
  1875 		// check if start of an escaped string, e.g. <123>"abc"
       
  1876 		if (GetStringToken())
       
  1877 			iToken=QUOTED_STRING_TOKEN;
       
  1878 		else
       
  1879 			{
       
  1880 			GetNextChar();
       
  1881 			if (iPkgChar == '=')
       
  1882 				{
       
  1883 				iToken=LE_TOKEN;
       
  1884 				GetNextChar();
       
  1885 				}
       
  1886 			else if (iPkgChar == '>')
       
  1887 				{
       
  1888 				iToken=NE_TOKEN;
       
  1889 				GetNextChar();
       
  1890 				}
       
  1891 			else
       
  1892 				iToken='<';
       
  1893 			}
       
  1894 		}
       
  1895 	else
       
  1896 		{
       
  1897 		iToken = iPkgChar;
       
  1898 		GetNextChar();
       
  1899 		}
       
  1900 	}
       
  1901 
       
  1902 bool CPackageParser::GetStringToken()
       
  1903 // Purpose  : Parse a quoted string from the input line
       
  1904 // Inputs   : m_pkgPtr    - The string to parse
       
  1905 //			  pszString   - The output string
       
  1906 //            wMaxLength  - The max length of pszString
       
  1907 	{
       
  1908 	DWORD wCount = 0;
       
  1909 	bool done=false;
       
  1910 	bool finished=false;
       
  1911 	DWORD escapeChars = 0;
       
  1912 
       
  1913 	while (!finished)
       
  1914 		{
       
  1915 		if (iPkgChar == '\"')
       
  1916 			{
       
  1917 			GetNextChar();
       
  1918 			while(iPkgChar && iPkgChar != '\"')
       
  1919 				{
       
  1920 				if(wCount < (MAX_STRING - 1))
       
  1921 					iTokenValue.pszString[wCount++] = iPkgChar;
       
  1922 				else //We dont want the string with length greater than MAX_STRING to be cut off silently
       
  1923 					throw ErrBadString;
       
  1924 				GetNextChar();
       
  1925 				}
       
  1926 			if(iPkgChar == '\0')
       
  1927 				throw ErrBadString;
       
  1928 			GetNextChar();
       
  1929 			done=true;
       
  1930 			}
       
  1931 		if (iPkgChar == '<')
       
  1932 			{
       
  1933 			iTokenValue.pszString[wCount] = L'\0';
       
  1934 			escapeChars=ParseEscapeChars();
       
  1935 			if (escapeChars>0)
       
  1936 				{
       
  1937 				done=true;
       
  1938 				wCount+=escapeChars;
       
  1939 				if (wCount>=MAX_STRING) wCount=MAX_STRING-1;
       
  1940 				}
       
  1941 			}
       
  1942 		if (escapeChars==0 || iPkgChar != '\"')
       
  1943 			finished=true;
       
  1944 		}
       
  1945 
       
  1946 	iTokenValue.pszString[wCount] = L'\0';
       
  1947 	return done;
       
  1948 	}
       
  1949 
       
  1950 WORD CPackageParser::ParseEscapeChars()
       
  1951 	{
       
  1952 	WORD found=0;
       
  1953 	WCHAR temp[MAX_STRING];
       
  1954 	while (iPkgChar == '<')
       
  1955 		{
       
  1956 		wcscpy(temp,iTokenValue.pszString);
       
  1957 		DWORD fileOffset=::SetFilePointer(iFileHandle, 0L, NULL, FILE_CURRENT);
       
  1958 		try
       
  1959 			{
       
  1960 			GetNextChar();
       
  1961 			GetNumericToken();
       
  1962 			if (iPkgChar=='>')
       
  1963 				found++;
       
  1964 			else
       
  1965 				{
       
  1966 				::SetFilePointer(iFileHandle, fileOffset, NULL, FILE_BEGIN);
       
  1967 				break;
       
  1968 				}
       
  1969 			}
       
  1970 		catch (TParseException)
       
  1971 			{
       
  1972 			wcscpy(iTokenValue.pszString,temp);
       
  1973 			::SetFilePointer(iFileHandle, fileOffset, NULL, FILE_BEGIN);
       
  1974 			break;
       
  1975 			}
       
  1976 		DWORD num=iTokenValue.dwNumber;
       
  1977 		// watch for CP1252 escapes which aren't appropriate for UNICODE
       
  1978 		if (num>=0x80 && num<=0x9F) throw ErrInvalidEscape;
       
  1979 		DWORD len=wcslen(temp);
       
  1980 		wcscpy(iTokenValue.pszString,temp);
       
  1981 		if (len+2<=MAX_STRING)
       
  1982 			{
       
  1983 			iTokenValue.pszString[len]=(WCHAR)num;
       
  1984 			len++;
       
  1985 			iTokenValue.pszString[len]='\0';
       
  1986 			}
       
  1987 		GetNextChar();
       
  1988 		}
       
  1989 	return found;
       
  1990 	}
       
  1991 
       
  1992 void CPackageParser::GetAlphaNumericToken()
       
  1993 // Purpose  : Parse an alphanumeric string from the input line
       
  1994 // Inputs   : m_pkgPtr    - The string to parse
       
  1995 //			  pszString   - The output string
       
  1996 //            wMaxLength  - The max length of pszString
       
  1997 	{
       
  1998 	WORD wCount = 0;
       
  1999 	while(iPkgChar && (isalnum(iPkgChar) || ((iPkgChar) == '_')))
       
  2000 		{
       
  2001 		if(wCount < (MAX_STRING - 1))
       
  2002 			iTokenValue.pszString[wCount++] = iPkgChar;
       
  2003 		GetNextChar();
       
  2004 		}
       
  2005 	iTokenValue.pszString[wCount] = L'\0';
       
  2006 	}
       
  2007 
       
  2008 bool CPackageParser::IsNumericToken()
       
  2009 // Purpose : Determines if the next lexeme is a numeric token
       
  2010 	{
       
  2011 	bool lexemeIsNumber = false;
       
  2012 	if (iswdigit(iPkgChar))
       
  2013 		lexemeIsNumber = true;
       
  2014 	else if (iPkgChar == '+' || iPkgChar == '-')
       
  2015 		{
       
  2016 		// we may have a number but we must look ahead one char to be certain
       
  2017 
       
  2018 		WCHAR oldChar = iPkgChar;
       
  2019 		DWORD fileOffset=::SetFilePointer(iFileHandle, 0L, NULL, FILE_CURRENT);
       
  2020 		GetNextChar();
       
  2021 		lexemeIsNumber = iswdigit(iPkgChar) != FALSE;
       
  2022 		iPkgChar = oldChar;
       
  2023 		::SetFilePointer(iFileHandle,fileOffset,NULL,FILE_BEGIN);
       
  2024 		}
       
  2025 
       
  2026 	return lexemeIsNumber;
       
  2027 	}
       
  2028 
       
  2029 
       
  2030 void CPackageParser::GetNumericToken()
       
  2031 // Purpose  : Parse a number from the input line
       
  2032 // Inputs   : m_pkgPtr    - The string to parse
       
  2033 //			  pdwNumber  - The output number
       
  2034 	{
       
  2035 	WCHAR temp[MAX_STRING];
       
  2036 	LPWSTR end;
       
  2037 	bool hexString = false;
       
  2038 	DWORD dwBytesRead;
       
  2039 	DWORD fileOffset=::SetFilePointer(iFileHandle, 0L, NULL, FILE_CURRENT);
       
  2040 
       
  2041 	temp[0]=iPkgChar;
       
  2042 	if (!::ReadFile(iFileHandle, &temp[1], (MAX_STRING-2)*sizeof(WCHAR), &dwBytesRead, NULL) ||
       
  2043 		dwBytesRead==0)
       
  2044 		throw ErrReadFailed;
       
  2045 	temp[1+dwBytesRead/sizeof(WCHAR)]='\0';
       
  2046 	hexString = (!CompareNString(temp, L"0x", 2) || !CompareNString(&temp[1], L"0x", 2));
       
  2047 
       
  2048 	iTokenValue.dwNumber = wcstoul(temp, &end, (hexString) ? 16 : 10);
       
  2049 
       
  2050 	if (end==temp) throw ErrReadFailed;
       
  2051 	if (errno==ERANGE)
       
  2052 		throw ErrNumberOutOfRange;
       
  2053 	::SetFilePointer(iFileHandle, fileOffset+(end-temp-1)*sizeof(WCHAR), NULL, FILE_BEGIN);
       
  2054 	GetNextChar();
       
  2055 	}
       
  2056 
       
  2057 void CPackageParser::GetNextChar()
       
  2058 	{
       
  2059 	DWORD dwBytesRead;
       
  2060 	if (!::ReadFile(iFileHandle, (LPVOID)&iPkgChar, sizeof(WCHAR), &dwBytesRead, NULL) ||
       
  2061 		dwBytesRead!=sizeof(WCHAR))
       
  2062 		iPkgChar='\0';
       
  2063 	}
       
  2064 
       
  2065 void CPackageParser::ValidateVersion(TInt32& major, TInt32 &minor, TInt32 &build)
       
  2066 	{
       
  2067 	if((major > 127) || (minor > 99) || (build > 32767))
       
  2068 		{
       
  2069 		iObserver.DoMsg(L"Warning : The valid version number ranges are : (Major: 0..127) (Minor: 0..99 ) (Build: 0..32,767).");
       
  2070 		}
       
  2071 	}
       
  2072 
       
  2073 bool CPackageParser::DoesExist(LPWSTR pszFile, DWORD *pdwSize)
       
  2074 // Purpose  : Attempt to determine whether the file exists (w. or W.out the search path), and gets
       
  2075 //		      it's file size.
       
  2076 // Inputs   : pszFile	-	The file to find (as a UNICODE string)
       
  2077 //			  pdwSize   - store its size here (set to zero if not found)
       
  2078 // Returns  : Yes or No
       
  2079 
       
  2080 	{
       
  2081 	bool fFound = false;
       
  2082 	*pdwSize = 0;
       
  2083 
       
  2084 	try
       
  2085 		{
       
  2086 		HANDLE hFile = ::MakeSISOpenFile(pszFile, GENERIC_READ, OPEN_EXISTING);
       
  2087 		if (hFile != INVALID_HANDLE_VALUE)
       
  2088 			{
       
  2089 			*pdwSize = ::GetFileSize(hFile, NULL);
       
  2090 			::CloseHandle(hFile);
       
  2091 			fFound = true;
       
  2092 			}
       
  2093 		else
       
  2094 			{
       
  2095 			// If we are using a search directory
       
  2096 			if(iSearchDir[0] != '\0')
       
  2097 				{
       
  2098 
       
  2099 				if (wcslen (iSearchDir) + wcslen (pszFile) < PATHMAX - 1)
       
  2100 					{
       
  2101 					wchar_t pszNewPath[PATHMAX];
       
  2102 					wcscpy(pszNewPath, iSearchDir);
       
  2103 					wcscat(pszNewPath, pszFile);
       
  2104 					HANDLE hFile = MakeSISOpenFile(pszNewPath, GENERIC_READ, OPEN_EXISTING);
       
  2105 					if (hFile != INVALID_HANDLE_VALUE)
       
  2106 						{
       
  2107 						*pdwSize = ::GetFileSize(hFile, NULL);
       
  2108 						CloseHandle(hFile);
       
  2109 						wcscpy(pszFile, pszNewPath);
       
  2110 						fFound = true;
       
  2111 						}
       
  2112 					}
       
  2113 				}
       
  2114 			}
       
  2115 		}
       
  2116 	catch (TUtilsException excp)
       
  2117 		{
       
  2118 		// ignore error if writing a stub file
       
  2119 		if (!iMakeStub) throw excp;
       
  2120 		iObserver.DoVerbage(L"warning :file does not exist");
       
  2121 		fFound=true;
       
  2122 		}
       
  2123 	return fFound;
       
  2124 	}
       
  2125 
       
  2126 bool CPackageParser::DoesFileExist (std::wstring& aFileName, TUint64& aSize)
       
  2127 
       
  2128 	{
       
  2129 	if (aFileName.empty ()) return false;
       
  2130 	bool found = false;
       
  2131 	aSize = 0;
       
  2132 
       
  2133 	try
       
  2134 		{
       
  2135 		HANDLE hFile = ::MakeSISOpenFile (aFileName.c_str (), GENERIC_READ, OPEN_EXISTING);
       
  2136 		if (hFile == INVALID_HANDLE_VALUE)
       
  2137 			{
       
  2138 			// If we are using a search directory
       
  2139 			if(iSearchDir[0] != '\0')
       
  2140 				{
       
  2141 				std::wstring newPath (std::wstring (iSearchDir) + aFileName);
       
  2142 				hFile = ::MakeSISOpenFile (newPath.c_str (), GENERIC_READ, OPEN_EXISTING);
       
  2143 				if (hFile != INVALID_HANDLE_VALUE) aFileName = newPath;
       
  2144 				}
       
  2145 			}
       
  2146 		if (hFile != INVALID_HANDLE_VALUE)
       
  2147 			{
       
  2148 			aSize  = GetSizeOfFile(hFile);
       
  2149 			found = true;
       
  2150 			}
       
  2151 		}
       
  2152 	catch (TUtilsException excp)
       
  2153 		{
       
  2154 		// ignore error if writing a stub file
       
  2155 		if (!iMakeStub) throw excp;
       
  2156 		iObserver.DoVerbage(L"warning :file does not exist");
       
  2157 		found=true;
       
  2158 		}
       
  2159 	return found;
       
  2160 	}
       
  2161 
       
  2162 TUint32 CPackageParser::Find(wchar_t* aWhat, CSISFileDescription& aFileDesciption)
       
  2163 	{
       
  2164 	TUint32 ret = -1;
       
  2165 	if ( iSrcFiles.find(aWhat) != iSrcFiles.end() )
       
  2166 		{
       
  2167 		aFileDesciption = iSrcFiles[aWhat];
       
  2168 		ret = aFileDesciption.FileIndex();
       
  2169 		}
       
  2170 	return ret;
       
  2171 	}
       
  2172 
       
  2173 void CPackageParser::Set(std::wstring& aWhat, CSISFileDescription& aData)
       
  2174 	{
       
  2175 	iSrcFiles[aWhat] = aData;
       
  2176 	}
       
  2177 
       
  2178 void CPackageParser::ReportInterpretSisError(TInterpretSisException aException)
       
  2179 	{
       
  2180 	iValidSISFile = false;
       
  2181 	iObserver.AddInterpretSisError(aException);
       
  2182 	}
       
  2183 
       
  2184 void CPackageParser::ComputeAndSetHash(CSISFileDescription& aFileDesc)
       
  2185 	{
       
  2186 	const CSISDataUnit& dataUnit = iSISXWriter.DataUnit();
       
  2187 	const CSISFileData& fileData  = dataUnit.FileData(aFileDesc.FileIndex());
       
  2188 	// Compute the hash data for the file. 
       
  2189 	CSISHash tempSisHash;	  	
       
  2190 	TUint8 digest [SHA_DIGEST_LENGTH];
       
  2191 	memset (&digest, 0, SHA_DIGEST_LENGTH);
       
  2192 #ifdef GENERATE_ERRORS
       
  2193 	if (CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugHashError))
       
  2194 		{
       
  2195 		for (unsigned index = 0; index < SHA_DIGEST_LENGTH; index++)
       
  2196 			{
       
  2197 			digest [index] = static_cast <TUint8> (rand () & 0xFF);
       
  2198 			}
       
  2199 		}
       
  2200 	else
       
  2201 #endif // GENERATE_ERRORS
       
  2202 		{
       
  2203 		SHA1 (fileData.Data (), fileData.UncompressedSize (), digest);
       
  2204 		}
       
  2205  	aFileDesc.SetHash(digest, SHA_DIGEST_LENGTH);
       
  2206 	}
       
  2207