messagingfw/msgsrvnstore/server/src/MTSR.CPP
changeset 22 bde600d88860
parent 0 8e480a14352b
child 34 b66b8f3a7fd8
child 39 e5b3a2155e1a
equal deleted inserted replaced
21:08008ce8a6df 22:bde600d88860
       
     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 
       
   179 EXPORT_C CServerMtmDllRegistry* CServerMtmDllRegistry::NewL(RFs& aFs,TTimeIntervalMicroSeconds32 aTimeoutMicroSeconds32)
       
   180 	{
       
   181 	return new(ELeave) CServerMtmDllRegistry(aFs,aTimeoutMicroSeconds32); 
       
   182 	}
       
   183 
       
   184 EXPORT_C CServerMtmDllRegistry::~CServerMtmDllRegistry()
       
   185 	{
       
   186 	}
       
   187 
       
   188 EXPORT_C CBaseServerMtm* CServerMtmDllRegistry::NewServerMtmL(TUid aMtmTypeUid, CMsvServerEntry* aInitialEntry)
       
   189 	{
       
   190 	CleanupStack::PushL(aInitialEntry); // Take ownership of the server entry
       
   191 
       
   192 	if(!IsPresent(aMtmTypeUid))
       
   193 		User::Leave(KErrNotFound);
       
   194 
       
   195 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   196 	CRegisteredMtmDll* registeredmtmdll=iRegisteredMtmDllArray[index];
       
   197 	RLibrary mtmdlllibrary;
       
   198 	User::LeaveIfError(registeredmtmdll->GetLibrary(iFs, mtmdlllibrary));
       
   199 	
       
   200 	TInt refcount = registeredmtmdll->MtmDllRefCount();
       
   201 	CBaseServerMtm* servermtm = NULL;
       
   202 	CleanupStack::Pop(); // aInitialEntry - function takes ownership of this
       
   203 
       
   204 	TRAPD(ret, servermtm = NewMtmL(mtmdlllibrary, aInitialEntry, *registeredmtmdll));
       
   205 
       
   206 	if ((ret!=KErrNone) && (registeredmtmdll->MtmDllRefCount()==refcount))  //  Library not released in mtm destructor
       
   207 		registeredmtmdll->ReleaseLibrary();
       
   208 	
       
   209 	User::LeaveIfError(ret);
       
   210 	return servermtm;
       
   211 	}
       
   212 
       
   213 CBaseServerMtm* CServerMtmDllRegistry::NewMtmL(const RLibrary& aLib, CMsvServerEntry* aServerEntry, CRegisteredMtmDll& aReg) const
       
   214 	{
       
   215 	CleanupStack::PushL(aServerEntry); // Take ownership of the server entry
       
   216 	typedef CBaseServerMtm*(*NewServerMtmL)(CRegisteredMtmDll& aRegisteredMtmDll, CMsvServerEntry* aInitialEntry);
       
   217 
       
   218 	TInt ordinal = aReg.MtmDllInfo().iEntryPointOrdinalNumber;
       
   219 	TLibraryFunction libFunc = aLib.Lookup(ordinal);
       
   220 	if (!libFunc)
       
   221 		User::Leave(KErrBadLibraryEntryPoint);
       
   222 
       
   223 	NewServerMtmL pFunc = (NewServerMtmL)libFunc;
       
   224 
       
   225 	CleanupStack::Pop(); // aServerEntry - mtm should take ownership of this
       
   226 	return (*pFunc)(aReg, aServerEntry);
       
   227 	}
       
   228 	
       
   229 CServerMtmDllRegistry::CServerMtmDllRegistry(RFs& aFs,TTimeIntervalMicroSeconds32 aTimeoutMicroSeconds32):
       
   230 	CMtmDllRegistry(aFs,KUidMtmServerComponent,aTimeoutMicroSeconds32)
       
   231 	{
       
   232 	__DECLARE_NAME(_S("CServerMtmDllRegistry"));
       
   233 	}
       
   234 
       
   235 CInstalledMtmGroupArray::CInstalledMtmGroupArray():
       
   236 	CArrayPtrFlat<CInstalledMtmGroup>(8)
       
   237 	{
       
   238 	}
       
   239 
       
   240 CInstalledMtmGroupArray::~CInstalledMtmGroupArray()
       
   241 	{
       
   242 	ResetAndDestroy();
       
   243 	}
       
   244 
       
   245 void CInstalledMtmGroupArray::AddInstalledMtmGroupL(CInstalledMtmGroup* aInstalledMtmGroup)
       
   246 	{
       
   247 	CleanupStack::PushL(aInstalledMtmGroup);
       
   248 	AppendL(aInstalledMtmGroup);
       
   249 	CleanupStack::Pop();
       
   250 	}
       
   251 
       
   252 
       
   253 EXPORT_C CMtmRegistryControl* CMtmRegistryControl::NewL(RFs& anFs,CServerMtmDllRegistry& aServerMtmDllRegistry)
       
   254 	{
       
   255 	CMtmRegistryControl* mtmregistrycontrol=new(ELeave) CMtmRegistryControl(anFs,aServerMtmDllRegistry);
       
   256 	CleanupStack::PushL(mtmregistrycontrol);
       
   257 	mtmregistrycontrol->ConstructL();
       
   258 	CleanupStack::Pop();
       
   259 	return mtmregistrycontrol;	
       
   260 	}
       
   261 
       
   262 EXPORT_C CMtmRegistryControl::~CMtmRegistryControl()
       
   263 	{
       
   264 	delete iInstalledMtmGroupArray;
       
   265 	}
       
   266 
       
   267 EXPORT_C TInt CMtmRegistryControl::InstallMtmGroup(const TDesC& aFullName,TUid& aMtmTypeUid)
       
   268 	{
       
   269 	aMtmTypeUid=KNullUid;
       
   270 
       
   271 	// Install the mtm
       
   272 	TRAPD(ret, DoInstallMtmGroupL(aFullName, aMtmTypeUid));
       
   273 	if ((ret!=KErrNone) && (aMtmTypeUid!=KNullUid))
       
   274 		RemoveInstalledMtmGroup(aMtmTypeUid);
       
   275 	return ret;
       
   276 	}
       
   277 
       
   278 EXPORT_C TInt CMtmRegistryControl::FullNameToMtmTypeUid(const TDesC& aFullName,TUid& aMtmTypeUid) const
       
   279 	{
       
   280 	aMtmTypeUid=KNullUid;
       
   281 	TRAPD(ret, aMtmTypeUid = DoFindMtmTypeUidL(aFullName));
       
   282 	if (ret==KErrNone)
       
   283 		{
       
   284 		TUidType uidtype(KPermanentFileStoreLayoutUid, KUidMsvDataComponent, aMtmTypeUid);
       
   285 		TInt index=UidTypeToIndex(uidtype);
       
   286 		if (index==iInstalledMtmGroupArray->Count())
       
   287 			ret=KErrNotFound;
       
   288 		else 
       
   289 			aMtmTypeUid=iInstalledMtmGroupArray->At(index)->iMtmGroupData->MtmTypeUid();
       
   290 		}
       
   291 	return ret;
       
   292 	}
       
   293 
       
   294 TBool CMtmRegistryControl::IsResFileL(const TDesC& aFullName) const
       
   295 	{
       
   296 	// Check the extension to see if it's a resource file
       
   297 	TParse parse;
       
   298 	User::LeaveIfError(parse.Set(aFullName, NULL, NULL));
       
   299 
       
   300 	// If first alpha character of extension is 'r' assume we're dealing with a resource file
       
   301 	TPtrC ext(parse.Ext());
       
   302 	return ext.Length() > 1 && TCharF(ext[1]) == TCharF('r');
       
   303 	}
       
   304 
       
   305 TUid CMtmRegistryControl::DoFindMtmTypeUidL(const TDesC& aFullName) const
       
   306 	{
       
   307 	TUid mtmTypeUid = KNullUid;
       
   308 
       
   309 	// Is the file a resource file?
       
   310 	if (!IsResFileL(aFullName))
       
   311 		{
       
   312 		// Get the third Uid
       
   313 		TEntry entry;
       
   314 		User::LeaveIfError(iFs.Entry(aFullName, entry));
       
   315 		mtmTypeUid = entry[2];
       
   316 		}
       
   317 	else
       
   318 		{
       
   319 		// Open the resource file
       
   320 		RResourceFile file;
       
   321 		file.OpenL(iFs, aFullName);
       
   322 		CleanupClosePushL(file);
       
   323 		HBufC8* res = file.AllocReadLC(1);
       
   324 		
       
   325 		// Interpret the resource buffer
       
   326 		TResourceReader reader;
       
   327 		reader.SetBuffer(res);
       
   328 
       
   329 		// Get the mtm type
       
   330 		mtmTypeUid = TUid::Uid(reader.ReadInt32());
       
   331 		CleanupStack::PopAndDestroy(2); // res, file
       
   332 		}
       
   333 
       
   334 	// Return the Uid Type
       
   335 	return mtmTypeUid;
       
   336 	}
       
   337 
       
   338 EXPORT_C TInt CMtmRegistryControl::DeInstallMtmGroup(TUid aMtmTypeUid)
       
   339 	{
       
   340 	TRAPD(ret,DoDeInstallMtmGroupL(aMtmTypeUid));
       
   341 	if (ret!=KErrNone)
       
   342 		{
       
   343 		TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   344 		iInstalledMtmGroupArray->At(index)->iIsInstalled=ETrue;
       
   345 		}
       
   346 	return ret;
       
   347 	}
       
   348 
       
   349 EXPORT_C TInt CMtmRegistryControl::UseMtmGroup(TUid aMtmTypeUid)
       
   350 	{
       
   351 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   352 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   353 	iInstalledMtmGroupArray->At(index)->iClientUsageCount++;	
       
   354 	return KErrNone;
       
   355 	}
       
   356 
       
   357 EXPORT_C TInt CMtmRegistryControl::ReleaseMtmGroup(TUid aMtmTypeUid)  
       
   358 	{
       
   359 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   360 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   361 	iInstalledMtmGroupArray->At(index)->iClientUsageCount--;	
       
   362 	return KErrNone;
       
   363 	}
       
   364 
       
   365 EXPORT_C TBool CMtmRegistryControl::IsInUse(TUid aMtmTypeUid) const
       
   366 	{
       
   367 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   368 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   369 	return (*iInstalledMtmGroupArray->At(index)).iClientUsageCount>0;
       
   370 	}
       
   371 
       
   372 EXPORT_C TInt CMtmRegistryControl::FillRegisteredMtmDllArray(TUid aMtmDllTypeUid,CRegisteredMtmDllArray& aRegisteredMtmDllArray,TTimeIntervalMicroSeconds32 aTimeoutMicroSeconds32)  // Fill array with Dlls whose second uid is aMtmDllTypeUid
       
   373 	{
       
   374 	aRegisteredMtmDllArray.ResetAndDestroy();  //  Trash the array
       
   375 	TUid mtmdlltypeuid[KMsvNumMtmDllTypes];  //  There must be an easier way to construct the array
       
   376 	mtmdlltypeuid[EMtsrServerComponentIndex]	=KUidMtmServerComponent;
       
   377 	mtmdlltypeuid[EMtsrClientComponentIndex]	=KUidMtmClientComponent;
       
   378 	mtmdlltypeuid[EMtsrUiComponentIndex]		=KUidMtmUiComponent;
       
   379 	mtmdlltypeuid[EMtsrUiDataComponentIndex]	=KUidMtmUiDataComponent;
       
   380 /*
       
   381 	mtmdlltypeuid[EMtsrDllTupe1Index]=KMsvDllType1Uid;
       
   382 	mtmdlltypeuid[EMtsrDllType2Index]=KMsvDllType2Uid;
       
   383 	mtmdlltypeuid[EMtsrDllType3Index]=KMsvDllType3Uid;
       
   384 	mtmdlltypeuid[EMtsrDllType4Index]=KMsvDllType4Uid;
       
   385 	mtmdlltypeuid[EMtsrDllType5Index]=KMsvDllType5Uid;
       
   386 	mtmdlltypeuid[EMtsrDllType6Index]=KMsvDllType6Uid;
       
   387 */
       
   388 	TInt index=0;
       
   389 	for (; (index<KMsvNumMtmDllTypes) && (aMtmDllTypeUid!=mtmdlltypeuid[index]); index++)
       
   390 		{
       
   391 		}
       
   392 	if (index==KMsvNumMtmDllTypes)
       
   393 		return KErrNotSupported;
       
   394 	TInt ret=KErrNone;
       
   395 	TInt count1=iInstalledMtmGroupArray->Count();
       
   396 	for (TInt i=0; i<count1; i++)
       
   397 		{
       
   398 		CMtmGroupData* mtmgroupdata=iInstalledMtmGroupArray->At(i)->iMtmGroupData;
       
   399 		TInt count2=mtmgroupdata->MtmDllInfoArray().Count();
       
   400 		if (index<count2)
       
   401 			{
       
   402 			CMtmDllInfo* mtmdllinfo=mtmgroupdata->MtmDllInfoArray()[index];
       
   403 			if (mtmdllinfo->iUidType[2]!=KNullUid)
       
   404 				{
       
   405 				TRAP(ret,
       
   406 					{	
       
   407 					CRegisteredMtmDll* registeredmtmdll=CRegisteredMtmDll::NewL(mtmgroupdata->MtmTypeUid(),mtmgroupdata->TechnologyTypeUid(),*mtmdllinfo,aTimeoutMicroSeconds32,*this);
       
   408 					
       
   409 					// The following takes ownership of registeredmtmdll
       
   410 					aRegisteredMtmDllArray.AddRegisteredMtmDllL(registeredmtmdll);
       
   411 					});
       
   412 
       
   413 				if (ret!=KErrNone)
       
   414 					{
       
   415 					aRegisteredMtmDllArray.ResetAndDestroy();
       
   416 					break;
       
   417 					}
       
   418 				}
       
   419 			}			
       
   420 		}
       
   421 	return ret;
       
   422 	}
       
   423 
       
   424 
       
   425 const CMtmGroupData& CMtmRegistryControl::GetMtmGroupDataReferenceL(TUid aMtmTypeUid) const
       
   426 	{
       
   427 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   428 	if (index==iInstalledMtmGroupArray->Count())
       
   429 		User::Leave(KErrNotFound);
       
   430 	
       
   431 	return *(iInstalledMtmGroupArray->At(index)->iMtmGroupData);
       
   432 	}
       
   433 
       
   434 EXPORT_C CMtmGroupData* CMtmRegistryControl::GetMtmGroupDataL(TUid aMtmTypeUid) const
       
   435 	{
       
   436 	return CMtmGroupData::NewL(GetMtmGroupDataReferenceL(aMtmTypeUid));
       
   437 	}
       
   438 
       
   439 EXPORT_C void CMtmRegistryControl::StoreRegistryL() const
       
   440 	{
       
   441 	TParse parsedname;
       
   442 	User::LeaveIfError(parsedname.Set(iPathName,NULL,NULL));
       
   443 	TInt ret=iFs.MkDirAll(parsedname.DriveAndPath());
       
   444 	if (ret!=KErrAlreadyExists)
       
   445 		User::LeaveIfError(ret);
       
   446 	CDictionaryFileStore* registryfilestore = CDictionaryFileStore::OpenLC(iFs,parsedname.FullName(),KUidRegistryFileStore);
       
   447 	RDictionaryWriteStream writestream;
       
   448 	writestream.AssignLC(*registryfilestore,KUidRegistryRootStream);
       
   449 	ExternalizeL(writestream);
       
   450 	writestream.CommitL();
       
   451 	writestream.Close();
       
   452 	registryfilestore->CommitL();
       
   453 	CleanupStack::PopAndDestroy(2);	// writestream and registryfilestore
       
   454 	}
       
   455 
       
   456 EXPORT_C void CMtmRegistryControl::RestoreRegistryL()
       
   457 	{
       
   458 	TParse parsedname;
       
   459 	User::LeaveIfError(parsedname.Set(iPathName,NULL,NULL));
       
   460 	TEntry entry;
       
   461 	User::LeaveIfError(iFs.Entry(parsedname.FullName(),entry));
       
   462 	CDictionaryFileStore* registryfilestore = CDictionaryFileStore::OpenLC(iFs,parsedname.FullName(),KUidRegistryFileStore);
       
   463 	RDictionaryReadStream readstream;
       
   464 	readstream.OpenLC(*registryfilestore,KUidRegistryRootStream);
       
   465 	InternalizeL(readstream);
       
   466 	readstream.Close();
       
   467 	CleanupStack::PopAndDestroy();// readstream
       
   468 	CleanupStack::PopAndDestroy();	// registryfilestore
       
   469 	}
       
   470 
       
   471 EXPORT_C void CMtmRegistryControl::InternalizeL(RReadStream& aStream)
       
   472 	{
       
   473 	__ASSERT_DEBUG(iInstalledMtmGroupArray->Count()==0,PanicServer(EMtsrRegistryControlStillInUse));
       
   474 	TRAPD(ret,DoInternalizeL(aStream))
       
   475 	if (ret!=KErrNone)
       
   476 		{
       
   477 		iInstalledMtmGroupArray->ResetAndDestroy();
       
   478 		iServerMtmDllRegistry.RemoveAllRegisteredMtmDlls();
       
   479 		User::Leave(ret);
       
   480 		}
       
   481 	}
       
   482 
       
   483 EXPORT_C void CMtmRegistryControl::ExternalizeL(RWriteStream& aStream) const
       
   484 	{
       
   485 	TInt count1=iInstalledMtmGroupArray->Count(),count2=0;
       
   486 	TInt i=0;
       
   487 	for (; i<count1; i++)
       
   488 		if ((*iInstalledMtmGroupArray->At(i)).iIsInstalled)
       
   489 			count2++;
       
   490 	aStream.WriteInt32L(count2);
       
   491 	for (i=0; i<count1; i++)
       
   492 		if ((*iInstalledMtmGroupArray->At(i)).iIsInstalled)
       
   493 			aStream << *(iInstalledMtmGroupArray->At(i)->iFilename);
       
   494 	}
       
   495 
       
   496 CMtmRegistryControl::CMtmRegistryControl(RFs& anFs,CServerMtmDllRegistry& aServerMtmDllRegistry):
       
   497 	iFs(anFs),
       
   498 	iInstalledMtmGroupArray(),
       
   499 	iServerMtmDllRegistry(aServerMtmDllRegistry)
       
   500 	{
       
   501 	__DECLARE_NAME(_S("CMtmRegistryControl"));
       
   502 	}
       
   503 
       
   504 void CMtmRegistryControl::ConstructL()
       
   505 	{
       
   506 	iInstalledMtmGroupArray = new(ELeave) CInstalledMtmGroupArray();
       
   507 
       
   508 	TChar iDriveChar= iFs.GetSystemDriveChar();
       
   509 	TBuf<2> systemDrive;
       
   510 	systemDrive.Append(iDriveChar);
       
   511 	systemDrive.Append(KDriveDelimiter);
       
   512 	iPathName=systemDrive;
       
   513 	iPathName.Append(KDefaultRegistryFileStoreName);
       
   514 	
       
   515 	TRAPD(ret,RestoreRegistryL());  
       
   516 	//should not delete registry if in use
       
   517 	if ((ret!=KErrNone) && (ret!=KErrInUse))
       
   518 		{
       
   519 		//ignore error if we can't delete a corrupt file; StoreRegistryL will leave
       
   520 		iFs.SetAtt(iPathName,0,KEntryAttReadOnly|KEntryAttHidden|KEntryAttSystem);
       
   521 		iFs.Delete(iPathName);
       
   522 		StoreRegistryL();
       
   523 		}
       
   524 	}
       
   525 
       
   526 TInt CMtmRegistryControl::MtmTypeUidToIndex(TUid aMtmTypeUid) const
       
   527 	{
       
   528 	TInt count=iInstalledMtmGroupArray->Count();
       
   529 	TInt index=0;
       
   530 	for (; (index<count) && (iInstalledMtmGroupArray->At(index)->iMtmGroupData->MtmTypeUid()!=aMtmTypeUid); index++)
       
   531 		{
       
   532 		}
       
   533 	return index;
       
   534 	}
       
   535 
       
   536 TInt CMtmRegistryControl::UidTypeToIndex(TUidType aUidType) const
       
   537 	{
       
   538 	TInt count=iInstalledMtmGroupArray->Count();
       
   539 	TInt index=0;
       
   540 	for (; (index<count) && (iInstalledMtmGroupArray->At(index)->iUidType!=aUidType); index++)
       
   541 		{
       
   542 		}
       
   543 	return index;
       
   544 	}
       
   545 
       
   546 CMtmGroupData *CMtmRegistryControl::LoadMTMFileL(const TDesC& aFullName, TUid &aUid)
       
   547 	{
       
   548 	if(IsResFileL(aFullName)==EFalse)
       
   549 		return(LoadDatFileL(aFullName, aUid));
       
   550 	else
       
   551 		return(LoadResFileL(aFullName, aUid));
       
   552 	}
       
   553 
       
   554 CMtmGroupData *CMtmRegistryControl::LoadDatFileL(const TDesC& aFullName, TUid &aUid)
       
   555 	{
       
   556 	TEntry entry;
       
   557 	User::LeaveIfError(iFs.Entry(aFullName,entry));  //  Check file exists
       
   558 	if ((entry[0]!=KPermanentFileStoreLayoutUid) || (entry[1]!=KUidMsvDataComponent))
       
   559 		User::Leave(KErrNotSupported);
       
   560 	aUid=entry[2];
       
   561 	CMtmGroupData* mtmgroupdata=ReadDataFileStoreL(aFullName);
       
   562 	return(mtmgroupdata);
       
   563 	}
       
   564 
       
   565 
       
   566 CMtmGroupData *CMtmRegistryControl::LoadResFileL(const TDesC& aFullName, TUid &aUid)
       
   567 	{
       
   568 	TFileName fileName(aFullName);
       
   569 	_LIT(KRssFileExtension, ".rsc");
       
   570 
       
   571 	TParsePtrC filenamePPtr(fileName);
       
   572 	TPtrC ext =filenamePPtr.Ext();
       
   573 	if(ext!=(KRssFileExtension)) 
       
   574 		{ //if ext is not .rsc, replace with rsc.  Always pass *.rsc to the BaflUtils::NearestLanguageFile
       
   575 		TInt pos=fileName.FindF(ext);
       
   576 		fileName.Replace(pos,fileName.Length()-pos,KRssFileExtension);
       
   577 		}
       
   578 	BaflUtils::NearestLanguageFile(iFs, fileName);
       
   579 
       
   580 	// Open the resource file	
       
   581 	RResourceFile file;
       
   582 	file.OpenL(iFs, fileName);
       
   583 	CleanupClosePushL(file);
       
   584 	HBufC8* res = file.AllocReadLC(KMtmInfoFileResourceId);
       
   585 
       
   586 	// Attempt to get the capabilities resource
       
   587 	HBufC8* cap = NULL;
       
   588 
       
   589 	TRAPD(error,cap = file.AllocReadL(KMtmCapabilitiesResourceId));
       
   590 	TBool capAvailable = EFalse;
       
   591 	TBool capSend = EFalse;
       
   592 	TBool capBody = EFalse;
       
   593 	if (error == KErrNone)
       
   594 		{
       
   595 		CleanupStack::PushL(cap);
       
   596 		capAvailable = ETrue;
       
   597 		TResourceReader capReader;
       
   598 		capReader.SetBuffer(cap);
       
   599 		// Get the send capability
       
   600 		capSend = capReader.ReadInt8();
       
   601 		// Get the body capability
       
   602 		capBody = capReader.ReadInt8();
       
   603 
       
   604 		CleanupStack::PopAndDestroy(cap);
       
   605 		}
       
   606 
       
   607 	// Interpret the resource buffer
       
   608 	TResourceReader reader;
       
   609 	reader.SetBuffer(res);
       
   610 	
       
   611 	// Get the mtm type
       
   612 	TUid mtmTypeUid = { reader.ReadInt32() };
       
   613 	aUid=mtmTypeUid;
       
   614 		
       
   615 	CMtmDllInfoArray* mtmDllInfoArray = new(ELeave) CMtmDllInfoArray();
       
   616 	CleanupStack::PushL(mtmDllInfoArray);
       
   617 	
       
   618 	// Get technology type
       
   619 	TUid technologyTypeUid = { reader.ReadInt32() };
       
   620 	
       
   621 	// Get number of mtm components
       
   622 	TInt components(reader.ReadInt16());
       
   623 	while(components--)
       
   624 		{
       
   625 		// Get the name of the component
       
   626 		TPtrC name(reader.ReadTPtrC());
       
   627 		
       
   628 		// Get the type of component
       
   629 		TUid componentUid = { reader.ReadInt32() };
       
   630 		
       
   631 		// Get specific Uid of the Dll
       
   632 		TUid specificUid = { reader.ReadInt32() };
       
   633 		
       
   634 		// Get the Dll entry point
       
   635 		TInt entryPoint(reader.ReadInt16());
       
   636 		
       
   637 		// Get version number
       
   638 		TInt major = reader.ReadInt16();
       
   639 		TInt minor = reader.ReadInt16();
       
   640 		TInt build = reader.ReadInt16();
       
   641 		TVersion version(major, minor, build);
       
   642 		
       
   643 		// Generate uid type
       
   644 		TUidType componentUidType(KDynamicLibraryUid, componentUid, specificUid);
       
   645 		
       
   646 		TPtrC mtmFilename;
       
   647 		if (specificUid.iUid == KUidMtmDefaultSpecificVal)
       
   648 			{
       
   649 			// We can assume the MTM resource file has been updated.
       
   650 			// The version number should be <= 2.0.
       
   651 			__ASSERT_DEBUG((version.iMajor < KMtmComponentCurrentMajorVersionNumber) || (version.iMajor == KMtmComponentCurrentMajorVersionNumber && version.iMinor == KMtmComponentCurrentMinorVersionNumber), PanicServer(EMsvBadMtmVersionNumber));
       
   652 
       
   653 			// Get filename
       
   654 			mtmFilename.Set(reader.ReadTPtrC());
       
   655 			}
       
   656 		// Add component info
       
   657 		CMtmDllInfo* mtmDllInfo = CMtmDllInfo::NewL(name, componentUidType, mtmFilename, entryPoint, version);
       
   658 		mtmDllInfo->SetMessagingCapability(capSend);
       
   659 		mtmDllInfo->SetSendBodyCapability(capBody);
       
   660 		mtmDllInfo->SetCapabilitiesAvailable(capAvailable);
       
   661 		mtmDllInfoArray->AddMtmDllInfoL(mtmDllInfo);
       
   662 		}
       
   663 	
       
   664 	// Are there any components?
       
   665 	if (mtmDllInfoArray->Count() == 0)
       
   666 		User::Leave(KErrNotFound);
       
   667 	
       
   668 
       
   669 	// The resource file *must* contain a security capability set once __SUPPORT_MESSAGING_API_V1__ is no longer defined
       
   670 	__ASSERT_DEBUG(file.OwnsResourceId(KMtmSecurityCapabilitySetResourceId), PanicServer(EMsvSecurityCapabilitySetResourceIsNotPresent));
       
   671 	HBufC8* securityResBuf = file.AllocReadLC(KMtmSecurityCapabilitySetResourceId);
       
   672 	reader.SetBuffer(securityResBuf);
       
   673 	TCapabilitySet mtmRequiredCaps;
       
   674 	MsvSecurityCapabilitySetUtils::ReadFromResourceL(reader,mtmRequiredCaps);
       
   675 	CleanupStack::PopAndDestroy(securityResBuf);
       
   676 	CleanupStack::Pop(mtmDllInfoArray);
       
   677 	// Generate the group data - transfer ownership of mtmDllInfoArray and mtmRequiredCaps
       
   678 	CMtmGroupData* mtmgroupdata = CMtmGroupData::NewL(mtmTypeUid, technologyTypeUid, mtmDllInfoArray, mtmRequiredCaps);
       
   679 
       
   680 
       
   681 
       
   682 	CleanupStack::PopAndDestroy(res);
       
   683 	CleanupStack::PopAndDestroy(&file);
       
   684 	return(mtmgroupdata);
       
   685 	}
       
   686 
       
   687 void CMtmRegistryControl::DoInstallMtmGroupL(const TDesC& aFullName,TUid& aMtmTypeUid)
       
   688 	{
       
   689 	aMtmTypeUid=KNullUid;
       
   690 	TUid uid;
       
   691 	CMtmGroupData* mtmgroupdata = LoadMTMFileL(aFullName,uid);
       
   692 	TInt index=MtmTypeUidToIndex(mtmgroupdata->MtmTypeUid());
       
   693 	if (index<iInstalledMtmGroupArray->Count())
       
   694 		{
       
   695 		delete mtmgroupdata;
       
   696 		User::Leave(KErrAlreadyExists);
       
   697 		}
       
   698 
       
   699 	// The following takes ownership of the group data
       
   700 	TUidType uidtype(KPermanentFileStoreLayoutUid, KUidMsvDataComponent, uid);
       
   701 	CInstalledMtmGroup* installedmtmgroup=CInstalledMtmGroup::NewL(uidtype,mtmgroupdata,aFullName);
       
   702 	aMtmTypeUid=mtmgroupdata->MtmTypeUid();
       
   703 
       
   704 	// Install the Mtm
       
   705 	AddInstalledMtmGroupL(installedmtmgroup);
       
   706 
       
   707 	//  Attempt to store registry
       
   708 	StoreRegistryL();
       
   709 	}
       
   710 
       
   711 CMtmGroupData* CMtmRegistryControl::ReadDataFileStoreL(const TDesC& aFullName) const
       
   712 	{
       
   713 	CFileStore* filestore = CPermanentFileStore::OpenLC(iFs,aFullName,EFileStream|EFileRead|EFileShareExclusive);
       
   714 	TStreamId streamid=filestore->Root();
       
   715 	RStoreReadStream readstream;
       
   716 	readstream.OpenLC(*filestore,streamid);
       
   717 	CMtmGroupData* mtmgroupdata=CMtmGroupData::NewL(readstream);
       
   718 	CleanupStack::PopAndDestroy(2);	// readstream, filestore
       
   719 	return mtmgroupdata;
       
   720 	}
       
   721 
       
   722 void CMtmRegistryControl::DoDeInstallMtmGroupL(TUid aMtmTypeUid)
       
   723 	{
       
   724 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   725 	__ASSERT_DEBUG(index<iInstalledMtmGroupArray->Count(),PanicServer(EMtsrInstalledMtmGroupNotPresent));
       
   726 	__ASSERT_DEBUG(!IsInUse(aMtmTypeUid),PanicServer(EMtsrInstalledMtmGroupStillInUse));
       
   727 	CInstalledMtmGroup* installedmtmgroup=iInstalledMtmGroupArray->At(index);
       
   728 	installedmtmgroup->iIsInstalled=EFalse;
       
   729 	StoreRegistryL();
       
   730 	RemoveInstalledMtmGroup(aMtmTypeUid);
       
   731 	}
       
   732 
       
   733 void CMtmRegistryControl::DoInternalizeL(RReadStream& aStream)
       
   734 	{
       
   735 	iInstalledMtmGroupArray->ResetAndDestroy();
       
   736 	iServerMtmDllRegistry.RemoveAllRegisteredMtmDlls();
       
   737 	TInt count=aStream.ReadInt32L();
       
   738 	for (TInt i=0; i<count; i++)
       
   739 		{
       
   740 		HBufC *filename=HBufC::NewLC(aStream,KMaxFileName);
       
   741 		TUid uid=KNullUid;
       
   742 		CMtmGroupData *mtmgroupdata=NULL;
       
   743 		TRAPD(error,mtmgroupdata=LoadMTMFileL(*filename,uid));
       
   744 		if(error==KErrNone)
       
   745 			{
       
   746 			TUidType uidtype(KPermanentFileStoreLayoutUid, KUidMsvDataComponent, uid);
       
   747 			CInstalledMtmGroup* installedmtmgroup=CInstalledMtmGroup::NewL(uidtype,mtmgroupdata,*filename);
       
   748 			AddInstalledMtmGroupL(installedmtmgroup);
       
   749 			}
       
   750 		else if(error!=KErrNotFound)
       
   751 			{
       
   752 			User::Leave(error);
       
   753 			}
       
   754 		CleanupStack::PopAndDestroy(filename);		
       
   755 		}
       
   756 	User::LeaveIfError(FillRegisteredMtmDllArray(iServerMtmDllRegistry.iMtmDllTypeUid,iServerMtmDllRegistry.iRegisteredMtmDllArray,iServerMtmDllRegistry.iTimeoutMicroSeconds32));
       
   757 	}
       
   758 
       
   759 void CMtmRegistryControl::AddInstalledMtmGroupL(CInstalledMtmGroup* aInstalledMtmGroup)
       
   760 	{
       
   761 	iInstalledMtmGroupArray->AddInstalledMtmGroupL(aInstalledMtmGroup);
       
   762 	CMtmDllInfo* mtmdllinfo=aInstalledMtmGroup->iMtmGroupData->MtmDllInfoArray()[EMtsrServerComponentIndex];
       
   763 	if (mtmdllinfo->FileName().Length() > 0)
       
   764 		User::LeaveIfError(iServerMtmDllRegistry.AddRegisteredMtmDll(aInstalledMtmGroup->iMtmGroupData->MtmTypeUid(),aInstalledMtmGroup->iMtmGroupData->TechnologyTypeUid(),*mtmdllinfo,*this));	
       
   765 	}
       
   766 
       
   767 
       
   768 void CMtmRegistryControl::RemoveInstalledMtmGroup(TUid aMtmTypeUid)
       
   769 	{
       
   770 	TInt index=MtmTypeUidToIndex(aMtmTypeUid);
       
   771 	if (index<iInstalledMtmGroupArray->Count())
       
   772 		{
       
   773 
       
   774 		delete iInstalledMtmGroupArray->At(index);
       
   775 		iInstalledMtmGroupArray->Delete(index);
       
   776 		}
       
   777 	if (iServerMtmDllRegistry.IsPresent(aMtmTypeUid))
       
   778 		iServerMtmDllRegistry.RemoveRegisteredMtmDll(aMtmTypeUid);
       
   779 	}
       
   780 
       
   781