lowlevellibsandfws/pluginfw/Framework/frame/Registrar.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 1997-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 // Implementation of the registrar class
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @internalComponent
       
    20  @file 
       
    21 */
       
    22 
       
    23 #include <barsc2.h> // CResourceFile
       
    24 #include <barsread2.h> // RResourceReader
       
    25 #include <bautils.h>
       
    26 #include <e32uid.h>
       
    27 #include <startup.hrh> // for EStartupStateNonCritical
       
    28 
       
    29 #include "ecompanics.h"
       
    30 #include "EComDebug.h"
       
    31 #include <ecom/ecom.h>
       
    32 #include <ecom/ecomerrorcodes.h>
       
    33 #include <ecom/ecomresolverparams.h>
       
    34 #include "TestUtilities.h"	// For __FILE__LINE__
       
    35 #include "Registrar.h"
       
    36 #include "Discoverer.h"
       
    37 #include "BackupNotifier.h"
       
    38 #include "RegistryData.h"
       
    39 #include "EComUidCodes.h"
       
    40 #include "RegistrarObserver.h"
       
    41 #include "DriveInfo.h"
       
    42 #include "ParseImplementationData.h"
       
    43 #include "EComInternalErrorCodes.h"
       
    44 	
       
    45 const TInt KMinBuffAllocSize = 1;
       
    46 
       
    47 
       
    48 #define UNUSED_VAR(a) a = a
       
    49 
       
    50 
       
    51 CRegistrar* CRegistrar::NewL(CRegistryData& aRegistry, MRegistrarObserver& aRegistrarObserver, RFs& aFs)
       
    52 	{
       
    53 	CRegistrar* self = new(ELeave) CRegistrar(aRegistry,aRegistrarObserver,aFs);
       
    54 	CleanupStack::PushL(self);
       
    55 	self->ConstructL();
       
    56 	CleanupStack::Pop(self);
       
    57 	return self;
       
    58 	}
       
    59 
       
    60 // Default d'tor
       
    61 
       
    62 CRegistrar::~CRegistrar()
       
    63 	{
       
    64 	delete iBackupNotifier;
       
    65 	delete iDiscoverer;
       
    66 	delete iCachedDriveInfo;
       
    67 	}
       
    68 
       
    69 // Default c'tor
       
    70 
       
    71 CRegistrar::CRegistrar(CRegistryData& aRegistry, MRegistrarObserver& aRegistrarObserver, RFs& aFs)
       
    72 : CBase(), iRegistry(aRegistry), iRegistrarObserver(aRegistrarObserver), iFs(aFs), iState(EReg_Undefined)
       
    73 	{
       
    74 	}
       
    75 
       
    76 
       
    77 void CRegistrar::ConstructL()
       
    78 	{
       
    79 	iCachedDriveInfo = CEComCachedDriveInfo::NewL(iFs);
       
    80 
       
    81 	// Instantiate the discoverer
       
    82 	iDiscoverer = CDiscoverer::NewL(*this, iFs);
       
    83 	InitialiseEvent();
       
    84 	}
       
    85 
       
    86 
       
    87 TInt CRegistrar::Disable(TUid aImplementationUid)
       
    88 	{
       
    89 	return iRegistry.SetEnabledState(aImplementationUid, EFalse);
       
    90 	}
       
    91 
       
    92 
       
    93 TInt CRegistrar::Enable(TUid aImplementationUid)
       
    94 	{
       
    95 	return iRegistry.SetEnabledState(aImplementationUid, ETrue);
       
    96 	}
       
    97 
       
    98 
       
    99 TInt CRegistrar::Resume()
       
   100 	{
       
   101 	return iDiscoverer->Resume();
       
   102 	}
       
   103 
       
   104 
       
   105 TInt CRegistrar::Suspend()
       
   106 	{
       
   107 	return iDiscoverer->Suspend();
       
   108 	}
       
   109 
       
   110 
       
   111 void CRegistrar::DriveRemovedL(TDriveUnit aDrive)
       
   112 	{
       
   113 	iRegistry.TemporaryUninstallL(aDrive);
       
   114 	}
       
   115 
       
   116 
       
   117 void CRegistrar::DriveReinstatedL(TDriveUnit aDrive)
       
   118 	{
       
   119 	iRegistry.UndoTemporaryUninstallL(aDrive);
       
   120 	}
       
   121 	
       
   122 TBool CRegistrar::IsAnyDllRegisteredWithDriveL(const TDriveUnit aDrive)const
       
   123 	{
       
   124 	return iRegistry.IsAnyDllRegisteredWithDriveL(aDrive);
       
   125 	}
       
   126 
       
   127 void CRegistrar::RegisterDiscoveryL(const TDriveName& aDrive,CPluginBase*& aDirEntry, TBool aAnyDllDiscovered)
       
   128 	{
       
   129 	TBool found = EFalse;
       
   130 	TBool update = EFalse;
       
   131 	TInt  registryDriveIndex = KErrNotFound;
       
   132 
       
   133 	// Find the appropriate drive entry
       
   134 	TChar driveLetter = User::UpperCase(aDrive[0]) - 'A';
       
   135 	TDriveUnit driveUnit = EDriveA + driveLetter;
       
   136 	CRegistryData::CDriveData* drive =NULL;
       
   137 	
       
   138 	// Get the drive data in the registry.
       
   139 	registryDriveIndex = iRegistry.FindDriveL(driveUnit, drive);
       
   140 	if(registryDriveIndex == KErrNotFound)
       
   141 		{
       
   142 		User::Leave(KEComErrDriveNotFound);
       
   143 		}
       
   144 		
       
   145 
       
   146 	// Get the registry to return enough data so that the Add and Update routines
       
   147 	// can be optimised to avoid rescanning the registry data.
       
   148 	// This means that registryDriveIndex MUST remain valid until after
       
   149 	// the ParseRegistrationDataL call below.
       
   150 	
       
   151 	// IsRegisteredWithDate will be called if the this drive is NOT
       
   152 	// under its initial discovery. If any Dll is discovered in the drive, then
       
   153 	// this drive is NOT in its initial discovery.
       
   154 	
       
   155 	// In read-only drive with SPI enable, aAnyDllDiscovered will be always false. 
       
   156 	// If language downgrade path has been changed, IsRegisteredWithDate will be
       
   157 	// called to check whether current localised file need to be updated. 
       
   158 	if((aAnyDllDiscovered) || (iRegistry.HasLanguageChanged()))
       
   159 		{
       
   160 		found = iRegistry.IsRegisteredWithDate(aDirEntry->iDllThirdUid, aDirEntry->iDllModifiedTime, update, drive);
       
   161 		}
       
   162 	
       
   163 	if(!found || update || iRegistry.HasLanguageChanged())
       
   164 		{
       
   165 		if(found && !update && iRegistry.HasLanguageChanged())
       
   166 			{
       
   167 			// If we got here because the language has changed
       
   168 			// ensure the existing registry data is updated rather than a new entry added
       
   169 			update = ETrue;
       
   170 			}
       
   171 		ParseRegistrationDataL(aDirEntry,driveUnit, update, registryDriveIndex, drive);
       
   172 		}
       
   173 	}
       
   174 
       
   175 
       
   176 void CRegistrar::DiscoveriesBegin()
       
   177 	{
       
   178 	// We are about to receive registrations so inform the registry that its index
       
   179 	// is about to be invalid
       
   180 	iRegistry.DiscoveriesBeginning();
       
   181 	}
       
   182 
       
   183 
       
   184 void CRegistrar::DiscoveriesComplete(TBool aSuccessful, TPluginProcessingTypeIdentifier aProcessingType)
       
   185 	{
       
   186 	
       
   187 	TBool doesRegChanged = EFalse;
       
   188 
       
   189 	// Successfully completed, if registry data has been changed, update 
       
   190 	TRAPD(error,iRegistry.DiscoveriesCompleteL(aSuccessful, aProcessingType,doesRegChanged));
       
   191     UNUSED_VAR(error);
       
   192 	// Notify if the registry data has been changed.
       
   193 	if(doesRegChanged)
       
   194 		{
       
   195 	// Notify that we have updated the registry
       
   196 		iRegistrarObserver.Notification(KErrNone);
       
   197 		}
       
   198 	}
       
   199 
       
   200 void CRegistrar::SetDiscoveryFlagL(const TDriveUnit& aDriveUnit)
       
   201 	{
       
   202 	//set the drive flag to indicate it has changes.
       
   203 	iRegistry.SetDiscoveryFlagL(aDriveUnit);
       
   204 	}
       
   205 	
       
   206 TBool CRegistrar::NotifiedWithErrorCode(TInt aError)
       
   207 	{
       
   208 	// Test the safe error codes
       
   209 	return (aError == KErrNotReady ||		// Drive removed?
       
   210 			aError == KErrPathNotFound);	// Directory deleted?
       
   211 	}
       
   212 
       
   213 void CRegistrar::ParseRegistrationDataL(CPluginBase*& aEntry,
       
   214 										const TDriveUnit& aDrive, 
       
   215 										TBool aUpdate, 
       
   216 										TInt aRegistryDriveIndex,
       
   217 										CRegistryData::CDriveData* aDriveData)
       
   218 	{
       
   219 	// Ok we intend installing this item so 
       
   220 	// create the Interface Implementation Collection entry first
       
   221 	CRegistryData::CDllData* dll = CRegistryData::CDllData::NewLC(*(aEntry->iDllName),aEntry->iDllModifiedTime,aEntry->iDllSecondUid,aEntry->iDllThirdUid,aDriveData);
       
   222 
       
   223 #ifdef ECOM_TRACE
       
   224 	static int counter = 0; counter++;
       
   225 	TFileName fullFileName(aDrive.Name());
       
   226 	fullFileName.Append(_L("\\sys\\bin\\"));
       
   227 	fullFileName.Append(*(aEntry->iDllName));
       
   228 	__ECOM_TRACE2("ECOM: Plugin discovered (%04d) %S", counter, &fullFileName);
       
   229 #endif
       
   230 
       
   231 	// update resource ext info
       
   232 	HBufC* resourceExt = aEntry->RscFileExt();
       
   233 	if(resourceExt)
       
   234 		dll->SetResourceExtL(*resourceExt);
       
   235 	
       
   236 	// Don't automatically leave during the parse of the implementation
       
   237 	// collection's registration data.
       
   238 	// If we did then there would be a cascade of leaves which stop the 
       
   239 	// entire registration process for all discoveries remaining on the list.
       
   240 	// Check to see if there is a problem specifically with the registration data
       
   241 	// OR if its a general problem. In the latter case leave.
       
   242 	TInt error=KErrNone;
       
   243 			
       
   244 	TRAP(error, ParseL(aEntry,*dll));
       
   245 	if (error==KErrNoMemory)
       
   246 		User::LeaveNoMemory();
       
   247 	if(error == KErrNone)
       
   248 		{
       
   249 		if(aUpdate)
       
   250 			{	
       
   251 			iRegistry.UpdateDllDataL(aDrive, aRegistryDriveIndex, dll);
       
   252 			}
       
   253 		else
       
   254 			{	
       
   255 			iRegistry.AddDllDataL(aDrive, aRegistryDriveIndex, dll);
       
   256 			}
       
   257 		// Remove dll from CleanupStack as ownership has been passed in one of
       
   258 		// the two functions above
       
   259 		CleanupStack::Pop(dll);
       
   260 		}
       
   261 	else
       
   262 		{
       
   263 		// This interface implementation collection 
       
   264 		// cannot be registered correctly.
       
   265 		CleanupStack::PopAndDestroy(dll);
       
   266 		}
       
   267 	}
       
   268 
       
   269 void CRegistrar::GetResourceFormatVersionL(RResourceReader& aReader, TInt& aResourceFormatVersion)
       
   270 	{
       
   271 	aResourceFormatVersion = 1;
       
   272 	TUid dllUid(KNullUid);
       
   273 	TUid uid = {aReader.ReadInt32L()};
       
   274 	if(uid==KUidEComResourceFormatV2)
       
   275 		{
       
   276 		aResourceFormatVersion = 2;
       
   277 		dllUid.iUid = aReader.ReadInt32L();
       
   278 		}
       
   279 	else if(uid==KUidEComResourceFormatV3)
       
   280 		{
       
   281 		aResourceFormatVersion = 3;
       
   282 		dllUid.iUid = aReader.ReadInt32L();
       
   283 		}		
       
   284 	else
       
   285 		dllUid = uid;
       
   286 	}
       
   287 
       
   288 	
       
   289 void CRegistrar::ParseL(CPluginBase*& aEntry,CRegistryData::CDllData& aDll)
       
   290 	{
       
   291 // Read the resource file starting at offset:0 section size:0
       
   292 	CResourceFile* regFile =aEntry->RscFile();
       
   293 //	Note : There may be an issue here with resource reading when the 
       
   294 //  file is not in the ROM. The solution would be to call
       
   295 //	regFile.ConfirmSignatureL(regFile.SignatureL());
       
   296 //	However for 6.2 interface implementation collections will ALL
       
   297 //	be within the ROM. and future development will move to an
       
   298 //	XML parsed solution @ build time.
       
   299 //	IF this situation changes, place the fix here.
       
   300  	RResourceReader theReader;
       
   301  	theReader.OpenLC(regFile, KMinBuffAllocSize);
       
   302 	TInt resourceFormatVersion = 0;
       
   303 	GetResourceFormatVersionL(theReader,resourceFormatVersion);
       
   304 	
       
   305 	TDriveUnit drive(aDll.iParent->iDrive);
       
   306 	TBool romBased = iCachedDriveInfo->DriveIsReadOnlyInternalL(drive);
       
   307 	const TInt numInterfaces = theReader.ReadInt16L();
       
   308 	if (resourceFormatVersion == 3 && numInterfaces > KMaxInterfacesInResV3)
       
   309 		{
       
   310 		User::Leave(KErrNotSupported);
       
   311 		}
       
   312 	for(TInt iface = 0; iface < numInterfaces; ++iface)
       
   313 		{
       
   314 		// Read the interface uid
       
   315 		const TUid interfaceUid = {theReader.ReadInt32L()};
       
   316 		CRegistryData::CInterfaceData* interfaceList = CRegistryData::CInterfaceData::NewLC(interfaceUid,&aDll);
       
   317 		aDll.AddL(interfaceList);
       
   318 		CleanupStack::Pop(interfaceList);		// Now owned by aDll
       
   319 		const TInt numImplementations = theReader.ReadInt16L();
       
   320 		if (resourceFormatVersion == 3 && numImplementations > KMaxImplementationsForEachInterfacesInResV3)
       
   321 			{
       
   322 			User::Leave(KErrNotSupported);
       
   323 			}
       
   324 		for(TInt index = 0; index < numImplementations; ++index)
       
   325 			{
       
   326 			TUid implementationUid;
       
   327 			TInt versionNo;
       
   328 			TInt infoFormat;
       
   329 			TBool romOnly;
       
   330 			RExtendedInterfacesArray* extendedInterfaces = NULL;
       
   331 			HBufC* name = NULL;
       
   332 			HBufC8* defaultData = NULL;
       
   333 			HBufC8* opaqueData = NULL;
       
   334 			CParseImplementationData* parseImplementationData = CParseImplementationData::NewLC(resourceFormatVersion);
       
   335 			parseImplementationData->ParseL(theReader,
       
   336 											infoFormat,
       
   337 											implementationUid,
       
   338 											versionNo,
       
   339 									   	  	name,
       
   340 									      	defaultData,
       
   341 									      	opaqueData,
       
   342 									      	extendedInterfaces,
       
   343 									      	romOnly);
       
   344 			CleanupStack::PopAndDestroy(parseImplementationData);									      	
       
   345 			
       
   346 			CleanupStack::PushL(TCleanupItem(CloseAndDeleteArray, extendedInterfaces));
       
   347 			CleanupStack::PushL(name);
       
   348 			CleanupStack::PushL(defaultData);
       
   349 			CleanupStack::PushL(opaqueData);
       
   350 			if (romOnly && !(romBased))
       
   351 				{
       
   352 				// pop and destroy opaquedata, defaultdata,name and extendedInterfaces
       
   353 				CleanupStack::PopAndDestroy(4,extendedInterfaces); 
       
   354 				}
       
   355 			else
       
   356 				{
       
   357 				CRegistryData::CImplementationData* implData = CRegistryData::CImplementationData::NewL(interfaceList,
       
   358 																										implementationUid, 
       
   359 																				 						versionNo, 
       
   360 																				 						name, 
       
   361 																						 				defaultData,
       
   362 																										opaqueData,
       
   363 																					 					drive,
       
   364 																					 					romOnly,
       
   365 																				 						romBased,
       
   366 																				 						extendedInterfaces);
       
   367 				CleanupStack::Pop(4,extendedInterfaces); // opaqueData,defaultData,name,extendedInterfaces owned by implData
       
   368 				CleanupStack::PushL(implData);
       
   369 				interfaceList->AddL(implData);	// Now owned by interfaceList	
       
   370 				CleanupStack::Pop(implData);
       
   371 				}
       
   372 			}
       
   373 		}
       
   374 	CleanupStack::PopAndDestroy(&theReader);		
       
   375 	}
       
   376 
       
   377 	
       
   378 CRegistrar::TRegistrarState CRegistrar::State()const
       
   379 	{
       
   380 	return iState;
       
   381 	}
       
   382 
       
   383 void CRegistrar::ProcessSSAEventL(TStartupStateIdentifier aKnownState)
       
   384 	{
       
   385 	iDiscoverer->ProcessSSAEventL(aKnownState); 
       
   386 	if(aKnownState == EStartupStateNonCritical && iState == EReg_StartupInProgess)
       
   387 		{
       
   388 		__ECOM_TRACE("ECOM: CRegistrar::ProcessSSAEventL(): EStartupStateNonCritical is reached.");
       
   389 
       
   390 		iState = EReg_StartupComplete;
       
   391 		iBackupNotifier = CBackupNotifier::NewL(*this);
       
   392 		}
       
   393 	}
       
   394 void CRegistrar::InitialiseEvent()
       
   395 	{
       
   396 	iState = EReg_StartupInProgess;
       
   397 	}
       
   398 
       
   399 void CRegistrar::LanguageChangedL(TBool& aLanguageChanged)
       
   400 	{
       
   401 	iRegistry.LanguageChangedL(aLanguageChanged);
       
   402 	}
       
   403 
       
   404 void CRegistrar::InstallSwiEventCallBack(const TCallBackWithArg& aCallBack)
       
   405 	{
       
   406 	iDiscoverer->SetSwiChangeCallBack(aCallBack);
       
   407 	}
       
   408 
       
   409 void CRegistrar::InstallBurEventCallBack(const TCallBackWithArg& aCallBack)
       
   410 	{
       
   411 	iDiscoverer->SetBurChangeCallBack(aCallBack);
       
   412 	}