secureswitools/swisistools/source/sisxlibrary/sisfiledescription.cpp
changeset 0 ba25891c3a9e
child 26 04d4a7bbc3e0
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2004-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 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20  @file 
       
    21  @internalComponent
       
    22  @released
       
    23 */
       
    24 #ifdef _MSC_VER
       
    25 #pragma warning (disable: 4786)
       
    26 #endif // _MSC_VER
       
    27 //
       
    28 // Note: This file may contain code to generate corrupt files for test purposes.
       
    29 // Such code is excluded from production builds by use of compiler defines;
       
    30 // it is recommended that such code should be removed if this code is ever published publicly.
       
    31 //
       
    32 
       
    33 #include "sisfiledescription.h"
       
    34 #include "sisdataunit.h"
       
    35 #include <string>
       
    36 #include "utility_interface.h"
       
    37 #include "siscontents.h"
       
    38 
       
    39 static std::wstring aOption1;
       
    40 // This table must remain sorted by identifier name, since the search routine
       
    41 // assumes that it is sorted.
       
    42 static const SIdentifierTable KOptions [] = 
       
    43 	{
       
    44 		{	L"FA",					CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionForceAbort	},
       
    45 		{	L"FF",					CSISFileDescription::EOpInstall,	CSISFileDescription::EInstFileNone	},
       
    46 		{	L"FILE",				CSISFileDescription::EOpInstall,	CSISFileDescription::EInstFileNone	},
       
    47 		{	L"FILEMIME",			CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionByMimeType	},
       
    48 		{	L"FILENULL",			CSISFileDescription::EOpNull,		CSISFileDescription::EInstFileNone	},
       
    49 		{	L"FILERUN",				CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileNone	},
       
    50 		{	L"FILETEXT",			CSISFileDescription::EOpText,		CSISFileDescription::EInstFileNone	},
       
    51 		{	L"FM",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionByMimeType	},
       
    52 		{	L"FN",					CSISFileDescription::EOpNull,		CSISFileDescription::EInstFileNone	},
       
    53 		{	L"FORCEABORT",			CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionForceAbort	},	
       
    54 		{	L"FR",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileNone	},
       
    55 		{	L"FT",					CSISFileDescription::EOpText,		CSISFileDescription::EInstFileNone	},
       
    56 		{	L"MF",					0,	0			},
       
    57 		{	L"MODIFIABLE",			0,	0			},
       
    58 		{	L"RA",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionAfterInstall },
       
    59 		{	L"RB",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionInstall | CSISFileDescription::EInstFileRunOptionUninstall	},
       
    60 		{	L"RBS",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionBeforeShutdown	},
       
    61 		{	L"RI",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionInstall		},
       
    62 		{	L"RR",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionUninstall	},
       
    63 		{	L"RS",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionSendEnd		},
       
    64 		{	L"RUNAFTERINSTALL",		CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionAfterInstall },
       
    65 		{	L"RUNBEFORESHUTDOWN",	CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionBeforeShutdown	},
       
    66 		{	L"RUNBOTH",				CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionInstall | CSISFileDescription::EInstFileRunOptionUninstall	},
       
    67 		{	L"RUNINSTALL",			CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionInstall		},
       
    68 		{	L"RUNREMOVE",			CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionUninstall	},
       
    69 		{	L"RUNSENDEND",			CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionSendEnd		},
       
    70 		{	L"RUNWAITEND",			CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionWaitEnd		},
       
    71 		{	L"RW",					CSISFileDescription::EOpRun,		CSISFileDescription::EInstFileRunOptionWaitEnd		},
       
    72 		{	L"TA",					CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionAbortIfNo	},
       
    73 		{	L"TC",					CSISFileDescription::EOpText,		CSISFileDescription::EInstFileNone	},
       
    74 		{	L"TE",					CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionExitIfNo	},
       
    75 		{	L"TEXTABORT",			CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionAbortIfNo	},
       
    76 		{	L"TEXTCONTINUE",		CSISFileDescription::EOpText,		CSISFileDescription::EInstFileNone	},
       
    77 		{	L"TEXTEXIT",			CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionExitIfNo	},
       
    78 		{	L"TEXTSKIP",			CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionSkipIfNo	},
       
    79 		{	L"TS",					CSISFileDescription::EOpText,		CSISFileDescription::EInstFileTextOptionSkipIfNo	},
       
    80 		{	L"VERIFY",				CSISFileDescription::EOpInstall,	CSISFileDescription::EInstVerifyOnRestore			},
       
    81 		{	L"VR",					CSISFileDescription::EOpInstall,	CSISFileDescription::EInstVerifyOnRestore			},
       
    82 		{	NULL,					0,									0	}
       
    83 
       
    84 	};
       
    85 
       
    86 static const SKeyword1 KEscSymbols [] = 
       
    87 	{
       
    88 		{ L"?"},
       
    89 		{ L"*"},
       
    90 		{ L"\""},
       
    91 		{ L":"},
       
    92 		{ L"|"},
       
    93 		{ L"/"},
       
    94 		{L"<"},
       
    95 		{L">"},
       
    96 		{NULL}
       
    97 	};
       
    98 
       
    99 void CSISFileDescription::InsertMembers ()
       
   100 	{
       
   101 	InsertMember (iTarget);
       
   102 	InsertMember (iMimeType);
       
   103 	InsertMember (iCapabilities);
       
   104 	InsertMember (iHash);
       
   105 	InsertMember (iOperation);
       
   106 	InsertMember (iOperationOptions);
       
   107 	InsertMember (iLength);
       
   108 	InsertMember (iUncompressedLength);
       
   109 	InsertMember (iFileIndex);
       
   110 	}
       
   111 
       
   112 
       
   113 CSISFileDescription::CSISFileDescription (const CSISFileDescription& aInitialiser)	:
       
   114 		CStructure <CSISFieldRoot::ESISFileDescription> (aInitialiser),
       
   115 		iTarget (aInitialiser.iTarget),
       
   116 		iMimeType (aInitialiser.iMimeType),
       
   117 		iCapabilities (aInitialiser.iCapabilities),
       
   118 		iOperation (aInitialiser.iOperation),
       
   119 		iOperationOptions (aInitialiser.iOperationOptions),
       
   120 		iHash (aInitialiser.iHash),
       
   121 		iLength (aInitialiser.iLength),
       
   122 		iUncompressedLength (aInitialiser.iUncompressedLength),
       
   123 		iFileIndex (aInitialiser.iFileIndex)
       
   124 	{ 
       
   125 	InsertMembers (); 
       
   126 	}
       
   127 
       
   128 CSISFileDescription::TSISInstOption CSISFileDescription::InterpretOption (const std::wstring& aOption)
       
   129 	{
       
   130 	aOption1 = aOption; 
       
   131 	int index = SearchSortedUCTable (KOptions, aOption);
       
   132 	CSISException::ThrowIf (index < 0, CSISException::ESyntax, L"unknown option: " + aOption);
       
   133 	if (KOptions [index].iDeprecated)
       
   134 		{
       
   135 		SISLogger::Log(L"Option ");
       
   136 		SISLogger::Log(aOption);
       
   137 		SISLogger::Log(L" ignored.\n");
       
   138 		}
       
   139 	CSISException::ThrowIf ((iOperation > EOpNone) && (iOperation != KOptions [index].iValue),
       
   140 							CSISException::ESyntax,
       
   141 							L"incompatible option: " + aOption);
       
   142 	iOperation |= KOptions [index].iValue;
       
   143 	iOperationOptions |= KOptions [index].iSubValue;
       
   144     
       
   145     
       
   146     // in order to be approximately backwards compatible - RUNAFTERINSTALL implies RUNINSTALL. SWI
       
   147 	// will run after install if it understands the new flag, or at install if it doesn't.
       
   148     if (KOptions [index].iSubValue &  CSISFileDescription::EInstFileRunOptionAfterInstall)
       
   149         {
       
   150         iOperationOptions |= CSISFileDescription::EInstFileRunOptionInstall;
       
   151         }
       
   152     
       
   153 	return static_cast <CSISFileDescription::TSISInstOption> (iOperationOptions.Value ());
       
   154 	}
       
   155 
       
   156 void CSISFileDescription::MakeNeat ()
       
   157 	{
       
   158 	
       
   159 	CStructure <CSISFieldRoot::ESISFileDescription>::MakeNeat ();
       
   160 		
       
   161 	std::wstring strTemp = iTarget.GetString();
       
   162 
       
   163 	// The hashes of files in \sys and \resource MUST be checked at restore time.
       
   164 	// N.B. SWI checks the hashes of these files regardless of the value of this flag. This
       
   165 	// is just set for consistency.
       
   166 	if ((strTemp.find(L"\\sys\\",0) == 2) || (strTemp.find(L"\\resource\\",0) == 2))
       
   167 		{
       
   168 		iOperationOptions = iOperationOptions |= EInstVerifyOnRestore;
       
   169 		}	
       
   170 
       
   171 	// If the package file specifies run by mime type but doesn't specify whether
       
   172 	// it should be run on install or uninstall, then default to install as per
       
   173 	// the old installer.
       
   174 	if ((iOperationOptions & EInstFileRunOptionByMimeType) &&
       
   175 		! (iOperationOptions & (EInstFileRunOptionInstall | EInstFileRunOptionUninstall)))
       
   176 		{
       
   177 		iOperationOptions |= EInstFileRunOptionInstall;
       
   178 		}
       
   179 
       
   180 
       
   181 	}
       
   182 
       
   183 void CSISFileDescription::Verify (const TUint32 aLanguages) const
       
   184 	{
       
   185 	CStructure <CSISFieldRoot::ESISFileDescription>::Verify (aLanguages);
       
   186 	CSISException::ThrowIf (iOperation >= EOpIllegal, CSISException::EVerification, "unsupported installation operation");
       
   187 	CSISException::ThrowIf (((iOperation & EOpInstall) != 0) && (iTarget.size () == 0),
       
   188 							CSISException::EVerification,
       
   189 							"installation requires a target file");
       
   190 	CSISException::ThrowIf (((iOperationOptions & EInstFileRunOptionByMimeType) != 0) && (iMimeType.size () == 0),
       
   191 							CSISException::EVerification,
       
   192 							"run by MIME Type requires a MIME type");
       
   193 	std::wstring destinationFile (iTarget.GetString());
       
   194 
       
   195 	if (iTarget.size () > 0)
       
   196 		{
       
   197 		if(destinationFile[1] != ':')
       
   198 			{
       
   199 			throw CSISException (CSISException::EInvalidDestination, "Invalid destination path check : is missing");		
       
   200 			}
       
   201 		
       
   202 		if(destinationFile[2] != '\\')
       
   203 			{
       
   204 			throw CSISException (CSISException::EInvalidDestination, "Invalid destination path check \\ is missing");		
       
   205 			}
       
   206 		
       
   207 		// Check whether the first character is either an alphabet or '!' or '$'(represents system drive).
       
   208 		if(!(isalpha(destinationFile[0])) && (destinationFile[0] !='!') && (destinationFile[0] != SYSTEMDRIVE ))
       
   209 			{
       
   210 			throw CSISException (CSISException::EInvalidDestination, "Invalid destination path check drive or ! is missing");					
       
   211 			}
       
   212 			
       
   213 		// Check for double dot paths in filename 
       
   214 			
       
   215 		CSISException::ThrowIf ((-1 != destinationFile.find(L"\\..\\")),
       
   216 			CSISException::EInvalidDestination, "File paths may not contain '..'");	
       
   217 		
       
   218 		unsigned int temp1 = destinationFile.find_last_of(L"\\" ,iTarget.size ());
       
   219 		std::wstring destinationFileName(destinationFile.substr(temp1 + 1,iTarget.size ()));
       
   220 		
       
   221 		// Check if install-file (exe or dll)  contain non ASCII characters
       
   222 		int size = iTarget.size();
       
   223 		
       
   224 		if(iTarget.size() >= 10)
       
   225 			{
       
   226 			std::wstring destinationFilePath (destinationFile.substr(0,10));
       
   227 			// Check for :\sys\bin after converting array in uppercase
       
   228 			for(int i = 1; i <= 9; i++)
       
   229 				{
       
   230 				destinationFilePath[i] = toupper(destinationFilePath[i]);
       
   231 				}
       
   232 			if(destinationFilePath.find(L":\\SYS\\BIN") != std::string::npos )
       
   233 				{
       
   234 				//For ROM stub file , if makesis encounters a wildcard in the file under \\sys\\bin directoy,
       
   235 				//throw a warning as described below
       
   236 				if (CSISContents::IsStub() && ((destinationFileName.find(L"*") != std::string::npos) || (destinationFileName.find(L"?") != std::string::npos)))
       
   237 					{
       
   238 					//iWarningFlag is added so that makesis can generate the warning at the first occurance of wildcard,
       
   239 					// if there are many executables in the ROM stub sis file with wildcards.
       
   240 					
       
   241 					static bool aWarningFlag = false;
       
   242 					if (!aWarningFlag)
       
   243 						{
       
   244 						SISLogger::Log(L"Warning: Executables should be included explicitly (without wildcards),to enable SID checks to work as expected.\n");
       
   245 						aWarningFlag = true;
       
   246 						}
       
   247 					}
       
   248 
       
   249 				int temp = 0;
       
   250 				for (int x = 0; x< iTarget.size () ;x++)
       
   251 					{
       
   252 					if(destinationFile[x] == '\\')
       
   253 					temp = x;
       
   254 					}
       
   255 				for(x = temp; x < iTarget.size (); x++)
       
   256 					{
       
   257 					if(!(isascii(destinationFile[x])))
       
   258 						{
       
   259 						throw CSISException (CSISException::EInvalidDestination, "File name contain non ascii characters");		
       
   260 						}
       
   261 					}
       
   262 				}
       
   263 			}
       
   264 
       
   265 		std::wstring destinationFile1 (destinationFile.substr(2,temp1-1));
       
   266 		const SKeyword1* index = NULL; 
       
   267 		for (index = &KEscSymbols[0]; index -> iName != NULL ; index++)
       
   268 			{
       
   269 			for (int x = 0; x <= temp1-2 ;x++)
       
   270 				{
       
   271 				if ((destinationFile1.find(index -> iName) != std::string::npos)) 
       
   272 					{
       
   273 					throw CSISException (CSISException::EInvalidDestination, "File paths may not contain \"<>'/");		
       
   274 					}
       
   275 				}
       
   276 			}
       
   277 		
       
   278 				
       
   279 		for (index = &KEscSymbols[0]; index -> iName != NULL ; index++)
       
   280 			{
       
   281 			for (int x = 0; x< (iTarget.size() - (temp1+1)) ;x++)
       
   282 				{
       
   283 				if (destinationFileName.find(index -> iName) != std::string::npos) 
       
   284 					{
       
   285 #ifdef SIGNSIS
       
   286 					if(index -> iName == (L"*"))
       
   287 						{
       
   288 						continue;
       
   289 						}
       
   290 #else
       
   291 					// Allow wildchars in ROM stub sis files
       
   292 					if (CSISContents::IsStub() && ((index -> iName == (L"*")) || (index -> iName == (L"?"))) )
       
   293 						{
       
   294 						continue;
       
   295 						}	
       
   296 					// Allow * for FN case, ex: ""-"c:\*", FN
       
   297 					else if((index -> iName == (L"*")) && (iOperation & EOpNull))
       
   298 						{
       
   299 						continue;
       
   300 						}
       
   301 #endif
       
   302 					else
       
   303 						{
       
   304 						throw CSISException (CSISException::EInvalidDestination, "File paths may not contain \"<>'/");
       
   305 						break;
       
   306 						}
       
   307 					}
       
   308 				}
       
   309 			}
       
   310 		}
       
   311 	int nNo = 0;
       
   312 	if ((iOperationOptions & EInstFileTextOptionSkipIfNo) != 0) 
       
   313 		{
       
   314 		nNo++;
       
   315 		}
       
   316 	if ((iOperationOptions & EInstFileTextOptionAbortIfNo) != 0) 
       
   317 		{
       
   318 		nNo++;
       
   319 		}
       
   320 	if ((iOperationOptions & EInstFileTextOptionExitIfNo) != 0) 
       
   321 		{
       
   322 		nNo++;
       
   323 		}
       
   324 	if ((iOperationOptions & EInstFileTextOptionForceAbort) != 0) 
       
   325 		{
       
   326 		nNo++;
       
   327 		}
       
   328 	
       
   329 	CSISException::ThrowIf (nNo > 1,
       
   330 							CSISException::EVerification,
       
   331 							"Skip If No, Abort If No, Exit If No and ForceAbort options incompatible");
       
   332 	CSISException::ThrowIf (((iOperationOptions & EInstFileRunOptionWaitEnd) != 0) && ((iOperationOptions & EInstFileRunOptionSendEnd) != 0),
       
   333 							CSISException::EVerification,
       
   334 							"Wait End and Send End are incompatible");
       
   335 	}
       
   336 
       
   337 
       
   338 
       
   339 std::string CSISFileDescription::Name () const
       
   340 	{
       
   341 	return "File Description";
       
   342 	}
       
   343 
       
   344 void CSISFileDescription::SetHash(const TUint8* aHash, TUint32 aHashSize)
       
   345 	{
       
   346 	iHash.SetHash(aHash, aHashSize);
       
   347 	}
       
   348 
       
   349 void CSISFileDescription::SetHash (const CSISHash& aHash)
       
   350 	{
       
   351 	iHash = aHash;
       
   352 	}
       
   353 
       
   354 void CSISFileDescription::ExtractCapabilities(const std::wstring& aFileName)
       
   355 	{
       
   356 #ifdef GENERATE_ERRORS
       
   357 	if (CSISFieldRoot::IsBugToBeCreated(CSISFieldRoot::EBugEmptyCaps))
       
   358 		{
       
   359 		// don't store exe capabilities in the controller
       
   360 		return;
       
   361 		}
       
   362 #endif 
       
   363 	iCapabilities.ExtractCapabilities(aFileName);
       
   364 	
       
   365 	}
       
   366 
       
   367 void CSISFileDescription::AddPackageEntry(std::wostream& aStream, bool aVerbose) const
       
   368 	{
       
   369 	aStream <<L";";
       
   370 	iTarget.AddPackageEntry(aStream, aVerbose);
       
   371 	aStream << std::endl << L"; File length " << iLength << L" (" << iUncompressedLength << L")" << std::endl;
       
   372 	iCapabilities.AddPackageEntry(aStream, aVerbose);
       
   373 	iHash.AddPackageEntry(aStream, aVerbose);
       
   374 	
       
   375 	const wchar_t* fileName = GetFileName(); 
       
   376 	
       
   377 	aStream <<std::endl <<L"\"" << fileName << L"\"";
       
   378 	delete[] const_cast<wchar_t*>(fileName);
       
   379 	aStream << L"-";
       
   380 	aStream << L"\"";
       
   381 	iTarget.AddPackageEntry(aStream, aVerbose);
       
   382 	aStream << L"\"";
       
   383 
       
   384 	TUint32 operation = (TUint32) iOperation;
       
   385 	TUint32 options = (TUint32) iOperationOptions;
       
   386 
       
   387 	if (((operation & EOpInstall) || (operation & EOpRun)) && (options & EInstVerifyOnRestore))
       
   388 		{
       
   389 		options &= ~EInstVerifyOnRestore;
       
   390 		aStream << L", " << (aVerbose?L"VERIFY":L"VR");
       
   391 		}			
       
   392 
       
   393 	if (operation & EOpInstall)
       
   394 		{
       
   395 		operation &= ~EOpInstall;
       
   396 		aStream << L", " << (aVerbose?L"FILE":L"FF");
       
   397 		}
       
   398 
       
   399 	if (operation & EOpRun)
       
   400 		{
       
   401 		operation &= ~EOpRun;
       
   402 		if (options & EInstFileRunOptionByMimeType)
       
   403 			{
       
   404 			options &= ~EInstFileRunOptionByMimeType;
       
   405 			aStream << L", " << (aVerbose?L"FILEMIME, ":L"FM,\" ");
       
   406 			iMimeType.AddPackageEntry(aStream, aVerbose);
       
   407 			aStream<<L"\"";
       
   408 			}
       
   409 		else
       
   410 			{
       
   411 			aStream << L", " << (aVerbose?L"FILERUN":L"FR");
       
   412 			}
       
   413 		if (options & (EInstFileRunOptionInstall&EInstFileRunOptionUninstall))
       
   414 			{
       
   415 			options &= ~(EInstFileRunOptionInstall&EInstFileRunOptionUninstall);
       
   416 			aStream << L", " << (aVerbose?L"RUNBOTH":L"RB");
       
   417 			}
       
   418 		if (options & EInstFileRunOptionInstall)
       
   419 			{
       
   420 			options &= ~EInstFileRunOptionInstall;
       
   421 			aStream << L", " << (aVerbose?L"RUNINSTALL":L"RI");
       
   422 			}
       
   423 		if (options & EInstFileRunOptionUninstall)
       
   424 			{
       
   425 			options &= ~EInstFileRunOptionUninstall;
       
   426 			aStream << L", " << (aVerbose?L"RUNREMOVE":L"RR");
       
   427 			}
       
   428 		if (options & EInstFileRunOptionBeforeShutdown)
       
   429 			{
       
   430 			options &= ~EInstFileRunOptionBeforeShutdown;
       
   431 			aStream << L", " << (aVerbose?L"RUNBEFORESHUTDOWN":L"RBS");
       
   432 			}
       
   433 		if (options & EInstFileRunOptionWaitEnd)
       
   434 			{
       
   435 			options &= ~EInstFileRunOptionWaitEnd;
       
   436 			aStream << L", " << (aVerbose?L"RUNWAITEND":L"RW");
       
   437 			}
       
   438 		if (options & EInstFileRunOptionSendEnd)
       
   439 			{
       
   440 			options &= ~EInstFileRunOptionSendEnd;
       
   441 			aStream << L", " << (aVerbose?L"RUNSENDEND":L"RS");
       
   442 			}
       
   443 		if (options & EInstFileRunOptionAfterInstall)
       
   444 			{
       
   445 			options &= ~EInstFileRunOptionAfterInstall;
       
   446 			aStream << L", " << (aVerbose?L"RUNAFTERINSTALL":L"RA");
       
   447 			}
       
   448 		}
       
   449 	if (operation & EOpText)
       
   450 		{
       
   451 		operation &= ~EOpText;
       
   452 		aStream << L", " << (aVerbose?L"FILETEXT":L"FT");
       
   453 		if (options & EInstFileTextOptionContinue)
       
   454 			{
       
   455 			options &= ~EInstFileTextOptionContinue;
       
   456 			aStream << L", " << (aVerbose?L"TEXTCONTINUE":L"TC");
       
   457 			}
       
   458 		if (options & EInstFileTextOptionSkipIfNo)
       
   459 			{
       
   460 			options &= ~EInstFileTextOptionSkipIfNo;
       
   461 			aStream << L", " << (aVerbose?L"TEXTSKIP":L"TS");
       
   462 			}
       
   463 		if (options & EInstFileTextOptionAbortIfNo)
       
   464 			{
       
   465 			options &= ~EInstFileTextOptionAbortIfNo;
       
   466 			aStream << L", " << (aVerbose?L"TEXTABORT":L"TA");
       
   467 			}
       
   468 		if (options & EInstFileTextOptionExitIfNo)
       
   469 			{
       
   470 			options &= ~EInstFileTextOptionExitIfNo;
       
   471 			aStream << L", " << (aVerbose?L"TEXTEXIT":L"TE");
       
   472 			}
       
   473 		if (options & EInstFileTextOptionForceAbort)
       
   474 			{
       
   475 			options &= ~EInstFileTextOptionForceAbort;
       
   476 			aStream << L", " << (aVerbose?L"FORCEABORT":L"FA");
       
   477 			}
       
   478 		}
       
   479 	if (operation & EOpNull) 
       
   480 		{ 
       
   481 		operation &=~EOpNull; 
       
   482 		aStream << L", " << (aVerbose?L"FILENULL":L"FN"); 
       
   483 		} 
       
   484 
       
   485 	aStream << std::endl;
       
   486 	if (aVerbose && operation)
       
   487 		{
       
   488 		aStream << L"; (warning: unparsed operation(s) on preceding line" << std::endl;
       
   489 		}
       
   490 	if (aVerbose && options)
       
   491 		{
       
   492 		aStream << L"; (warning: unparsed option(s) on preceding line" << std::endl;
       
   493 		}
       
   494 	}
       
   495 
       
   496 const wchar_t* CSISFileDescription::GetFileName() const
       
   497 	{
       
   498 	// Using actual iFileIndex rather than iFileNum because source file might be
       
   499 	// the same for several targets and hence has an index different from simple
       
   500 	// sequentual ordinal value
       
   501 	wchar_t* fileName = new wchar_t[30];
       
   502 #ifdef _MSC_VER
       
   503 	swprintf(fileName, L"file%d", iFileIndex.Value());
       
   504 #else
       
   505 	swprintf(fileName, 30, L"file%d", iFileIndex.Value());
       
   506 #endif //_MSC_VER
       
   507 	return fileName;
       
   508 	}
       
   509 
       
   510 
       
   511 #ifdef GENERATE_ERRORS
       
   512 void CSISFileDescription::CreateDefects ()
       
   513 	{
       
   514 	if (CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugInvalidValues))
       
   515 		{
       
   516 		iOperation = rand ();
       
   517 		}
       
   518 	if (CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugInvalidValues))
       
   519 		{
       
   520 		iOperationOptions = rand ();
       
   521 		}
       
   522 	if (CSISFieldRoot::IsBugToBeCreated (CSISFieldRoot::EBugInvalidValues))
       
   523 		{
       
   524 		iFileIndex = rand ();
       
   525 		}
       
   526 	}
       
   527 #endif // GENERATE_ERRORS