messagingfw/msgsrvnstore/server/src/MTSR.CPP
changeset 62 db3f5fa34ec7
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 1998-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 // MTSR.CPP
       
    15 //
       
    16 
       
    17 #include "MSVRUIDS.H"
       
    18 #include "MTSR.H"
       
    19 #include "MTSRUT.H"
       
    20 #include "MSVPANIC.H"
       
    21 #include "MSVENTRY.H"
       
    22 #include "MsvSecurityCapabilitySet.h"
       
    23 #include <tmsvsystemprogress.h>
       
    24 
       
    25 #include <e32uid.h>
       
    26 #include <s32file.h>
       
    27 #include <barsc.h>
       
    28 #include <barsread.h>
       
    29 #include <bautils.h>
       
    30 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
       
    31 #include "cinstalledmtmgroup.h"
       
    32 #include "msvconsts.h"				
       
    33 #endif
       
    34 
       
    35 _LIT(KDefaultRegistryFileStoreName, "\\private\\1000484b\\Mtm Registry v2");
       
    36 
       
    37 
       
    38 const TUid KUidRegistryFileStore={0x10003C6A};
       
    39 const TUid KUidRegistryRootStream={268439422};
       
    40 
       
    41 const TInt KMtmInfoFileResourceId = 1;
       
    42 const TInt KMtmCapabilitiesResourceId = 2;
       
    43 const TInt KMtmSecurityCapabilitySetResourceId = 3;
       
    44 
       
    45 EXPORT_C CBaseServerMtm::~CBaseServerMtm()
       
    46 /** Destructor.
       
    47 
       
    48 This cleans up the base class. CBaseServerMtm-derived objects are deleted by the 
       
    49 Message Server when they are no longer required. 
       
    50 
       
    51 Derived classes can implement a destructor to do any additional clean up tasks 
       
    52 that they require. */
       
    53 	{
       
    54 	iRegisteredMtmDll.ReleaseLibrary();
       
    55 	delete iServerEntry;
       
    56 	}
       
    57 
       
    58 /** Constructor. 
       
    59 
       
    60 The function is passed a CMsvServerEntry object in aServerEntry. This object is used to access
       
    61 and change Message Server entries. Its context is initially set either to the
       
    62 parent of the entry or selection being operated on, or the entry itself. The
       
    63 constructor stores it in the protected iServerEntry member.
       
    64 
       
    65 Derived classes can implement a constructor to perform any additional MTM-specific 
       
    66 setup that can be safely carried out in a constructor. Such constructors must call the 
       
    67 base class constructor function.
       
    68 
       
    69 @param aRegisteredMtmDll Registration data for the MTM DLL
       
    70 @param aServerEntry Context on which to operate
       
    71 */
       
    72 EXPORT_C CBaseServerMtm::CBaseServerMtm(CRegisteredMtmDll& aRegisteredMtmDll, CMsvServerEntry* aServerEntry):
       
    73 	CActive(EPriorityStandard),	iServerEntry(aServerEntry), iRegisteredMtmDll(aRegisteredMtmDll)
       
    74 	{
       
    75 	}
       
    76 
       
    77 EXPORT_C void CBaseServerMtm::RunL()
       
    78 /** Provides a simple implementation of CActive::RunL() that calls the derived 
       
    79 class's DoRunL() function. If that function leaves, then the leave is trapped, 
       
    80 and DoComplete() is called to handle the error.
       
    81 
       
    82 This implementation ensures that derived classes handle leave errors in RunL(), 
       
    83 rather than the default of the error being passed to the active scheduler. */
       
    84 	{
       
    85 	DoRunL();
       
    86 	}
       
    87 
       
    88 
       
    89 /** Handles the cases where RunL is leaving.
       
    90 */
       
    91 EXPORT_C TInt CBaseServerMtm::RunError(TInt aError)
       
    92 	{
       
    93 	DoComplete(aError);
       
    94 	return KErrNone;
       
    95 	}
       
    96 
       
    97 
       
    98 /**
       
    99 Returns a pointer to the interface with the specified Uid. 
       
   100 
       
   101 This method is the first part of an extension pattern to allow for 
       
   102 more functionality to be supported without adding virtual methods 
       
   103 to this base class.
       
   104 
       
   105 The default implementation returns a NULL pointer.
       
   106  
       
   107 @param	aUid  
       
   108 Uid of the extension interface
       
   109 @return
       
   110 Pointer to the extension interface
       
   111 */
       
   112 EXPORT_C TAny* CBaseServerMtm::GetInterface(TUid /*aUid*/)
       
   113  	{
       
   114 	return NULL;
       
   115  	}
       
   116 
       
   117 /** 
       
   118 This call leads to calling one of the server Mtms to populate the 
       
   119 TMsvSystemProgress structure.
       
   120 @param aOutSysProg The TMsvSystemProgress structure to be populated by the server
       
   121 @return the error of the Extension_ method call
       
   122 */
       
   123 EXPORT_C TInt CBaseServerMtm::SystemProgress(TMsvSystemProgress& aOutSysProg)
       
   124 	{
       
   125 	TAny* ptrNull = NULL;
       
   126 	return Extension_(KUIDMsgMsvSystemProgress, ptrNull, &aOutSysProg);
       
   127 	}
       
   128 
       
   129 /**
       
   130 Call to this method leads to call Extension_ method of server MTMs, to which
       
   131 the thread handle of the client application is passed.
       
   132 */
       
   133 #if (defined SYMBIAN_USER_PROMPT_SERVICE)	
       
   134 TInt CBaseServerMtm::ClientThreadInfo(TThreadId aClientInfo, TBool aCapabilityCheck)
       
   135 	{
       
   136 	TAny* ptrNull = &aCapabilityCheck;
       
   137 	return Extension_(KUIDMsgClientThreadInfo, ptrNull, &aClientInfo);
       
   138 	}
       
   139 #endif
       
   140 
       
   141 TInt CBaseServerMtm::GetNonOperationMtmData(TNonOperationMtmDataType& aMtmDataType, TPtrC8& aResultBuffer)
       
   142 	{
       
   143 	TAny* mtmDataTypePtr = &aMtmDataType;
       
   144 	return Extension_(KUidMsgNonOperationMtmData, mtmDataTypePtr, &aResultBuffer);
       
   145 	}
       
   146 
       
   147 /** The extension method provides a polymorphic behaviour to call the correct
       
   148 SystemProgress function.
       
   149 @param aExtensionId The Uid passed in as KUIDMsgMsvSystemProgress to obtain the
       
   150 System Progress.
       
   151 @return KErrExtensionNotSupported retuned if no Extension_ function is overriddden
       
   152 by the derived class.
       
   153 */	
       
   154 EXPORT_C TInt CBaseServerMtm::Extension_(TUint aExtensionId, TAny *&a0, TAny *a1)	
       
   155 	{
       
   156 	TInt ret = KErrNone;
       
   157 	switch(aExtensionId)
       
   158 		{
       
   159 		case KUIDMsgMsvSystemProgress:
       
   160 		case KUidMsgNonOperationMtmData:
       
   161 #if (defined SYMBIAN_USER_PROMPT_SERVICE)	
       
   162 		case KUIDMsgClientThreadInfo:
       
   163 #endif		
       
   164 			{
       
   165 			ret = KErrExtensionNotSupported;
       
   166 			}
       
   167 			break;
       
   168 
       
   169 		default:
       
   170 			{
       
   171 		// Chain to base class
       
   172 			ret = CActive::Extension_(aExtensionId, a0, a1);
       
   173 			}
       
   174 			break;
       
   175 		}
       
   176 	return ret;
       
   177 	}
       
   178 // Empty declaration
       
   179 EXPORT_C TInt CBaseServerMtm::ChangeEntriesL( const CMsvEntrySelection& /*aSelection*/,TInt /*aMark*/, TRequestStatus& aStatus )
       
   180     {
       
   181     //Empty declaration. Respective MTM implementation should be call .
       
   182     TRequestStatus aEmptyStatus;
       
   183     aEmptyStatus = aStatus ;
       
   184     
       
   185     return KErrNotSupported; // Specific to MTM. Base return Not supported.  
       
   186     }
       
   187 
       
   188 
       
   189 EXPORT_C CServerMtmDllRegistry* CServerMtmDllRegistry::NewL(RFs& aFs,TTimeIntervalMicroSeconds32 aTimeoutMicroSeconds32)
       
   190 	{
       
   191 	return new(ELeave) CServerMtmDllRegistry(aFs,aTimeoutMicroSeconds32); 
       
   192 	}
       
   193 
       
   194 EXPORT_C CServerMtmDllRegistry::~CServerMtmDllRegistry()
       
   195 	{
       
   196 	}
       
   197 
       
   198 EXPORT_C CBaseServerMtm* CServerMtmDllRegistry::NewServerMtmL(TUid aMtmTypeUid, CMsvServerEntry* aInitialEntry)
       
   199 	{
       
   200 	CleanupStack::PushL(aInitialEntry); // Take ownership of the server entry
       
   201 
       
   202 	if(!IsPresent(aMtmTypeUid))
       
   203 		User::Leave(KErrNotFound);
       
   204 
       
   205 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   206 	CRegisteredMtmDll* registeredmtmdll=iRegisteredMtmDllArray[index];
       
   207 	RLibrary mtmdlllibrary;
       
   208 	User::LeaveIfError(registeredmtmdll->GetLibrary(iFs, mtmdlllibrary));
       
   209 	
       
   210 	TInt refcount = registeredmtmdll->MtmDllRefCount();
       
   211 	CBaseServerMtm* servermtm = NULL;
       
   212 	CleanupStack::Pop(); // aInitialEntry - function takes ownership of this
       
   213 
       
   214 	TRAPD(ret, servermtm = NewMtmL(mtmdlllibrary, aInitialEntry, *registeredmtmdll));
       
   215 
       
   216 	if ((ret!=KErrNone) && (registeredmtmdll->MtmDllRefCount()==refcount))  //  Library not released in mtm destructor
       
   217 		registeredmtmdll->ReleaseLibrary();
       
   218 	
       
   219 	User::LeaveIfError(ret);
       
   220 	return servermtm;
       
   221 	}
       
   222 
       
   223 CBaseServerMtm* CServerMtmDllRegistry::NewMtmL(const RLibrary& aLib, CMsvServerEntry* aServerEntry, CRegisteredMtmDll& aReg) const
       
   224 	{
       
   225 	CleanupStack::PushL(aServerEntry); // Take ownership of the server entry
       
   226 	typedef CBaseServerMtm*(*NewServerMtmL)(CRegisteredMtmDll& aRegisteredMtmDll, CMsvServerEntry* aInitialEntry);
       
   227 
       
   228 	TInt ordinal = aReg.MtmDllInfo().iEntryPointOrdinalNumber;
       
   229 	TLibraryFunction libFunc = aLib.Lookup(ordinal);
       
   230 	if (!libFunc)
       
   231 		User::Leave(KErrBadLibraryEntryPoint);
       
   232 
       
   233 	NewServerMtmL pFunc = (NewServerMtmL)libFunc;
       
   234 
       
   235 	CleanupStack::Pop(); // aServerEntry - mtm should take ownership of this
       
   236 	return (*pFunc)(aReg, aServerEntry);
       
   237 	}
       
   238 	
       
   239 CServerMtmDllRegistry::CServerMtmDllRegistry(RFs& aFs,TTimeIntervalMicroSeconds32 aTimeoutMicroSeconds32):
       
   240 	CMtmDllRegistry(aFs,KUidMtmServerComponent,aTimeoutMicroSeconds32)
       
   241 	{
       
   242 	__DECLARE_NAME(_S("CServerMtmDllRegistry"));
       
   243 	}
       
   244 
       
   245 CInstalledMtmGroupArray::CInstalledMtmGroupArray():
       
   246 	CArrayPtrFlat<CInstalledMtmGroup>(8)
       
   247 	{
       
   248 	}
       
   249 
       
   250 CInstalledMtmGroupArray::~CInstalledMtmGroupArray()
       
   251 	{
       
   252 	ResetAndDestroy();
       
   253 	}
       
   254 
       
   255 void CInstalledMtmGroupArray::AddInstalledMtmGroupL(CInstalledMtmGroup* aInstalledMtmGroup)
       
   256 	{
       
   257 	CleanupStack::PushL(aInstalledMtmGroup);
       
   258 	AppendL(aInstalledMtmGroup);
       
   259 	CleanupStack::Pop();
       
   260 	}
       
   261 
       
   262 
       
   263 EXPORT_C CMtmRegistryControl* CMtmRegistryControl::NewL(RFs& anFs,CServerMtmDllRegistry& aServerMtmDllRegistry)
       
   264 	{
       
   265 	CMtmRegistryControl* mtmregistrycontrol=new(ELeave) CMtmRegistryControl(anFs,aServerMtmDllRegistry);
       
   266 	CleanupStack::PushL(mtmregistrycontrol);
       
   267 	mtmregistrycontrol->ConstructL();
       
   268 	CleanupStack::Pop();
       
   269 	return mtmregistrycontrol;	
       
   270 	}
       
   271 
       
   272 EXPORT_C CMtmRegistryControl::~CMtmRegistryControl()
       
   273 	{
       
   274 	delete iInstalledMtmGroupArray;
       
   275 	}
       
   276 
       
   277 EXPORT_C TInt CMtmRegistryControl::InstallMtmGroup(const TDesC& aFullName,TUid& aMtmTypeUid)
       
   278 	{
       
   279 	aMtmTypeUid=KNullUid;
       
   280 
       
   281 	// Install the mtm
       
   282 	TRAPD(ret, DoInstallMtmGroupL(aFullName, aMtmTypeUid));
       
   283 	if ((ret!=KErrNone) && (aMtmTypeUid!=KNullUid))
       
   284 		RemoveInstalledMtmGroup(aMtmTypeUid);
       
   285 	return ret;
       
   286 	}
       
   287 
       
   288 EXPORT_C TInt CMtmRegistryControl::FullNameToMtmTypeUid(const TDesC& aFullName,TUid& aMtmTypeUid) const
       
   289 	{
       
   290 	aMtmTypeUid=KNullUid;
       
   291 	TRAPD(ret, aMtmTypeUid = DoFindMtmTypeUidL(aFullName));
       
   292 	if (ret==KErrNone)
       
   293 		{
       
   294 		TUidType uidtype(KPermanentFileStoreLayoutUid, KUidMsvDataComponent, aMtmTypeUid);
       
   295 		TInt index=UidTypeToIndex(uidtype);
       
   296 		if (index==iInstalledMtmGroupArray->Count())
       
   297 			ret=KErrNotFound;
       
   298 		else 
       
   299 			aMtmTypeUid=iInstalledMtmGroupArray->At(index)->iMtmGroupData->MtmTypeUid();
       
   300 		}
       
   301 	return ret;
       
   302 	}
       
   303 
       
   304 TBool CMtmRegistryControl::IsResFileL(const TDesC& aFullName) const
       
   305 	{
       
   306 	// Check the extension to see if it's a resource file
       
   307 	TParse parse;
       
   308 	User::LeaveIfError(parse.Set(aFullName, NULL, NULL));
       
   309 
       
   310 	// If first alpha character of extension is 'r' assume we're dealing with a resource file
       
   311 	TPtrC ext(parse.Ext());
       
   312 	return ext.Length() > 1 && TCharF(ext[1]) == TCharF('r');
       
   313 	}
       
   314 
       
   315 TUid CMtmRegistryControl::DoFindMtmTypeUidL(const TDesC& aFullName) const
       
   316 	{
       
   317 	TUid mtmTypeUid = KNullUid;
       
   318 
       
   319 	// Is the file a resource file?
       
   320 	if (!IsResFileL(aFullName))
       
   321 		{
       
   322 		// Get the third Uid
       
   323 		TEntry entry;
       
   324 		User::LeaveIfError(iFs.Entry(aFullName, entry));
       
   325 		mtmTypeUid = entry[2];
       
   326 		}
       
   327 	else
       
   328 		{
       
   329 		// Open the resource file
       
   330 		RResourceFile file;
       
   331 		file.OpenL(iFs, aFullName);
       
   332 		CleanupClosePushL(file);
       
   333 		HBufC8* res = file.AllocReadLC(1);
       
   334 		
       
   335 		// Interpret the resource buffer
       
   336 		TResourceReader reader;
       
   337 		reader.SetBuffer(res);
       
   338 
       
   339 		// Get the mtm type
       
   340 		mtmTypeUid = TUid::Uid(reader.ReadInt32());
       
   341 		CleanupStack::PopAndDestroy(2); // res, file
       
   342 		}
       
   343 
       
   344 	// Return the Uid Type
       
   345 	return mtmTypeUid;
       
   346 	}
       
   347 
       
   348 EXPORT_C TInt CMtmRegistryControl::DeInstallMtmGroup(TUid aMtmTypeUid)
       
   349 	{
       
   350 	TRAPD(ret,DoDeInstallMtmGroupL(aMtmTypeUid));
       
   351 	if (ret!=KErrNone)
       
   352 		{
       
   353 		TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   354 		iInstalledMtmGroupArray->At(index)->iIsInstalled=ETrue;
       
   355 		}
       
   356 	return ret;
       
   357 	}
       
   358 
       
   359 EXPORT_C TInt CMtmRegistryControl::UseMtmGroup(TUid aMtmTypeUid)
       
   360 	{
       
   361 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   362 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   363 	iInstalledMtmGroupArray->At(index)->iClientUsageCount++;	
       
   364 	return KErrNone;
       
   365 	}
       
   366 
       
   367 EXPORT_C TInt CMtmRegistryControl::ReleaseMtmGroup(TUid aMtmTypeUid)  
       
   368 	{
       
   369 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   370 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   371 	iInstalledMtmGroupArray->At(index)->iClientUsageCount--;	
       
   372 	return KErrNone;
       
   373 	}
       
   374 
       
   375 EXPORT_C TBool CMtmRegistryControl::IsInUse(TUid aMtmTypeUid) const
       
   376 	{
       
   377 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   378 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   379 	return (*iInstalledMtmGroupArray->At(index)).iClientUsageCount>0;
       
   380 	}
       
   381 
       
   382 EXPORT_C TInt CMtmRegistryControl::FillRegisteredMtmDllArray(TUid aMtmDllTypeUid,CRegisteredMtmDllArray& aRegisteredMtmDllArray,TTimeIntervalMicroSeconds32 aTimeoutMicroSeconds32)  // Fill array with Dlls whose second uid is aMtmDllTypeUid
       
   383 	{
       
   384 	aRegisteredMtmDllArray.ResetAndDestroy();  //  Trash the array
       
   385 	TUid mtmdlltypeuid[KMsvNumMtmDllTypes];  //  There must be an easier way to construct the array
       
   386 	mtmdlltypeuid[EMtsrServerComponentIndex]	=KUidMtmServerComponent;
       
   387 	mtmdlltypeuid[EMtsrClientComponentIndex]	=KUidMtmClientComponent;
       
   388 	mtmdlltypeuid[EMtsrUiComponentIndex]		=KUidMtmUiComponent;
       
   389 	mtmdlltypeuid[EMtsrUiDataComponentIndex]	=KUidMtmUiDataComponent;
       
   390 /*
       
   391 	mtmdlltypeuid[EMtsrDllTupe1Index]=KMsvDllType1Uid;
       
   392 	mtmdlltypeuid[EMtsrDllType2Index]=KMsvDllType2Uid;
       
   393 	mtmdlltypeuid[EMtsrDllType3Index]=KMsvDllType3Uid;
       
   394 	mtmdlltypeuid[EMtsrDllType4Index]=KMsvDllType4Uid;
       
   395 	mtmdlltypeuid[EMtsrDllType5Index]=KMsvDllType5Uid;
       
   396 	mtmdlltypeuid[EMtsrDllType6Index]=KMsvDllType6Uid;
       
   397 */
       
   398 	TInt index=0;
       
   399 	for (; (index<KMsvNumMtmDllTypes) && (aMtmDllTypeUid!=mtmdlltypeuid[index]); index++)
       
   400 		{
       
   401 		}
       
   402 	if (index==KMsvNumMtmDllTypes)
       
   403 		return KErrNotSupported;
       
   404 	TInt ret=KErrNone;
       
   405 	TInt count1=iInstalledMtmGroupArray->Count();
       
   406 	for (TInt i=0; i<count1; i++)
       
   407 		{
       
   408 		CMtmGroupData* mtmgroupdata=iInstalledMtmGroupArray->At(i)->iMtmGroupData;
       
   409 		TInt count2=mtmgroupdata->MtmDllInfoArray().Count();
       
   410 		if (index<count2)
       
   411 			{
       
   412 			CMtmDllInfo* mtmdllinfo=mtmgroupdata->MtmDllInfoArray()[index];
       
   413 			if (mtmdllinfo->iUidType[2]!=KNullUid)
       
   414 				{
       
   415 				TRAP(ret,
       
   416 					{	
       
   417 					CRegisteredMtmDll* registeredmtmdll=CRegisteredMtmDll::NewL(mtmgroupdata->MtmTypeUid(),mtmgroupdata->TechnologyTypeUid(),*mtmdllinfo,aTimeoutMicroSeconds32,*this);
       
   418 					
       
   419 					// The following takes ownership of registeredmtmdll
       
   420 					aRegisteredMtmDllArray.AddRegisteredMtmDllL(registeredmtmdll);
       
   421 					});
       
   422 
       
   423 				if (ret!=KErrNone)
       
   424 					{
       
   425 					aRegisteredMtmDllArray.ResetAndDestroy();
       
   426 					break;
       
   427 					}
       
   428 				}
       
   429 			}			
       
   430 		}
       
   431 	return ret;
       
   432 	}
       
   433 
       
   434 
       
   435 const CMtmGroupData& CMtmRegistryControl::GetMtmGroupDataReferenceL(TUid aMtmTypeUid) const
       
   436 	{
       
   437 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   438 	if (index==iInstalledMtmGroupArray->Count())
       
   439 		User::Leave(KErrNotFound);
       
   440 	
       
   441 	return *(iInstalledMtmGroupArray->At(index)->iMtmGroupData);
       
   442 	}
       
   443 
       
   444 EXPORT_C CMtmGroupData* CMtmRegistryControl::GetMtmGroupDataL(TUid aMtmTypeUid) const
       
   445 	{
       
   446 	return CMtmGroupData::NewL(GetMtmGroupDataReferenceL(aMtmTypeUid));
       
   447 	}
       
   448 
       
   449 EXPORT_C void CMtmRegistryControl::StoreRegistryL() const
       
   450 	{
       
   451 	TParse parsedname;
       
   452 	User::LeaveIfError(parsedname.Set(iPathName,NULL,NULL));
       
   453 	TInt ret=iFs.MkDirAll(parsedname.DriveAndPath());
       
   454 	if (ret!=KErrAlreadyExists)
       
   455 		User::LeaveIfError(ret);
       
   456 	CDictionaryFileStore* registryfilestore = CDictionaryFileStore::OpenLC(iFs,parsedname.FullName(),KUidRegistryFileStore);
       
   457 	RDictionaryWriteStream writestream;
       
   458 	writestream.AssignLC(*registryfilestore,KUidRegistryRootStream);
       
   459 	ExternalizeL(writestream);
       
   460 	writestream.CommitL();
       
   461 	writestream.Close();
       
   462 	registryfilestore->CommitL();
       
   463 	CleanupStack::PopAndDestroy(2);	// writestream and registryfilestore
       
   464 	}
       
   465 
       
   466 EXPORT_C void CMtmRegistryControl::RestoreRegistryL()
       
   467 	{
       
   468 	TParse parsedname;
       
   469 	User::LeaveIfError(parsedname.Set(iPathName,NULL,NULL));
       
   470 	TEntry entry;
       
   471 	User::LeaveIfError(iFs.Entry(parsedname.FullName(),entry));
       
   472 	CDictionaryFileStore* registryfilestore = CDictionaryFileStore::OpenLC(iFs,parsedname.FullName(),KUidRegistryFileStore);
       
   473 	RDictionaryReadStream readstream;
       
   474 	readstream.OpenLC(*registryfilestore,KUidRegistryRootStream);
       
   475 	InternalizeL(readstream);
       
   476 	readstream.Close();
       
   477 	CleanupStack::PopAndDestroy();// readstream
       
   478 	CleanupStack::PopAndDestroy();	// registryfilestore
       
   479 	}
       
   480 
       
   481 EXPORT_C void CMtmRegistryControl::InternalizeL(RReadStream& aStream)
       
   482 	{
       
   483 	__ASSERT_DEBUG(iInstalledMtmGroupArray->Count()==0,PanicServer(EMtsrRegistryControlStillInUse));
       
   484 	TRAPD(ret,DoInternalizeL(aStream))
       
   485 	if (ret!=KErrNone)
       
   486 		{
       
   487 		iInstalledMtmGroupArray->ResetAndDestroy();
       
   488 		iServerMtmDllRegistry.RemoveAllRegisteredMtmDlls();
       
   489 		User::Leave(ret);
       
   490 		}
       
   491 	}
       
   492 
       
   493 EXPORT_C void CMtmRegistryControl::ExternalizeL(RWriteStream& aStream) const
       
   494 	{
       
   495 	TInt count1=iInstalledMtmGroupArray->Count(),count2=0;
       
   496 	TInt i=0;
       
   497 	for (; i<count1; i++)
       
   498 		if ((*iInstalledMtmGroupArray->At(i)).iIsInstalled)
       
   499 			count2++;
       
   500 	aStream.WriteInt32L(count2);
       
   501 	for (i=0; i<count1; i++)
       
   502 		if ((*iInstalledMtmGroupArray->At(i)).iIsInstalled)
       
   503 			aStream << *(iInstalledMtmGroupArray->At(i)->iFilename);
       
   504 	}
       
   505 
       
   506 CMtmRegistryControl::CMtmRegistryControl(RFs& anFs,CServerMtmDllRegistry& aServerMtmDllRegistry):
       
   507 	iFs(anFs),
       
   508 	iInstalledMtmGroupArray(),
       
   509 	iServerMtmDllRegistry(aServerMtmDllRegistry)
       
   510 	{
       
   511 	__DECLARE_NAME(_S("CMtmRegistryControl"));
       
   512 	}
       
   513 
       
   514 void CMtmRegistryControl::ConstructL()
       
   515 	{
       
   516 	iInstalledMtmGroupArray = new(ELeave) CInstalledMtmGroupArray();
       
   517 
       
   518 	TChar iDriveChar= iFs.GetSystemDriveChar();
       
   519 	TBuf<2> systemDrive;
       
   520 	systemDrive.Append(iDriveChar);
       
   521 	systemDrive.Append(KDriveDelimiter);
       
   522 	iPathName=systemDrive;
       
   523 	iPathName.Append(KDefaultRegistryFileStoreName);
       
   524 	
       
   525 	TRAPD(ret,RestoreRegistryL());  
       
   526 	//should not delete registry if in use
       
   527 	if ((ret!=KErrNone) && (ret!=KErrInUse))
       
   528 		{
       
   529 		//ignore error if we can't delete a corrupt file; StoreRegistryL will leave
       
   530 		iFs.SetAtt(iPathName,0,KEntryAttReadOnly|KEntryAttHidden|KEntryAttSystem);
       
   531 		iFs.Delete(iPathName);
       
   532 		StoreRegistryL();
       
   533 		}
       
   534 	}
       
   535 
       
   536 TInt CMtmRegistryControl::MtmTypeUidToIndex(TUid aMtmTypeUid) const
       
   537 	{
       
   538 	TInt count=iInstalledMtmGroupArray->Count();
       
   539 	TInt index=0;
       
   540 	for (; (index<count) && (iInstalledMtmGroupArray->At(index)->iMtmGroupData->MtmTypeUid()!=aMtmTypeUid); index++)
       
   541 		{
       
   542 		}
       
   543 	return index;
       
   544 	}
       
   545 
       
   546 TInt CMtmRegistryControl::UidTypeToIndex(TUidType aUidType) const
       
   547 	{
       
   548 	TInt count=iInstalledMtmGroupArray->Count();
       
   549 	TInt index=0;
       
   550 	for (; (index<count) && (iInstalledMtmGroupArray->At(index)->iUidType!=aUidType); index++)
       
   551 		{
       
   552 		}
       
   553 	return index;
       
   554 	}
       
   555 
       
   556 CMtmGroupData *CMtmRegistryControl::LoadMTMFileL(const TDesC& aFullName, TUid &aUid)
       
   557 	{
       
   558 	if(IsResFileL(aFullName)==EFalse)
       
   559 		return(LoadDatFileL(aFullName, aUid));
       
   560 	else
       
   561 		return(LoadResFileL(aFullName, aUid));
       
   562 	}
       
   563 
       
   564 CMtmGroupData *CMtmRegistryControl::LoadDatFileL(const TDesC& aFullName, TUid &aUid)
       
   565 	{
       
   566 	TEntry entry;
       
   567 	User::LeaveIfError(iFs.Entry(aFullName,entry));  //  Check file exists
       
   568 	if ((entry[0]!=KPermanentFileStoreLayoutUid) || (entry[1]!=KUidMsvDataComponent))
       
   569 		User::Leave(KErrNotSupported);
       
   570 	aUid=entry[2];
       
   571 	CMtmGroupData* mtmgroupdata=ReadDataFileStoreL(aFullName);
       
   572 	return(mtmgroupdata);
       
   573 	}
       
   574 
       
   575 
       
   576 CMtmGroupData *CMtmRegistryControl::LoadResFileL(const TDesC& aFullName, TUid &aUid)
       
   577 	{
       
   578 	TFileName fileName(aFullName);
       
   579 	_LIT(KRssFileExtension, ".rsc");
       
   580 
       
   581 	TParsePtrC filenamePPtr(fileName);
       
   582 	TPtrC ext =filenamePPtr.Ext();
       
   583 	if(ext!=(KRssFileExtension)) 
       
   584 		{ //if ext is not .rsc, replace with rsc.  Always pass *.rsc to the BaflUtils::NearestLanguageFile
       
   585 		TInt pos=fileName.FindF(ext);
       
   586 		fileName.Replace(pos,fileName.Length()-pos,KRssFileExtension);
       
   587 		}
       
   588 	BaflUtils::NearestLanguageFile(iFs, fileName);
       
   589 
       
   590 	// Open the resource file	
       
   591 	RResourceFile file;
       
   592 	file.OpenL(iFs, fileName);
       
   593 	CleanupClosePushL(file);
       
   594 	HBufC8* res = file.AllocReadLC(KMtmInfoFileResourceId);
       
   595 
       
   596 	// Attempt to get the capabilities resource
       
   597 	HBufC8* cap = NULL;
       
   598 
       
   599 	TRAPD(error,cap = file.AllocReadL(KMtmCapabilitiesResourceId));
       
   600 	TBool capAvailable = EFalse;
       
   601 	TBool capSend = EFalse;
       
   602 	TBool capBody = EFalse;
       
   603 	if (error == KErrNone)
       
   604 		{
       
   605 		CleanupStack::PushL(cap);
       
   606 		capAvailable = ETrue;
       
   607 		TResourceReader capReader;
       
   608 		capReader.SetBuffer(cap);
       
   609 		// Get the send capability
       
   610 		capSend = capReader.ReadInt8();
       
   611 		// Get the body capability
       
   612 		capBody = capReader.ReadInt8();
       
   613 
       
   614 		CleanupStack::PopAndDestroy(cap);
       
   615 		}
       
   616 
       
   617 	// Interpret the resource buffer
       
   618 	TResourceReader reader;
       
   619 	reader.SetBuffer(res);
       
   620 	
       
   621 	// Get the mtm type
       
   622 	TUid mtmTypeUid = { reader.ReadInt32() };
       
   623 	aUid=mtmTypeUid;
       
   624 		
       
   625 	CMtmDllInfoArray* mtmDllInfoArray = new(ELeave) CMtmDllInfoArray();
       
   626 	CleanupStack::PushL(mtmDllInfoArray);
       
   627 	
       
   628 	// Get technology type
       
   629 	TUid technologyTypeUid = { reader.ReadInt32() };
       
   630 	
       
   631 	// Get number of mtm components
       
   632 	TInt components(reader.ReadInt16());
       
   633 	while(components--)
       
   634 		{
       
   635 		// Get the name of the component
       
   636 		TPtrC name(reader.ReadTPtrC());
       
   637 		
       
   638 		// Get the type of component
       
   639 		TUid componentUid = { reader.ReadInt32() };
       
   640 		
       
   641 		// Get specific Uid of the Dll
       
   642 		TUid specificUid = { reader.ReadInt32() };
       
   643 		
       
   644 		// Get the Dll entry point
       
   645 		TInt entryPoint(reader.ReadInt16());
       
   646 		
       
   647 		// Get version number
       
   648 		TInt major = reader.ReadInt16();
       
   649 		TInt minor = reader.ReadInt16();
       
   650 		TInt build = reader.ReadInt16();
       
   651 		TVersion version(major, minor, build);
       
   652 		
       
   653 		// Generate uid type
       
   654 		TUidType componentUidType(KDynamicLibraryUid, componentUid, specificUid);
       
   655 		
       
   656 		TPtrC mtmFilename;
       
   657 		if (specificUid.iUid == KUidMtmDefaultSpecificVal)
       
   658 			{
       
   659 			// We can assume the MTM resource file has been updated.
       
   660 			// The version number should be <= 2.0.
       
   661 			__ASSERT_DEBUG((version.iMajor < KMtmComponentCurrentMajorVersionNumber) || (version.iMajor == KMtmComponentCurrentMajorVersionNumber && version.iMinor == KMtmComponentCurrentMinorVersionNumber), PanicServer(EMsvBadMtmVersionNumber));
       
   662 
       
   663 			// Get filename
       
   664 			mtmFilename.Set(reader.ReadTPtrC());
       
   665 			}
       
   666 		// Add component info
       
   667 		CMtmDllInfo* mtmDllInfo = CMtmDllInfo::NewL(name, componentUidType, mtmFilename, entryPoint, version);
       
   668 		mtmDllInfo->SetMessagingCapability(capSend);
       
   669 		mtmDllInfo->SetSendBodyCapability(capBody);
       
   670 		mtmDllInfo->SetCapabilitiesAvailable(capAvailable);
       
   671 		mtmDllInfoArray->AddMtmDllInfoL(mtmDllInfo);
       
   672 		}
       
   673 	
       
   674 	// Are there any components?
       
   675 	if (mtmDllInfoArray->Count() == 0)
       
   676 		User::Leave(KErrNotFound);
       
   677 	
       
   678 
       
   679 	// The resource file *must* contain a security capability set once __SUPPORT_MESSAGING_API_V1__ is no longer defined
       
   680 	__ASSERT_DEBUG(file.OwnsResourceId(KMtmSecurityCapabilitySetResourceId), PanicServer(EMsvSecurityCapabilitySetResourceIsNotPresent));
       
   681 	HBufC8* securityResBuf = file.AllocReadLC(KMtmSecurityCapabilitySetResourceId);
       
   682 	reader.SetBuffer(securityResBuf);
       
   683 	TCapabilitySet mtmRequiredCaps;
       
   684 	MsvSecurityCapabilitySetUtils::ReadFromResourceL(reader,mtmRequiredCaps);
       
   685 	CleanupStack::PopAndDestroy(securityResBuf);
       
   686 	CleanupStack::Pop(mtmDllInfoArray);
       
   687 	// Generate the group data - transfer ownership of mtmDllInfoArray and mtmRequiredCaps
       
   688 	CMtmGroupData* mtmgroupdata = CMtmGroupData::NewL(mtmTypeUid, technologyTypeUid, mtmDllInfoArray, mtmRequiredCaps);
       
   689 
       
   690 
       
   691 
       
   692 	CleanupStack::PopAndDestroy(res);
       
   693 	CleanupStack::PopAndDestroy(&file);
       
   694 	return(mtmgroupdata);
       
   695 	}
       
   696 
       
   697 void CMtmRegistryControl::DoInstallMtmGroupL(const TDesC& aFullName,TUid& aMtmTypeUid)
       
   698 	{
       
   699 	aMtmTypeUid=KNullUid;
       
   700 	TUid uid;
       
   701 	CMtmGroupData* mtmgroupdata = LoadMTMFileL(aFullName,uid);
       
   702 	TInt index=MtmTypeUidToIndex(mtmgroupdata->MtmTypeUid());
       
   703 	if (index<iInstalledMtmGroupArray->Count())
       
   704 		{
       
   705 		delete mtmgroupdata;
       
   706 		User::Leave(KErrAlreadyExists);
       
   707 		}
       
   708 
       
   709 	// The following takes ownership of the group data
       
   710 	TUidType uidtype(KPermanentFileStoreLayoutUid, KUidMsvDataComponent, uid);
       
   711 	CInstalledMtmGroup* installedmtmgroup=CInstalledMtmGroup::NewL(uidtype,mtmgroupdata,aFullName);
       
   712 	aMtmTypeUid=mtmgroupdata->MtmTypeUid();
       
   713 
       
   714 	// Install the Mtm
       
   715 	AddInstalledMtmGroupL(installedmtmgroup);
       
   716 
       
   717 	//  Attempt to store registry
       
   718 	StoreRegistryL();
       
   719 	}
       
   720 
       
   721 CMtmGroupData* CMtmRegistryControl::ReadDataFileStoreL(const TDesC& aFullName) const
       
   722 	{
       
   723 	CFileStore* filestore = CPermanentFileStore::OpenLC(iFs,aFullName,EFileStream|EFileRead|EFileShareExclusive);
       
   724 	TStreamId streamid=filestore->Root();
       
   725 	RStoreReadStream readstream;
       
   726 	readstream.OpenLC(*filestore,streamid);
       
   727 	CMtmGroupData* mtmgroupdata=CMtmGroupData::NewL(readstream);
       
   728 	CleanupStack::PopAndDestroy(2);	// readstream, filestore
       
   729 	return mtmgroupdata;
       
   730 	}
       
   731 
       
   732 void CMtmRegistryControl::DoDeInstallMtmGroupL(TUid aMtmTypeUid)
       
   733 	{
       
   734 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   735 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   736 	__ASSERT_DEBUG(!IsInUse(aMtmTypeUid),PanicServer(EMtsrInstalledMtmGroupStillInUse));
       
   737 	CInstalledMtmGroup* installedmtmgroup=iInstalledMtmGroupArray->At(index);
       
   738 	installedmtmgroup->iIsInstalled=EFalse;
       
   739 	StoreRegistryL();
       
   740 	RemoveInstalledMtmGroup(aMtmTypeUid);
       
   741 	}
       
   742 
       
   743 void CMtmRegistryControl::DoInternalizeL(RReadStream& aStream)
       
   744 	{
       
   745 	iInstalledMtmGroupArray->ResetAndDestroy();
       
   746 	iServerMtmDllRegistry.RemoveAllRegisteredMtmDlls();
       
   747 	TInt count=aStream.ReadInt32L();
       
   748 	for (TInt i=0; i<count; i++)
       
   749 		{
       
   750 		HBufC *filename=HBufC::NewLC(aStream,KMaxFileName);
       
   751 		TUid uid=KNullUid;
       
   752 		CMtmGroupData *mtmgroupdata=NULL;
       
   753 		TRAPD(error,mtmgroupdata=LoadMTMFileL(*filename,uid));
       
   754 		if(error==KErrNone)
       
   755 			{
       
   756 			TUidType uidtype(KPermanentFileStoreLayoutUid, KUidMsvDataComponent, uid);
       
   757 			CInstalledMtmGroup* installedmtmgroup=CInstalledMtmGroup::NewL(uidtype,mtmgroupdata,*filename);
       
   758 			AddInstalledMtmGroupL(installedmtmgroup);
       
   759 			}
       
   760 		else if(error!=KErrNotFound)
       
   761 			{
       
   762 			User::Leave(error);
       
   763 			}
       
   764 		CleanupStack::PopAndDestroy(filename);		
       
   765 		}
       
   766 	User::LeaveIfError(FillRegisteredMtmDllArray(iServerMtmDllRegistry.iMtmDllTypeUid,iServerMtmDllRegistry.iRegisteredMtmDllArray,iServerMtmDllRegistry.iTimeoutMicroSeconds32));
       
   767 	}
       
   768 
       
   769 void CMtmRegistryControl::AddInstalledMtmGroupL(CInstalledMtmGroup* aInstalledMtmGroup)
       
   770 	{
       
   771 	iInstalledMtmGroupArray->AddInstalledMtmGroupL(aInstalledMtmGroup);
       
   772 	CMtmDllInfo* mtmdllinfo=aInstalledMtmGroup->iMtmGroupData->MtmDllInfoArray()[EMtsrServerComponentIndex];
       
   773 	if (mtmdllinfo->FileName().Length() > 0)
       
   774 		User::LeaveIfError(iServerMtmDllRegistry.AddRegisteredMtmDll(aInstalledMtmGroup->iMtmGroupData->MtmTypeUid(),aInstalledMtmGroup->iMtmGroupData->TechnologyTypeUid(),*mtmdllinfo,*this));	
       
   775 	}
       
   776 
       
   777 
       
   778 void CMtmRegistryControl::RemoveInstalledMtmGroup(TUid aMtmTypeUid)
       
   779 	{
       
   780 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   781 	if (index<iInstalledMtmGroupArray->Count())
       
   782 		{
       
   783 
       
   784 		delete iInstalledMtmGroupArray->At(index);
       
   785 		iInstalledMtmGroupArray->Delete(index);
       
   786 		}
       
   787 	if (iServerMtmDllRegistry.IsPresent(aMtmTypeUid))
       
   788 		iServerMtmDllRegistry.RemoveRegisteredMtmDll(aMtmTypeUid);
       
   789 	}
       
   790 
       
   791