appfw/apparchitecture/apserv/apsnnappupdates.cpp
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Non-Native application registration functionality for the AppArc server session
       
    15 // 
       
    16 // apsnnappupdates.cpp
       
    17 //
       
    18 
       
    19 #include "apsnnappupdates.h"
       
    20 
       
    21 #include <bautils.h>
       
    22 #include <f32file.h>
       
    23 #include <s32file.h>
       
    24 
       
    25 #include "APAID.H"
       
    26 #include "../aplist/aplapplistitem.h"
       
    27 #include "apsserv.h"
       
    28 #include "APSSTD.H"
       
    29 #include "../aplist/aplappregfinder.h"
       
    30 #include "../apgrfx/apprivate.h"
       
    31 #include "apsnnapps.h"
       
    32 
       
    33 
       
    34 /**************************************************************************************************************
       
    35  * TFilePositionReset
       
    36  **************************************************************************************************************/
       
    37 
       
    38 /**
       
    39 This class is used to ensure that a RFile's read/write position is reset to its original value
       
    40 if a leave occurs.
       
    41 
       
    42 @internalComponent
       
    43 */
       
    44 NONSHARABLE_CLASS(TFilePositionReset)
       
    45 	{
       
    46 public:
       
    47 	TFilePositionReset(RFile& aFile) :
       
    48 	 		iFile(aFile),
       
    49  			iOriginalFilePosition(-1)
       
    50  		{
       
    51 	 	}
       
    52 
       
    53 	void RewindToStartLC()
       
    54 		{
       
    55 		TInt originalFilePosition=0;
       
    56 		User::LeaveIfError(iFile.Seek(ESeekCurrent, originalFilePosition)); // retrieves the current file-position
       
    57 		TInt newFilePosition=0;
       
    58 		User::LeaveIfError(iFile.Seek(ESeekStart, newFilePosition)); // RFile::Seek(ESeekStart,..) will not modify the TInt, but needs a reference.
       
    59 		iOriginalFilePosition=originalFilePosition;
       
    60 		CleanupStack::PushL(TCleanupItem(&StaticReset, this));
       
    61 		}
       
    62 
       
    63 	TInt Reset()
       
    64 		{
       
    65 		__ASSERT_DEBUG(iOriginalFilePosition>=0, Panic(ENonNativeAppsNegativeStoredFilePosition));
       
    66 		const TInt error = iFile.Seek(ESeekStart, iOriginalFilePosition);
       
    67 		iOriginalFilePosition=-1;
       
    68 		return error;
       
    69 		}
       
    70 
       
    71 private:
       
    72 	static void StaticReset(TAny* aThis)
       
    73 		{
       
    74 		// ignore the error code from this, we can't do anything about it
       
    75 		static_cast<TFilePositionReset*>(aThis)->Reset();
       
    76 		}
       
    77 
       
    78 private:
       
    79 	RFile& iFile;
       
    80 	TInt iOriginalFilePosition;
       
    81 	};
       
    82 
       
    83 
       
    84 /**************************************************************************************************************
       
    85  * TFileDetails
       
    86  **************************************************************************************************************/
       
    87 
       
    88 TFileDetails::TFileDetails() :
       
    89 		iState(EStateNull) 
       
    90 	{
       
    91 	}
       
    92 
       
    93 /*
       
    94 Returns the real path, (aka the target location) of this file
       
    95 */
       
    96 const TDesC& TFileDetails::Path()
       
    97 	{
       
    98 	__ASSERT_DEBUG(iPath != KNullDesC, Panic(ENonNativeAppsTFileDetailsPathNotSet));
       
    99 	return iPath;
       
   100 	}
       
   101 
       
   102 
       
   103 /*
       
   104 Sets the real path, (aka the target location) of this file
       
   105 */
       
   106 void TFileDetails::SetPath(const TDesC& aPath)
       
   107 	{
       
   108 	__ASSERT_DEBUG(iPath == KNullDesC, Panic(ENonNativeAppsTFileDetailsPathAlreadySet));
       
   109 	iPath = aPath;
       
   110 	}
       
   111 
       
   112 
       
   113 /*
       
   114 Determines whether this TFileDetails has a real path set.
       
   115 If thie object doesn't have a real path set, it is assumed to not be in use
       
   116 */
       
   117 TBool TFileDetails::Exists() const
       
   118 	{
       
   119 	return (iPath != KNullDesC);
       
   120 	}
       
   121 
       
   122 
       
   123 /*
       
   124 Releases whatever file handle is currently held, whether it is on the real file,
       
   125 temporary file, or none at all
       
   126 */
       
   127 void TFileDetails::CloseHandle()
       
   128 	{
       
   129 	iHandle.Close();
       
   130 	}
       
   131 
       
   132 
       
   133 /*
       
   134 Opens a handle on a real file
       
   135 */
       
   136 void TFileDetails::OpenL(RFs& aFs, const TFileName& aFileName)
       
   137 	{
       
   138 	__ASSERT_DEBUG(iState == EStateNull, Panic(ENonNativeAppsTFileDetailsOpenInBadState));
       
   139 	__ASSERT_DEBUG(iPath == KNullDesC, Panic(ENonNativeAppsTFileDetailsOpenWithRealPathSet));
       
   140 	__ASSERT_DEBUG(iTempPath == KNullDesC, Panic(ENonNativeAppsTFileDetailsOpenWithTempPathSet));
       
   141 
       
   142 	User::LeaveIfError(iHandle.Open(aFs, aFileName, EFileShareExclusive|EFileStream|EFileWrite));
       
   143 	iPath = aFileName;
       
   144 	iState = EStateReal;
       
   145 	}
       
   146 
       
   147 /*
       
   148 Creates a new, temporary file to write new data into
       
   149 Used in the preparation of a register-application update to create new resource
       
   150 and icon files before they are moved into their target locations.
       
   151 */
       
   152 void TFileDetails::CreateTemporaryL(RFs& aFs, const TFileName& aDir)
       
   153 	{
       
   154 	__ASSERT_DEBUG(iState == EStateNull, Panic(ENonNativeAppsTFileDetailsCreateTempInBadState));
       
   155 	__ASSERT_DEBUG(iTempPath == KNullDesC, Panic(ENonNativeAppsTFileDetailsCreateTempWithTempPathSet));
       
   156 	RFile file;
       
   157 	CleanupClosePushL(file);
       
   158 	// NOTE: remove this workaround if/when RFile::Temp is fixed by base
       
   159 	TInt tempErr = KErrAlreadyExists;
       
   160 	/* RFile::Temp is a bit dodgy, at least on Winscw with the proxy FS */
       
   161 	for(TInt tries = 0; tempErr == KErrAlreadyExists && tries < 50; ++tries)
       
   162 		{
       
   163 		tempErr = file.Temp(aFs, aDir, iTempPath, EFileShareExclusive|EFileStream|EFileWrite);
       
   164 		}
       
   165 	User::LeaveIfError(tempErr);
       
   166 	CleanupStack::Pop(&file);
       
   167 	iHandle = file;
       
   168 	iState = EStateTemporary;
       
   169 	}
       
   170 
       
   171 /*
       
   172 Makes aFile a duplicates of the file handle owned by this class.
       
   173 Used to write to a file created by CreateTemporaryL()
       
   174 */
       
   175 void TFileDetails::GetDuplicateHandleL(RFile& aFile)
       
   176 	{
       
   177 	User::LeaveIfError(aFile.Duplicate(iHandle));
       
   178 	}
       
   179 
       
   180 
       
   181 /*
       
   182 RenameToRealL
       
   183 
       
   184 Used to perform a register-appliction update
       
   185 This uses the same code as the non-leaving
       
   186 RenameToReal().
       
   187 */
       
   188 void TFileDetails::RenameToRealL(RFs& aFs)
       
   189 	{
       
   190 	User::LeaveIfError(RenameToReal(aFs));
       
   191 	}
       
   192 
       
   193 /*
       
   194 RenameToReal
       
   195 
       
   196 Used by RenameToRealL() and RestoreReal()
       
   197 @see RenameToRealL
       
   198 @see RestoreReal
       
   199 */
       
   200 TInt TFileDetails::RenameToReal(RFs& aFs)
       
   201 	{
       
   202 	__ASSERT_DEBUG(iState == EStateTemporary, Panic(ENonNativeAppsTFileDetailsRenameToRealInBadState));
       
   203 	__ASSERT_DEBUG(iTempPath != KNullDesC, Panic(ENonNativeAppsTFileDetailsRenameToRealWithoutTempPath));
       
   204 	__ASSERT_DEBUG(iPath != KNullDesC, Panic(ENonNativeAppsTFileDetailsRenameToRealWithoutRealPath));
       
   205 	TParse parse;
       
   206 	parse.SetNoWild(iPath,NULL,NULL);
       
   207 	if(!BaflUtils::FolderExists(aFs,parse.DriveAndPath())) 
       
   208 		{
       
   209 		TInt err = aFs.MkDirAll(parse.DriveAndPath());
       
   210 		if(err != KErrNone)
       
   211 			{
       
   212 			return err;
       
   213 			}
       
   214 		}
       
   215 	//Check if file already exists, if it exists delete it because we might be trying to register an upgrade 
       
   216 	if(BaflUtils::FileExists(aFs, iPath)) 
       
   217     	{ 
       
   218         TInt err = BaflUtils::DeleteFile(aFs, iPath); 
       
   219         if(KErrNone != err) 
       
   220         	{ 
       
   221             return err; 
       
   222             } 
       
   223 		}
       
   224 	TInt err = iHandle.Rename(iPath);
       
   225 	if(err != KErrNone)
       
   226 		{
       
   227 		return err;
       
   228 		}
       
   229 	iTempPath.Zero();
       
   230 	iState = EStateReal;
       
   231 	return KErrNone;
       
   232 	}
       
   233 
       
   234 /*
       
   235 RenameToTemporaryL
       
   236 
       
   237 Used to perform a deregister-application update
       
   238 */
       
   239 void TFileDetails::RenameToTemporaryL(RFs& aFs, const TFileName& aDir)
       
   240 	{
       
   241 	__ASSERT_DEBUG(iState == EStateReal, Panic(ENonNativeAppsTFileDetailsRenameToTempInBadState));
       
   242 	__ASSERT_DEBUG(iPath != KNullDesC, Panic(ENonNativeAppsTFileDetailsRenameToTempWithoutRealPathSet));
       
   243 	__ASSERT_DEBUG(iTempPath == KNullDesC, Panic(ENonNativeAppsTFileDetailsRenameToTempWithTempPathSet));
       
   244 	/* create a temp file and delete it to get an unused filename */
       
   245 	RFile file;
       
   246 	CleanupClosePushL(file);
       
   247 	// NOTE: remove this workaround if/when RFile::Temp is fixed by base
       
   248 	TInt tempErr = KErrAlreadyExists;
       
   249 	/* RFile::Temp is a bit dodgy, at least on Winscw with the proxy FS */
       
   250 	for(TInt tries = 0; tempErr == KErrAlreadyExists && tries < 50; ++tries)
       
   251 		{
       
   252 		tempErr = file.Temp(aFs, aDir, iTempPath, EFileShareExclusive|EFileStream|EFileWrite);
       
   253 		}
       
   254 	User::LeaveIfError(tempErr);
       
   255 	CleanupStack::PopAndDestroy(&file); // close the file handle
       
   256 	const TInt err = aFs.Delete(iTempPath);
       
   257 	if(err != KErrNone && err != KErrNotFound) 
       
   258 		{
       
   259 		User::Leave(err);
       
   260 		}
       
   261 
       
   262 	User::LeaveIfError(iHandle.Rename(iTempPath));
       
   263 	iState = EStateTemporary;
       
   264 	}
       
   265 
       
   266 
       
   267 /*
       
   268 Delete
       
   269 
       
   270 Whatever the state, real or temporary, delete it.
       
   271 Used in the rollback phase of a register-application update.
       
   272 
       
   273 This function releases the handle (if any) and sets the state back to EStateNull
       
   274 */
       
   275 TInt TFileDetails::Delete(RFs& aFs)
       
   276 	{
       
   277 	__ASSERT_DEBUG(iState == EStateNull || iState == EStateReal || iState == EStateTemporary,
       
   278 			Panic(ENonNativeAppsTFileDetailsDeleteInBadState));
       
   279 	if(iState == EStateNull)
       
   280 		{
       
   281 		return KErrNone;
       
   282 		}
       
   283 
       
   284 	iHandle.Close();
       
   285 	TInt err;
       
   286 	if(iState == EStateReal)
       
   287 		{
       
   288 		err = aFs.Delete(iPath);
       
   289 		}
       
   290 	else if(iState == EStateTemporary)
       
   291 		{
       
   292 		err = aFs.Delete(iTempPath);
       
   293 		}
       
   294 	else
       
   295 		{
       
   296 		err = KErrGeneral;
       
   297 		ASSERT(EFalse);
       
   298 		}
       
   299 	iPath.Zero();
       
   300 	iTempPath.Zero();
       
   301 	iState = EStateNull;
       
   302 	return err;
       
   303 	}
       
   304 
       
   305 
       
   306 /*
       
   307 DeleteTemporary
       
   308 
       
   309 Check that the state is EStateTemporary, and delete it.
       
   310 This function is used by the destructor of a deregister-application update
       
   311 
       
   312 This function releases the handle (if any) and sets the state back to EStateNull
       
   313 */
       
   314 TInt TFileDetails::DeleteTemporary(RFs& aFs)
       
   315 	{
       
   316 	__ASSERT_DEBUG(iState == EStateNull || iState == EStateTemporary,
       
   317 			Panic(ENonNativeAppsTFileDetailsDeleteTemporaryInBadState));
       
   318 	if(iState == EStateNull || iState == EStateTemporary)
       
   319 		{
       
   320 		return Delete(aFs);
       
   321 		}
       
   322 	return KErrGeneral;
       
   323 	}
       
   324 
       
   325 
       
   326 /*
       
   327 RestoreReal
       
   328 
       
   329 Whatever the state, real or temporary, try to move it back to the real location.
       
   330 Used in the rollback phase of a deregister-application update.
       
   331 
       
   332 This function releases the handle (if any) and sets the state back to EStateNull
       
   333 */
       
   334 TInt TFileDetails::RestoreReal(RFs& aFs)
       
   335 	{
       
   336 	__ASSERT_DEBUG(iState == EStateNull || iState == EStateReal || iState == EStateTemporary,
       
   337 		Panic(ENonNativeAppsTFileDetailsRestoreRealInBadState));
       
   338 	if(iState == EStateNull)
       
   339 		{
       
   340 		return KErrNone;
       
   341 		}
       
   342 
       
   343 	TInt err = KErrNone;
       
   344 	if(iState == EStateReal)
       
   345 		{
       
   346 		iHandle.Close();
       
   347 		}
       
   348 	else if(iState == EStateTemporary)
       
   349 		{
       
   350 		err = RenameToReal(aFs);
       
   351 		iHandle.Close();
       
   352 		}
       
   353 	else
       
   354 		{
       
   355 		ASSERT(EFalse);
       
   356 		}
       
   357 	iPath.Zero();
       
   358 	iTempPath.Zero();
       
   359 	iState = EStateNull;
       
   360 	return err;
       
   361 	}
       
   362 
       
   363 
       
   364 void TFileDetails::ExternalizeL(RWriteStream& aStream)
       
   365 	{
       
   366 	aStream.WriteUint8L(iState);
       
   367 	aStream.WriteUint32L(iPath.Length());
       
   368 	aStream.WriteL(iPath);
       
   369 	aStream.WriteUint32L(iTempPath.Length());
       
   370 	aStream.WriteL(iTempPath);
       
   371 	}
       
   372 
       
   373 void TFileDetails::ExternalizeContinuationL(RWriteStream& aStream, TInt aTag)
       
   374 	{
       
   375 	aStream.WriteInt8L(CApsNonNativeApplicationsUpdate::EContinuationOfUpdate);
       
   376 	aStream.WriteInt8L(aTag);
       
   377 	ExternalizeL(aStream);
       
   378 	aStream.CommitL(); // beta stopping point
       
   379 	}
       
   380 
       
   381 TInt TFileDetails::ExternalizeContinuation(RWriteStream& aStream, TInt aTag)
       
   382 	{
       
   383 	TRAPD(err,ExternalizeContinuationL(aStream,aTag));
       
   384 	return err;
       
   385 	}
       
   386 
       
   387 void TFileDetails::InternalizeL(RReadStream& aStream, TInt& aPosition)
       
   388 	{
       
   389 	TState state = static_cast<TState>(aStream.ReadUint8L());
       
   390 	TUint pathLen = aStream.ReadUint32L();
       
   391 	if(pathLen > KMaxFileName)
       
   392 		{
       
   393 		User::Leave(KErrCorrupt);
       
   394 		}
       
   395 	TFileName path;
       
   396 	aStream.ReadL(path, pathLen);
       
   397 	TUint tempPathLen = aStream.ReadUint32L();
       
   398 	if(tempPathLen > KMaxFileName)
       
   399 		{
       
   400 		User::Leave(KErrCorrupt);
       
   401 		}
       
   402 	TFileName tempPath;
       
   403 	aStream.ReadL(tempPath, tempPathLen);
       
   404 
       
   405 	/* all dangerous operations are now out of the way */
       
   406 	iState = state;
       
   407 	iPath = path;
       
   408 	iTempPath = tempPath;
       
   409 	// state, length, path, length, temppath
       
   410 	aPosition += sizeof(TUint8) +  sizeof(TUint32) + (pathLen * sizeof(TText)) +  sizeof(TUint32) + (tempPathLen * sizeof(TText));
       
   411 	}
       
   412 
       
   413 /*
       
   414 Works out what file we had a handle on when the log was written, and try to regain it.
       
   415 */	
       
   416 void TFileDetails::PostInternalizeL(RFs& aFs)
       
   417 	{
       
   418 	TInt err;
       
   419 	switch(iState)
       
   420 		{
       
   421 	case EStateNull:
       
   422 		if(iTempPath != KNullDesC)
       
   423 			{
       
   424 			User::Leave(KErrCorrupt);
       
   425 			}
       
   426 		break;
       
   427 	case EStateTemporary:
       
   428 		if(iTempPath == KNullDesC)
       
   429 			{
       
   430 			User::Leave(KErrCorrupt);
       
   431 			}
       
   432 		err = iHandle.Open(aFs, iTempPath, EFileShareExclusive|EFileStream|EFileWrite);
       
   433 		if(err == KErrNotFound || err == KErrPathNotFound)
       
   434 			{
       
   435 			iTempPath.Zero();
       
   436 			iPath.Zero();
       
   437 			iState = EStateNull;
       
   438 			}
       
   439 		else 
       
   440 			{
       
   441 			User::LeaveIfError(err);
       
   442 			}
       
   443 		break;
       
   444 	case EStateReal:
       
   445 		if(iPath == KNullDesC)
       
   446 			{
       
   447 			User::Leave(KErrCorrupt);
       
   448 			}
       
   449 		err = iHandle.Open(aFs, iPath, EFileShareExclusive|EFileStream|EFileWrite);
       
   450 		if(err == KErrNotFound || err == KErrPathNotFound)
       
   451 			{
       
   452 			iTempPath.Zero();
       
   453 			iPath.Zero();
       
   454 			iState = EStateNull;
       
   455 			}
       
   456 		else 
       
   457 			{
       
   458 			User::LeaveIfError(err);
       
   459 			}
       
   460 		break;
       
   461 	default:
       
   462 		User::Leave(KErrCorrupt);
       
   463 		break;
       
   464 		}
       
   465 	}
       
   466 
       
   467 /**************************************************************************************************************
       
   468  * CApsNonNativeApplicationsUpdate
       
   469  **************************************************************************************************************/
       
   470 
       
   471 CApsNonNativeApplicationsUpdate::CApsNonNativeApplicationsUpdate(RFs& aFs, TUid aUid, TState aState, TLogUpdateType aType) :
       
   472 		iState(aState),
       
   473 		iFs(aFs),
       
   474 		iType(aType),
       
   475 		iUid(aUid)
       
   476 	{
       
   477 	}
       
   478 
       
   479 CApsNonNativeApplicationsUpdate::~CApsNonNativeApplicationsUpdate()
       
   480 	{
       
   481 	}
       
   482 
       
   483 CApsNonNativeApplicationsUpdate* CApsNonNativeApplicationsUpdate::Previous() const
       
   484 	{
       
   485 	return iPrevious;
       
   486 	}
       
   487 
       
   488 CApsNonNativeApplicationsUpdate* CApsNonNativeApplicationsUpdate::Next() const
       
   489 	{
       
   490 	return iNext;
       
   491 	}
       
   492 
       
   493 TUid CApsNonNativeApplicationsUpdate::Uid() 
       
   494 	{
       
   495 	return iUid;
       
   496 	}
       
   497 
       
   498 void CApsNonNativeApplicationsUpdate::PerformUpdateL(RApsUpdateLog& aUpdateLog)
       
   499 	{
       
   500 	ASSERT(iState == ENew);
       
   501 	RWriteStream& stream = aUpdateLog.LogWriteStream();
       
   502 
       
   503 	/* NewUpdateSection */
       
   504 	stream.WriteInt8L(ENewUpdate);
       
   505 	stream.WriteInt8L(iType);
       
   506 	stream.WriteInt32L(iUid.iUid);
       
   507 	ExternalizeL(stream);
       
   508 	stream.CommitL(); // alpha stopping point
       
   509 
       
   510 	/* PerformUpdateSection */
       
   511 	stream.WriteInt8L(EPerformUpdate);
       
   512 	stream.WriteInt8L(iType);
       
   513 	stream.WriteInt32L(iUid.iUid);     // beta stopping points
       
   514 	StateChangeL(EPerforming, stream); // ...
       
   515 	DoPerformUpdateL(aUpdateLog);      // ...
       
   516 	StateChangeL(EPerformed, stream);  // ...
       
   517 	stream.WriteInt8L(EEndOfUpdate);
       
   518 	stream.CommitL();                  // alpha stopping point
       
   519 	}
       
   520 
       
   521 void CApsNonNativeApplicationsUpdate::RollbackUpdateL(RApsUpdateLog& aUpdateLog)
       
   522 	{
       
   523 	ASSERT(iState == EPerforming || iState == EPerformed || iState == ERollingBack);
       
   524 	RWriteStream& stream = aUpdateLog.LogWriteStream();
       
   525 	stream.WriteInt8L(ERollbackUpdate);
       
   526 	stream.WriteInt8L(iType);
       
   527 	stream.WriteInt32L(iUid.iUid);
       
   528 	stream.CommitL();                   // beta stopping point
       
   529  	// even if we're already in ERollingBack because we crashed and are reattempting it,
       
   530  	// it's harmless to write a duplicate statechange to the log
       
   531 	StateChangeL(ERollingBack, stream); // beta stopping points
       
   532 	DoRollbackUpdate(aUpdateLog);       // ...
       
   533 	StateChangeL(ERolledBack, stream);  // ...
       
   534 	stream.WriteInt8L(EEndOfUpdate);
       
   535 	stream.CommitL();                   // alpha stopping point
       
   536 	}
       
   537 
       
   538 TFileName CApsNonNativeApplicationsUpdate::TemporaryFilePathL(TDriveName& aDrive)
       
   539 	{
       
   540 	TFileName dir(aDrive);
       
   541 	
       
   542 	// this is safe since KMaxFileName >= (KMaxDriveName + length(KLitPathForTemporaryNonNativeResourceAndIconFiles))
       
   543 	dir.Append(KLitPathForTemporaryNonNativeResourceAndIconFiles);
       
   544 
       
   545 	if(!BaflUtils::FolderExists(iFs,dir)) 
       
   546 		{
       
   547 		User::LeaveIfError(iFs.MkDirAll(dir));
       
   548 		}	
       
   549 	return dir;
       
   550 	}
       
   551 
       
   552 void CApsNonNativeApplicationsUpdate::StateChangeL(TState aState, RWriteStream& aStream)
       
   553 	{
       
   554 	iState = aState;
       
   555 	aStream.WriteInt8L(EChangeOfUpdateState);
       
   556 	aStream.WriteInt8L(iState);
       
   557 	aStream.CommitL(); // beta stopping point
       
   558 	}
       
   559 
       
   560 void CApsNonNativeApplicationsUpdate::InternalizeStateChangeL(RReadStream& aStream, TInt& aPosition)
       
   561 	{
       
   562 	TState state = static_cast<TState>(aStream.ReadInt8L());
       
   563 	++aPosition;
       
   564 	iState = state;
       
   565 	}
       
   566 
       
   567 void CApsNonNativeApplicationsUpdate::InternalizeNewUpdateL(RReadStream& aStream, TInt& aPosition)
       
   568 	{
       
   569 	__ASSERT_DEBUG(iState == ENeedsInternalizing, Panic(ENonNativeAppsNonNativeApplicationsUpdateInternalizeNewUpdateInBadState));
       
   570 	/*
       
   571 	internalize all member variables to how they were before any updates were performed.
       
   572 	*/
       
   573 	InternalizeL(aStream, aPosition);
       
   574 	
       
   575 	iState = ENew; /* the update is now OK to add to the list */
       
   576 	}
       
   577 
       
   578 void CApsNonNativeApplicationsUpdate::InternalizePerformUpdateL(RReadStream& aStream, TInt& aPosition)
       
   579 	{
       
   580 	/*
       
   581 	internalize any state changes and update-specific continuations, until EEndOfUpdate
       
   582 	*/
       
   583 	SharedInternalizeLoopL(aStream, aPosition);
       
   584 	}
       
   585 
       
   586 void CApsNonNativeApplicationsUpdate::InternalizeRollbackUpdateL(RReadStream& aStream, TInt& aPosition)
       
   587 	{
       
   588 	/*
       
   589 	internalize any state changes and update-specific continuations, until EEndOfUpdate
       
   590 	*/
       
   591 	SharedInternalizeLoopL(aStream, aPosition);
       
   592 	}
       
   593 
       
   594 void CApsNonNativeApplicationsUpdate::SharedInternalizeLoopL(RReadStream& aStream, TInt& aPosition)
       
   595 	{
       
   596 	while (ETrue)
       
   597 		{
       
   598 		TInt pos = aPosition;
       
   599 		TLogActionType action = static_cast<TLogActionType>(aStream.ReadInt8L());
       
   600 		pos += sizeof(TInt8);
       
   601 		/* we are at a beta stopping point at the start of each loop iteration,
       
   602 		   so don't update aPosition until we have reached the end of the loop.
       
   603 		   give the funcitons a copy to stop them updating aPosition direclty and
       
   604 		   then leaving */
       
   605 		switch(action)
       
   606 			{
       
   607 		case EChangeOfUpdateState:
       
   608 			InternalizeStateChangeL(aStream, pos);
       
   609 			break;
       
   610 		case EContinuationOfUpdate:
       
   611 			InternalizeUpdateContinuationL(aStream, pos);
       
   612 			break;
       
   613 		case EEndOfUpdate:
       
   614 			aPosition = pos;
       
   615 			return;
       
   616 		default:
       
   617 			User::Leave(KErrCorrupt);
       
   618 			break;
       
   619 			}
       
   620 		aPosition = pos;
       
   621 		}
       
   622 	}
       
   623 
       
   624 /*
       
   625  Default implemenation of a virtual function. does nothing.
       
   626 
       
   627  In this method, subclasses should write out all important, subclass-specific data.
       
   628  It will be called before DoPerformUpdateL.
       
   629  */
       
   630 void CApsNonNativeApplicationsUpdate::ExternalizeL(RWriteStream& /*aStream*/)
       
   631 	{
       
   632 	}
       
   633 
       
   634 /*
       
   635  Default implemenation of a virtual function. does nothing.
       
   636 
       
   637  In this method, subclasses read in any subclass-specific data that was written out
       
   638  by ExternalizeL().
       
   639  */
       
   640 void CApsNonNativeApplicationsUpdate::InternalizeL(RReadStream& /*aStream*/, TInt& /*aPosition*/)
       
   641 	{
       
   642 	}
       
   643 
       
   644 /*
       
   645  Default implemenation of a virtual function. does nothing.
       
   646 
       
   647  In this method, subclasses should handle any EContinuationOfUpdate messages that
       
   648  they might have written to the log during DoPerformUpdateL or DoRollbackUpdate
       
   649  */
       
   650 void CApsNonNativeApplicationsUpdate::InternalizeUpdateContinuationL(RReadStream& /*aStream*/, TInt& /*aPosition*/)
       
   651 	{
       
   652 	}
       
   653 
       
   654 /*
       
   655  Default implemenation of a virtual function. does nothing.
       
   656 
       
   657  In this method, subclasses should do any internal initialization that is dependent on
       
   658  data that may be changed by InternalizeUpdateContinuationL().
       
   659  
       
   660  InternalizeUpdateContinuationL() may be called many times over and its implementation
       
   661  may change the same member variable many times.
       
   662  This function will only be called once, and it will be called after the entire log has
       
   663  been read and InternalizeUpdateContinuationL() has been called for the last time.
       
   664  */
       
   665 void CApsNonNativeApplicationsUpdate::PostInternalizeL()
       
   666 	{
       
   667 	}
       
   668 
       
   669 /**************************************************************************************************************
       
   670  * CApsRegisterNonNativeApplication
       
   671  **************************************************************************************************************/
       
   672 
       
   673 CApsRegisterNonNativeApplication* CApsRegisterNonNativeApplication::NewL(RFs& aFs, TUid aUid, const TDriveName& aDrive, TState aState)
       
   674 	{
       
   675 	return new(ELeave) CApsRegisterNonNativeApplication(aFs, aUid, aDrive, aState);
       
   676 	}
       
   677 
       
   678 CApsRegisterNonNativeApplication::CApsRegisterNonNativeApplication(RFs& aFs, TUid aUid, const TDriveName& aDrive, TState aState) :
       
   679 		CApsNonNativeApplicationsUpdate(aFs, aUid, aState, ERegisterApplication),
       
   680 		iDrive(aDrive)
       
   681 	{
       
   682 	}
       
   683 
       
   684 void CApsRegisterNonNativeApplication::SetResourceFileTargetLocation(const TDesC& aLocation)
       
   685 	{
       
   686 	iResourceFile.SetPath(aLocation);
       
   687 	}
       
   688 
       
   689 void CApsRegisterNonNativeApplication::SetLocalisableResourceFileTargetLocation(const TDesC& aLocation)
       
   690 	{
       
   691 	iLocalisableResourceFile.SetPath(aLocation);
       
   692 	}
       
   693 
       
   694 void CApsRegisterNonNativeApplication::SetIconFileTargetLocation(const TDesC& aLocation)
       
   695 	{
       
   696 	iIconFile.SetPath(aLocation);
       
   697 	}
       
   698 
       
   699 void CApsRegisterNonNativeApplication::WriteResourceFileL(const TDesC8& aData, const TDesC8* aDataPrefix) 
       
   700 	{
       
   701 	WriteResourceFileL(iResourceFile, aData, aDataPrefix);
       
   702 	}
       
   703 
       
   704 void CApsRegisterNonNativeApplication::WriteLocalisableResourceFileL(const TDesC8& aData, const TDesC8* aDataPrefix)
       
   705 	{
       
   706 	WriteResourceFileL(iLocalisableResourceFile, aData, aDataPrefix);
       
   707 	}
       
   708 
       
   709 //
       
   710 
       
   711 /**
       
   712 Create a new file in a designated temporary-files directory
       
   713 */
       
   714 void CApsRegisterNonNativeApplication::NewTemporaryFileL(TFileDetails& aFile)
       
   715 	{
       
   716 	TFileName path(TemporaryFilePathL(iDrive));
       
   717 	aFile.CreateTemporaryL(iFs,path);
       
   718 	}
       
   719 
       
   720 /**
       
   721 Writes a resource file to a new temporary file
       
   722  */
       
   723 void CApsRegisterNonNativeApplication::WriteResourceFileL(TFileDetails& aFile, const TDesC8& aData, const TDesC8* aDataPrefix)
       
   724 	{
       
   725 	// create temp file, put stuff on the cleanup stack
       
   726 	NewTemporaryFileL(aFile);
       
   727 	RFileWriteStream targetStream;
       
   728 	CleanupClosePushL(targetStream);
       
   729 
       
   730 	// the stream takes ownership of the file handle and closes it, so make a copy
       
   731 	RFile targetFile;
       
   732 	aFile.GetDuplicateHandleL(targetFile);
       
   733 	targetStream.Attach(targetFile); // will take ownership of the handle and set targetFile to a Null handle
       
   734 
       
   735 	if (aDataPrefix!=NULL)
       
   736 		{
       
   737 		targetStream.WriteL(*aDataPrefix);
       
   738 		}
       
   739 	targetStream.WriteL(aData);
       
   740 	targetStream.CommitL();
       
   741 
       
   742 	CleanupStack::PopAndDestroy(&targetStream);
       
   743 	}
       
   744 
       
   745 /**
       
   746 This function will copy the file provided to a new temporary file.
       
   747 Upon success or failure, the read/write position of aSourceFile should remain unchanged.
       
   748  */
       
   749 void CApsRegisterNonNativeApplication::CopyIconFileL(RFile& aSourceFile)
       
   750 	{
       
   751 	NewTemporaryFileL(iIconFile);
       
   752 
       
   753 	// RFile*Stream::Attach will take ownership of the handle we give it, but we want to hold
       
   754 	// on to the handles we have. To achieve this, we give Attach a copy of the file handle,
       
   755 	// for both streams.
       
   756 	RFileWriteStream targetStream;
       
   757 	CleanupClosePushL(targetStream);
       
   758 	RFile targetFile;
       
   759 	iIconFile.GetDuplicateHandleL(targetFile);
       
   760 	targetStream.Attach(targetFile);
       
   761 
       
   762 	// rewind to start, but restore original position if a leave occurs
       
   763 	TFilePositionReset filePositionReset(aSourceFile);
       
   764 	filePositionReset.RewindToStartLC();
       
   765 
       
   766 	RFileReadStream sourceStream;
       
   767 	CleanupClosePushL(sourceStream);
       
   768 	RFile sourceFile;
       
   769 	User::LeaveIfError(sourceFile.Duplicate(aSourceFile));
       
   770 	sourceStream.Attach(sourceFile);
       
   771 
       
   772 	targetStream.WriteL(sourceStream);
       
   773 	targetStream.CommitL();
       
   774 	CleanupStack::PopAndDestroy(&sourceStream);
       
   775 
       
   776 	// perform these seperately so we can leave if Reset fails
       
   777 	CleanupStack::Pop(&filePositionReset);
       
   778 	User::LeaveIfError(filePositionReset.Reset());
       
   779 
       
   780 	CleanupStack::PopAndDestroy(&targetStream);
       
   781 	}
       
   782 
       
   783 void CApsRegisterNonNativeApplication::DoPerformUpdateL(RApsUpdateLog& aUpdateLog)
       
   784 	{
       
   785 	TRAPD(err,aUpdateLog.DrivesAffected().InsertIsqL(iDrive, ECmpFolded));
       
   786 	if (err != KErrAlreadyExists) // We silently ignore attempts to insert duplicates
       
   787 		User::LeaveIfError(err);
       
   788 	
       
   789 	RWriteStream& stream = aUpdateLog.LogWriteStream();
       
   790 
       
   791 	iResourceFile.RenameToRealL(iFs);
       
   792 
       
   793 	/* make a note of what's changed */
       
   794 	iResourceFile.ExternalizeContinuationL(stream, EResourceFileUpdate);
       
   795 
       
   796 	if(iLocalisableResourceFile.Exists()) 
       
   797 		{
       
   798 		iLocalisableResourceFile.RenameToRealL(iFs);
       
   799 		iResourceFile.ExternalizeContinuationL(stream, ELocalisableResourceFileUpdate);
       
   800 		}
       
   801 
       
   802 	if(iIconFile.Exists())
       
   803 		{
       
   804 		iIconFile.RenameToRealL(iFs);
       
   805 		iResourceFile.ExternalizeContinuationL(stream, EIconFileUpdate);
       
   806 		}
       
   807 	
       
   808 	TRAP(err,aUpdateLog.NewRegistrationFiles().InsertIsqL(iResourceFile.Path(), ECmpFolded));
       
   809 	if (err != KErrAlreadyExists) // We silently ignore attempts to insert duplicates
       
   810 		User::LeaveIfError(err);
       
   811 	}
       
   812 
       
   813 void CApsRegisterNonNativeApplication::DoRollbackUpdate(RApsUpdateLog& aUpdateLog)
       
   814 	{
       
   815 	RWriteStream& stream = aUpdateLog.LogWriteStream();
       
   816 
       
   817 	/* TFileDetails::Delete() is safe to call whatever state the object is in.
       
   818 
       
   819 	   if it was never opened, it'll do nothing, otherwise it'll delete whichever
       
   820 	   file (real/temp) it has a handle on.
       
   821 	
       
   822 	   ignore the return codes since we can't do anything about it if they fail */
       
   823 	iResourceFile.Delete(iFs);
       
   824 	iResourceFile.ExternalizeContinuation(stream, EResourceFileUpdate);
       
   825 
       
   826 	iLocalisableResourceFile.Delete(iFs);
       
   827 	iResourceFile.ExternalizeContinuation(stream, ELocalisableResourceFileUpdate);
       
   828 
       
   829 	iIconFile.Delete(iFs);
       
   830 	iResourceFile.ExternalizeContinuation(stream, EIconFileUpdate);
       
   831 	}
       
   832 
       
   833 
       
   834 //
       
   835 
       
   836 void CApsRegisterNonNativeApplication::ExternalizeL(RWriteStream& aStream)
       
   837 	{
       
   838 	/* write our initial state to the log stream */
       
   839 	aStream.WriteUint32L(iDrive.Length());
       
   840 	aStream.WriteL(iDrive);
       
   841 	iResourceFile.ExternalizeL(aStream);
       
   842 	iLocalisableResourceFile.ExternalizeL(aStream);
       
   843 	iIconFile.ExternalizeL(aStream);
       
   844 	}
       
   845 
       
   846 void CApsRegisterNonNativeApplication::InternalizeL(RReadStream& aStream, TInt& aPosition)
       
   847 	{
       
   848 	// we can update aPosition whenever we like in this function since we're protected
       
   849 	// from it being left at a bad value by the copy taken by CApsNonNativeApplicationsUpdateList::InternalizeActionL
       
   850 	TUint driveLen = aStream.ReadUint32L();
       
   851 	aPosition += sizeof(TUint32);
       
   852 	if(driveLen > KMaxDriveName)
       
   853 		{
       
   854 		User::Leave(KErrCorrupt);
       
   855 		}
       
   856 	iDrive.Zero();
       
   857 	aStream.ReadL(iDrive, driveLen);
       
   858 	aPosition += driveLen * sizeof(TText);
       
   859 
       
   860 	iResourceFile.InternalizeL(aStream, aPosition);
       
   861 	iLocalisableResourceFile.InternalizeL(aStream, aPosition);
       
   862 	iIconFile.InternalizeL(aStream, aPosition);
       
   863 	}
       
   864 	
       
   865 void CApsRegisterNonNativeApplication::InternalizeUpdateContinuationL(RReadStream& aStream, TInt& aPosition)
       
   866 	{
       
   867 	// we can update aPosition whenever we like in this function since we're protected
       
   868 	// from it being left at a bad value by the copy taken by CApsNonNativeApplicationsUpdate::SharedInternalizeLoopL
       
   869 
       
   870 	TLogContinuationType type = static_cast<TLogContinuationType>(aStream.ReadInt8L());
       
   871 	aPosition += sizeof(TInt8);
       
   872 
       
   873 	switch(type)
       
   874 		{
       
   875 	case EResourceFileUpdate:
       
   876 		iResourceFile.InternalizeL(aStream, aPosition);
       
   877 		break;
       
   878 	case ELocalisableResourceFileUpdate:
       
   879 		iLocalisableResourceFile.InternalizeL(aStream, aPosition);
       
   880 		break;
       
   881 	case EIconFileUpdate:
       
   882 		iIconFile.InternalizeL(aStream, aPosition);
       
   883 		break;
       
   884 	default:
       
   885 		User::Leave(KErrCorrupt);
       
   886 		break;
       
   887 		}
       
   888 	}
       
   889 
       
   890 void CApsRegisterNonNativeApplication::PostInternalizeL()
       
   891 	{
       
   892 	iResourceFile.PostInternalizeL(iFs);
       
   893 	iLocalisableResourceFile.PostInternalizeL(iFs);
       
   894 	iIconFile.PostInternalizeL(iFs);
       
   895 	}
       
   896 	
       
   897 CApsRegisterNonNativeApplication::~CApsRegisterNonNativeApplication()
       
   898 	{
       
   899 	/*
       
   900 	if we performed the update successfully, just close the handles and leave
       
   901 	the reg files in place.
       
   902 
       
   903 	in all other cases, just delete everything that still exists
       
   904 	 */
       
   905 	if(iState == EPerformed) 
       
   906 		{
       
   907 		iResourceFile.CloseHandle();
       
   908 		iLocalisableResourceFile.CloseHandle();
       
   909 		iIconFile.CloseHandle();
       
   910 		}
       
   911 	else
       
   912 		{
       
   913 		iResourceFile.Delete(iFs);
       
   914 		iLocalisableResourceFile.Delete(iFs);
       
   915 		iIconFile.Delete(iFs);
       
   916 		}
       
   917 	}
       
   918 
       
   919 
       
   920 /**************************************************************************************************************
       
   921  * CApsDeregisterNonNativeApplication
       
   922  **************************************************************************************************************/
       
   923 
       
   924 CApsDeregisterNonNativeApplication* CApsDeregisterNonNativeApplication::NewL(RFs& aFs, CApaAppArcServer& aServ, TUid aUid, TState aState)
       
   925 	{
       
   926 	return new(ELeave)CApsDeregisterNonNativeApplication(aFs, aServ, aUid, aState);
       
   927 	}
       
   928 
       
   929 CApsDeregisterNonNativeApplication::CApsDeregisterNonNativeApplication(RFs& aFs, CApaAppArcServer& aServ, TUid aUid, TState aState) :
       
   930 		CApsNonNativeApplicationsUpdate(aFs, aUid, aState, EDeregisterApplication),
       
   931 		iServ(aServ)
       
   932 	{
       
   933 	}
       
   934 
       
   935 //
       
   936 
       
   937 
       
   938 CApaAppData* CApsDeregisterNonNativeApplication::FindAppDataLC(RApsUpdateLog& aUpdateLog)
       
   939 	{
       
   940 	/* search back through the list for a an update concerning the same Uid */
       
   941 	CApsNonNativeApplicationsUpdate* prev = Previous();
       
   942 	while(prev != NULL)
       
   943 		{
       
   944 		if(prev->Uid() == Uid())
       
   945 			break;
       
   946 		prev = prev->Previous();
       
   947 		}
       
   948 
       
   949 	/* if none found, use apparc's app list as a shortcut */
       
   950 	CApaAppData* appData = NULL;
       
   951 	if(prev == NULL)
       
   952 		{
       
   953 		appData = iServ.AppList().AppDataByUid(Uid());
       
   954 
       
   955 		if(appData != NULL) 
       
   956 			{
       
   957 			// create a new AppData so we can put it on the cleanup stack.
       
   958 			// if the NewL fails for whatever reson, fall back to the search code below
       
   959 
       
   960 			// this is a bit tricky because we need to create the appdata from a
       
   961 			// TApaAppEntry for the reg file, but using appData->AppEntry() will give us
       
   962 			// one for the dll.
       
   963 			TApaAppEntry entry;
       
   964 			entry.iFullName = appData->RegistrationFileName();
       
   965 			TEntry fsEntry;
       
   966 
       
   967 			User::LeaveIfError(iFs.Entry(entry.iFullName,fsEntry));
       
   968 			entry.iUidType = fsEntry.iType;
       
   969 
       
   970 			appData = NULL;
       
   971 			TRAP_IGNORE(appData = CApaAppData::NewL(entry,iFs));
       
   972 			if(appData != NULL)
       
   973 				{
       
   974 				CleanupStack::PushL(appData);
       
   975 				return appData;
       
   976 				}
       
   977 			}
       
   978 		}
       
   979 
       
   980 	/*
       
   981 	 * If the appData wasn't found or we can't trust the app list because of previous updates,
       
   982 	 * attempt to find and load the appData manually
       
   983 	 */
       
   984 	CApaAppRegFinder* regFinder = CApaAppRegFinder::NewLC(iFs);
       
   985 	TBool found = EFalse;
       
   986 	TApaAppEntry appEntry;
       
   987 
       
   988 	regFinder->FindAllAppsL(CApaAppRegFinder::EScanAllDrives);
       
   989 	const CDesCArray& forcedRegs = aUpdateLog.NewRegistrationFiles();
       
   990 
       
   991 	while(regFinder->NextL(appEntry, forcedRegs))
       
   992 		{
       
   993 		if (appEntry.iUidType[2] == Uid())
       
   994 			{
       
   995 			found = ETrue;
       
   996 			break;
       
   997 			}
       
   998 		}
       
   999 	CleanupStack::PopAndDestroy(regFinder);
       
  1000 
       
  1001 	if(found)
       
  1002 		{
       
  1003 		appData = CApaAppData::NewL(appEntry, iFs);
       
  1004 		CleanupStack::PushL(appData);
       
  1005 		return appData;
       
  1006 		}
       
  1007 
       
  1008 	CleanupStack::PushL(static_cast<CApaAppData*>(NULL));
       
  1009 	return NULL;
       
  1010 	}
       
  1011 		
       
  1012 void CApsDeregisterNonNativeApplication::RenameToTemporaryL(TFileDetails& aFile, RApsUpdateLog& aUpdateLog)
       
  1013 	{
       
  1014 	/* get the drive */
       
  1015 	TParse parse;
       
  1016 	parse.SetNoWild(aFile.Path(), NULL, NULL);
       
  1017 	if(!parse.DrivePresent())
       
  1018 		{
       
  1019 		// should really never happen
       
  1020 		User::Leave(KErrPathNotFound);
       
  1021 		}
       
  1022 	TDriveName drive(parse.Drive());
       
  1023 	TRAPD(err, aUpdateLog.DrivesAffected().InsertIsqL(drive, ECmpFolded));
       
  1024 	if (err != KErrAlreadyExists) // We silently ignore attempts to insert duplicates
       
  1025 		User::LeaveIfError(err);
       
  1026 
       
  1027 	const TFileName path(TemporaryFilePathL(drive));
       
  1028 	aFile.RenameToTemporaryL(iFs, path);
       
  1029 	}
       
  1030 
       
  1031 void CApsDeregisterNonNativeApplication::DoPerformUpdateL(RApsUpdateLog& aUpdateLog)
       
  1032 	{
       
  1033 	CApaAppData* appData = FindAppDataLC(aUpdateLog);
       
  1034 	if(appData == NULL)
       
  1035 		{
       
  1036 		/*
       
  1037 		 * App not found.
       
  1038 		 * Behavioural backwards compatibility says we shouldn't raise an error here,
       
  1039 		 * instead just let it go and carry on.
       
  1040 		 */
       
  1041 		CleanupStack::Pop(appData);
       
  1042 		return;
       
  1043 		}
       
  1044 
       
  1045 	/*
       
  1046 	 for each of the 3 files, open a handle on the real file if it exists
       
  1047 	 the first one (iResourceFile) is mandatory
       
  1048 	 */
       
  1049 	TRAPD(err,iResourceFile.OpenL(iFs, appData->RegistrationFileName()));
       
  1050 	if(err != KErrNone && err != KErrNotFound)
       
  1051 		{
       
  1052 		User::Leave(err);
       
  1053 		}
       
  1054 
       
  1055 	if(appData->LocalisableResourceFileName() != KNullDesC)
       
  1056 		{
       
  1057 		TRAP(err,iLocalisableResourceFile.OpenL(iFs, appData->LocalisableResourceFileName()));
       
  1058 		if(err != KErrNone && err != KErrNotFound)
       
  1059 			{
       
  1060 			User::Leave(err);
       
  1061 			}
       
  1062 		}
       
  1063 
       
  1064 	if(appData->IconFileName() != KNullDesC)
       
  1065 		{
       
  1066 		TRAP(err,iIconFile.OpenL(iFs, appData->IconFileName()));
       
  1067 		if(err != KErrNone && err != KErrNotFound)
       
  1068 			{
       
  1069 			User::Leave(err);
       
  1070 			}
       
  1071 		}
       
  1072 
       
  1073 	CleanupStack::PopAndDestroy(appData);
       
  1074 
       
  1075 	/*
       
  1076 	 perform the actual updates
       
  1077 	 */
       
  1078 	RWriteStream& stream = aUpdateLog.LogWriteStream();
       
  1079 
       
  1080 	if(iIconFile.Exists())
       
  1081 		{
       
  1082 		RenameToTemporaryL(iIconFile, aUpdateLog);
       
  1083 		iIconFile.ExternalizeContinuationL(stream, EIconFileUpdate);
       
  1084 		}
       
  1085 	
       
  1086 	if(iLocalisableResourceFile.Exists())
       
  1087 		{
       
  1088 		RenameToTemporaryL(iLocalisableResourceFile, aUpdateLog);
       
  1089 		iLocalisableResourceFile.ExternalizeContinuationL(stream, ELocalisableResourceFileUpdate);
       
  1090 		}
       
  1091 
       
  1092 	RenameToTemporaryL(iResourceFile, aUpdateLog);
       
  1093 	iResourceFile.ExternalizeContinuationL(stream, EResourceFileUpdate);
       
  1094 	}
       
  1095 
       
  1096 void CApsDeregisterNonNativeApplication::DoRollbackUpdate(RApsUpdateLog& aUpdateLog)
       
  1097 	{
       
  1098 	RWriteStream& stream = aUpdateLog.LogWriteStream();
       
  1099 
       
  1100 	iResourceFile.RestoreReal(iFs);
       
  1101 	iResourceFile.ExternalizeContinuation(stream, EResourceFileUpdate);
       
  1102 
       
  1103 	iLocalisableResourceFile.RestoreReal(iFs);
       
  1104 	iLocalisableResourceFile.ExternalizeContinuation(stream, ELocalisableResourceFileUpdate);
       
  1105 	
       
  1106 	iIconFile.RestoreReal(iFs);
       
  1107 	iIconFile.ExternalizeContinuation(stream, EIconFileUpdate);
       
  1108 	}
       
  1109 
       
  1110 void CApsDeregisterNonNativeApplication::ExternalizeL(RWriteStream& aStream)
       
  1111 	{
       
  1112 	iResourceFile.ExternalizeL(aStream);
       
  1113 	iLocalisableResourceFile.ExternalizeL(aStream);
       
  1114 	iIconFile.ExternalizeL(aStream);
       
  1115 	}
       
  1116 
       
  1117 void CApsDeregisterNonNativeApplication::InternalizeL(RReadStream& aStream, TInt& aPosition)
       
  1118 	{
       
  1119 	// we can update aPosition whenever we like in this function since we're protected
       
  1120 	// from it being left at a bad value by the copy taken by CApsNonNativeApplicationsUpdateList::InternalizeActionL
       
  1121 	iResourceFile.InternalizeL(aStream, aPosition);
       
  1122 	iLocalisableResourceFile.InternalizeL(aStream, aPosition);
       
  1123 	iIconFile.InternalizeL(aStream, aPosition);
       
  1124 	}
       
  1125 
       
  1126 void CApsDeregisterNonNativeApplication::InternalizeUpdateContinuationL(RReadStream& aStream, TInt& aPosition)
       
  1127 	{
       
  1128 	// we can update aPosition whenever we like in this function since we're protected
       
  1129 	// from it being left at a bad value by the copy taken by CApsNonNativeApplicationsUpdate::SharedInternalizeLoopL
       
  1130 
       
  1131 	TLogContinuationType type = static_cast<TLogContinuationType>(aStream.ReadInt8L());
       
  1132 	aPosition += sizeof(TInt8);
       
  1133 
       
  1134 	switch(type)
       
  1135 		{
       
  1136 	case EResourceFileUpdate:
       
  1137 		iResourceFile.InternalizeL(aStream, aPosition);
       
  1138 		break;
       
  1139 	case ELocalisableResourceFileUpdate:
       
  1140 		iLocalisableResourceFile.InternalizeL(aStream, aPosition);
       
  1141 		break;
       
  1142 	case EIconFileUpdate:
       
  1143 		iIconFile.InternalizeL(aStream, aPosition);
       
  1144 		break;
       
  1145 	default:
       
  1146 		User::Leave(KErrCorrupt);
       
  1147 		break;
       
  1148 		}
       
  1149 	}
       
  1150 
       
  1151 void CApsDeregisterNonNativeApplication::PostInternalizeL()
       
  1152 	{
       
  1153 	iResourceFile.PostInternalizeL(iFs);
       
  1154 	iLocalisableResourceFile.PostInternalizeL(iFs);
       
  1155 	iIconFile.PostInternalizeL(iFs);
       
  1156 	}
       
  1157 
       
  1158 CApsDeregisterNonNativeApplication::~CApsDeregisterNonNativeApplication()
       
  1159 	{
       
  1160 	/*
       
  1161 	if we performed the update successfully, we need to delete the temporary
       
  1162 
       
  1163 	in all other cases, just delete everything that still exists
       
  1164 	 */
       
  1165 	if(iState == EPerformed) 
       
  1166 		{
       
  1167 		// in this state we know that Perform has completed successfully.
       
  1168 		iResourceFile.DeleteTemporary(iFs);
       
  1169 		iLocalisableResourceFile.DeleteTemporary(iFs);
       
  1170 		iIconFile.DeleteTemporary(iFs);
       
  1171 		}
       
  1172 	else
       
  1173 		{
       
  1174 		// Hopefully these are now (back) in their target locations.
       
  1175 		// if they're not, there's nothing we can do now, so abandon them either way
       
  1176 		iResourceFile.CloseHandle();
       
  1177 		iLocalisableResourceFile.CloseHandle();
       
  1178 		iIconFile.CloseHandle();
       
  1179 		}
       
  1180 	}
       
  1181 
       
  1182 #ifdef _DEBUG
       
  1183 /**************************************************************************************************************
       
  1184  * CApsAlwaysFailUpdate
       
  1185  **************************************************************************************************************/
       
  1186 
       
  1187 CApsAlwaysFailUpdate::CApsAlwaysFailUpdate(RFs& aFs, TState aState) :
       
  1188 		CApsNonNativeApplicationsUpdate(aFs,TUid::Uid(0xDEADBEEF),aState,EFail)
       
  1189 	{
       
  1190 	}
       
  1191 
       
  1192 void CApsAlwaysFailUpdate::DoPerformUpdateL(RApsUpdateLog& /*aUpdateLog*/)
       
  1193 	{
       
  1194 	User::Leave(KErrGeneral);
       
  1195 	}
       
  1196 
       
  1197 /**************************************************************************************************************
       
  1198  * CApsAlwaysPanicUpdate
       
  1199  **************************************************************************************************************/
       
  1200 
       
  1201 CApsAlwaysPanicUpdate::CApsAlwaysPanicUpdate(RFs& aFs, TState aState) :
       
  1202 		CApsNonNativeApplicationsUpdate(aFs,TUid::Uid(0xCAFEBABE),aState,EPanic)
       
  1203 	{
       
  1204 	}
       
  1205 
       
  1206 void CApsAlwaysPanicUpdate::DoPerformUpdateL(RApsUpdateLog& /*aUpdateLog*/)
       
  1207 	{
       
  1208 	TBool jit = User::JustInTime();
       
  1209 	User::SetJustInTime(EFalse);
       
  1210 	Panic(ENonNativeAppsTestHandlingPanicDuringUpdate);
       
  1211 	User::SetJustInTime(jit);
       
  1212 	}
       
  1213 
       
  1214 /**************************************************************************************************************
       
  1215  * CApsAlwaysPanicOnRollbackUpdate
       
  1216  **************************************************************************************************************/
       
  1217 
       
  1218 CApsAlwaysPanicOnRollbackUpdate::CApsAlwaysPanicOnRollbackUpdate(RFs& aFs, TState aState) :
       
  1219 		CApsNonNativeApplicationsUpdate(aFs,TUid::Uid(0x1337D00D),aState,ERollbackPanic)
       
  1220 	{
       
  1221 	}
       
  1222 
       
  1223 void CApsAlwaysPanicOnRollbackUpdate::DoRollbackUpdate(RApsUpdateLog& /*aUpdateLog*/)
       
  1224 	{
       
  1225 	TBool jit = User::JustInTime();
       
  1226 	User::SetJustInTime(EFalse);
       
  1227 	Panic(ENonNativeAppsTestHandlingPanicDuringRollback);
       
  1228 	User::SetJustInTime(jit);
       
  1229 	}
       
  1230 
       
  1231 #endif // _DEBUG