os/security/contentmgmt/contentaccessfwfordrm/source/caf/resolver.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <e32debug.h>
sl@0
    20
#include <ecom/ecom.h>
sl@0
    21
sl@0
    22
#include "resolver.h"
sl@0
    23
#include <caf/agentfactory.h>
sl@0
    24
#include <caf/agentinterface.h>
sl@0
    25
#include "agentinfo.h"
sl@0
    26
#include <caf/agent.h>
sl@0
    27
#include <caf/cafpanic.h>
sl@0
    28
#include <caf/caferr.h>
sl@0
    29
#include <caf/patchdata.h>
sl@0
    30
sl@0
    31
sl@0
    32
using namespace ContentAccess;
sl@0
    33
sl@0
    34
// Constants for the F32 agent
sl@0
    35
_LIT(KF32Agent,"F32 CA Agent");
sl@0
    36
sl@0
    37
sl@0
    38
_LIT(KParentDir, "..\\");
sl@0
    39
_LIT(KPrivateDir, "\\private\\");
sl@0
    40
const TInt KPrivateDirLength = 9;   // "\\private\\"
sl@0
    41
const TInt KPrivateDirAndDriveLength = 11;   // "x:\\private\\"
sl@0
    42
const TInt KPrivateDirOffset = 2; // "x:\\"
sl@0
    43
sl@0
    44
sl@0
    45
EXPORT_C CAgentResolver* CAgentResolver::NewLC(const TBool aDynamicAgentUpdate)
sl@0
    46
	{
sl@0
    47
	CAgentResolver* self = new (ELeave) CAgentResolver(aDynamicAgentUpdate);
sl@0
    48
	CleanupStack::PushL(self);
sl@0
    49
	self->ConstructL();
sl@0
    50
	return self;
sl@0
    51
	}
sl@0
    52
sl@0
    53
EXPORT_C CAgentResolver* CAgentResolver::NewL(const TBool aDynamicAgentUpdate)
sl@0
    54
	{
sl@0
    55
	CAgentResolver* self = CAgentResolver::NewLC(aDynamicAgentUpdate);
sl@0
    56
	CleanupStack::Pop(self);
sl@0
    57
	return self;
sl@0
    58
	}
sl@0
    59
sl@0
    60
CAgentResolver::CAgentResolver(const TBool aDynamicAgentUpdate) : CActive(EPriorityStandard), iDynamicAgentUpdate(aDynamicAgentUpdate)
sl@0
    61
	{
sl@0
    62
	}
sl@0
    63
sl@0
    64
CAgentResolver::~CAgentResolver()
sl@0
    65
	{
sl@0
    66
	// remove ourselves from the ActiveScheduler
sl@0
    67
	if(IsAdded())
sl@0
    68
		{
sl@0
    69
		Deque();
sl@0
    70
		}
sl@0
    71
	
sl@0
    72
	// Unload all the agents
sl@0
    73
	DestroyListOfAgents();
sl@0
    74
	
sl@0
    75
	// Close our ECOM session
sl@0
    76
	if(iEcomSession)
sl@0
    77
		{
sl@0
    78
		if(iDynamicAgentUpdate)
sl@0
    79
			{
sl@0
    80
			iEcomSession->CancelNotifyOnChange(iStatus);
sl@0
    81
			}
sl@0
    82
		iEcomSession->Close();
sl@0
    83
		REComSession::FinalClose();
sl@0
    84
		}
sl@0
    85
sl@0
    86
	iSupplierMimeTypes.Close();
sl@0
    87
	iConsumerMimeTypes.Close();
sl@0
    88
	iAgentInfos.Close();
sl@0
    89
	}
sl@0
    90
sl@0
    91
void CAgentResolver::ConstructL()
sl@0
    92
	{
sl@0
    93
	if(iDynamicAgentUpdate)
sl@0
    94
		{
sl@0
    95
		// Add ourselves to the current active scheduler so we can get dynamic 
sl@0
    96
		// updates when agents are removed or new agents are added
sl@0
    97
		CActiveScheduler::Add(this);
sl@0
    98
		}
sl@0
    99
sl@0
   100
	iEcomSession = &REComSession::OpenL();
sl@0
   101
	
sl@0
   102
	// find all the agents
sl@0
   103
	BuildListOfAgentsL();
sl@0
   104
sl@0
   105
	if(iDynamicAgentUpdate)
sl@0
   106
		{
sl@0
   107
		// register for ECOM update notifications in case a new agent appears
sl@0
   108
		SetActive();
sl@0
   109
		iEcomSession->NotifyOnChange(iStatus);
sl@0
   110
		}
sl@0
   111
	}
sl@0
   112
sl@0
   113
void CAgentResolver::BuildListOfAgentsL()
sl@0
   114
	{
sl@0
   115
	TInt err = KErrNone;
sl@0
   116
sl@0
   117
	// Get all plugins which implement the agent interface
sl@0
   118
	RImplInfoPtrArray implArray;
sl@0
   119
	CleanupStack::PushL(TCleanupItem(CleanImplArray, &implArray));
sl@0
   120
	REComSession::ListImplementationsL(KCAAgentInterfaceUid, implArray);
sl@0
   121
sl@0
   122
	for (TInt i = 0; i < implArray.Count(); ++i)
sl@0
   123
		{
sl@0
   124
#ifdef __EPOC32__
sl@0
   125
		// On hardware - to load agents from sources other than ROM the patch 
sl@0
   126
		// data KCafLoadPostProductionAgents must be set to True (non-zero).
sl@0
   127
		// Default SymbianOS behavior is to only load agents from ROM
sl@0
   128
		if ((KCafLoadPostProductionAgents == 0) &&
sl@0
   129
            !implArray[i]->RomBased())
sl@0
   130
			{
sl@0
   131
			// If the agent is not in ROM, don't load it because it might
sl@0
   132
			// be a security risk.
sl@0
   133
			continue;
sl@0
   134
			}
sl@0
   135
#endif
sl@0
   136
sl@0
   137
		// Construct all the agent infos from these implementations
sl@0
   138
		TRAP(err, AddAgentL(*implArray[i]));
sl@0
   139
sl@0
   140
		// If we ran out of memory proagate the leave to the caller
sl@0
   141
		// otherwise don't let a dodgy agent affect the construction of the other
sl@0
   142
		// agents
sl@0
   143
		if(err == KErrNoMemory)
sl@0
   144
			{
sl@0
   145
			User::Leave(KErrNoMemory);
sl@0
   146
			}
sl@0
   147
		}
sl@0
   148
	CleanupStack::PopAndDestroy(&implArray);  
sl@0
   149
sl@0
   150
sl@0
   151
	if (!iDefaultAgent)
sl@0
   152
		{
sl@0
   153
		// If we didn't find a default agent, we have a big problem so panic
sl@0
   154
		User::Panic(KCafPanicString, ECafPanicNoF32Agent);
sl@0
   155
		}
sl@0
   156
	}
sl@0
   157
sl@0
   158
void CAgentResolver::AddAgentL(const CImplementationInformation& aImplInfo)
sl@0
   159
	{
sl@0
   160
	// Create a CAgentInfo instance
sl@0
   161
	CAgentInfo* agentInfo = CAgentInfo::NewLC(aImplInfo);
sl@0
   162
sl@0
   163
sl@0
   164
	if(IsF32Agent(*agentInfo))
sl@0
   165
		{
sl@0
   166
		// It's the F32 Agent
sl@0
   167
		if(iDefaultAgent)
sl@0
   168
			{
sl@0
   169
			// If we already have a default agent something is seriously wrong
sl@0
   170
			User::Panic(KCafPanicString, ECafPanicDuplicateF32Agent);
sl@0
   171
			}
sl@0
   172
sl@0
   173
		// Note that the default agent is NOT stored in the agents list, it is a special case
sl@0
   174
		iDefaultAgent = agentInfo;
sl@0
   175
		CleanupStack::Pop(agentInfo);
sl@0
   176
		}
sl@0
   177
	else
sl@0
   178
		{
sl@0
   179
		// All other agents go in the agent list
sl@0
   180
		User::LeaveIfError(iAgentInfos.Append(agentInfo));
sl@0
   181
		CleanupStack::Pop(agentInfo);
sl@0
   182
sl@0
   183
		TInt mimeIndex=0;
sl@0
   184
sl@0
   185
		// Update our list of all supplier mime types supported by CAF
sl@0
   186
		for(mimeIndex=0;mimeIndex < agentInfo->SupplierMimeTypes().Count(); mimeIndex++) 
sl@0
   187
			{
sl@0
   188
			User::LeaveIfError(iSupplierMimeTypes.Append(*agentInfo->SupplierMimeTypes()[mimeIndex]));
sl@0
   189
			}
sl@0
   190
sl@0
   191
		// Update our list of all consumer mime types supported by CAF
sl@0
   192
		for(mimeIndex=0;mimeIndex < agentInfo->ConsumerMimeTypes().Count(); mimeIndex++) 
sl@0
   193
			{
sl@0
   194
			User::LeaveIfError(iConsumerMimeTypes.Append(*agentInfo->ConsumerMimeTypes()[mimeIndex]));
sl@0
   195
			}
sl@0
   196
		}
sl@0
   197
	}
sl@0
   198
sl@0
   199
void CAgentResolver::DestroyListOfAgents()
sl@0
   200
	{
sl@0
   201
	iSupplierMimeTypes.Reset();
sl@0
   202
	iConsumerMimeTypes.Reset();
sl@0
   203
sl@0
   204
	// cant forget to delete the default agent
sl@0
   205
	delete iDefaultAgent;
sl@0
   206
	iDefaultAgent = NULL;
sl@0
   207
sl@0
   208
	// Free memory assocated with the iAgentInfos array 
sl@0
   209
	iAgentInfos.ResetAndDestroy();
sl@0
   210
	}
sl@0
   211
sl@0
   212
void CAgentResolver::DoCancel()
sl@0
   213
	{
sl@0
   214
	// Abort any update notification 
sl@0
   215
	iEcomSession->CancelNotifyOnChange(iStatus);
sl@0
   216
	}
sl@0
   217
sl@0
   218
void CAgentResolver::RunL()
sl@0
   219
	{
sl@0
   220
	// Called by the ECOM framework if a new agent appears
sl@0
   221
sl@0
   222
	// remove the existing list of agents and build a new one
sl@0
   223
	DestroyListOfAgents();
sl@0
   224
	BuildListOfAgentsL();
sl@0
   225
sl@0
   226
	// request notification of any further changes
sl@0
   227
	iEcomSession->NotifyOnChange(iStatus);
sl@0
   228
	SetActive();
sl@0
   229
	}	
sl@0
   230
sl@0
   231
TBool CAgentResolver::IsF32Agent(CAgentInfo& aAgentInfo)
sl@0
   232
	{
sl@0
   233
	// Check if the agent has no consumer or supplier mime types
sl@0
   234
	// and that it has the correct name and Uid
sl@0
   235
	if (aAgentInfo.Agent().ImplementationUid() == KF32AgentImplUid
sl@0
   236
		&& aAgentInfo.Agent().Name().Compare(KF32Agent()) == 0 
sl@0
   237
		&& aAgentInfo.ConsumerMimeTypes().Count() == 0 
sl@0
   238
		&& aAgentInfo.SupplierMimeTypes().Count() == 0)
sl@0
   239
		{
sl@0
   240
		return ETrue;
sl@0
   241
		}
sl@0
   242
	else
sl@0
   243
		{
sl@0
   244
		return EFalse;
sl@0
   245
		}
sl@0
   246
	}
sl@0
   247
sl@0
   248
CAgentInfo& CAgentResolver::ResolveSupplierMimeL(const TDesC8& aMimeType) const
sl@0
   249
	{
sl@0
   250
	// Go through all the agents and return the one which supports the
sl@0
   251
	// required supplier mime type
sl@0
   252
	CAgentInfo* retVal=NULL;
sl@0
   253
sl@0
   254
	for (TInt i = 0; i < iAgentInfos.Count(); ++i)
sl@0
   255
		{
sl@0
   256
		if (iAgentInfos[i]->IsSupportedSupplier(aMimeType))
sl@0
   257
			{
sl@0
   258
			retVal = iAgentInfos[i];
sl@0
   259
			break;
sl@0
   260
			}
sl@0
   261
		}
sl@0
   262
	
sl@0
   263
	if (!retVal)
sl@0
   264
		{
sl@0
   265
		User::Leave(KErrCANoAgent);
sl@0
   266
		}
sl@0
   267
	return *retVal;
sl@0
   268
	}
sl@0
   269
sl@0
   270
CAgentInfo& CAgentResolver::ResolveConsumerMime(const TDesC8& aMimeType) const
sl@0
   271
	{
sl@0
   272
	// By default, set the return value to be the default agent. If we find
sl@0
   273
	// anything better, then we change it
sl@0
   274
	CAgentInfo* retVal = iDefaultAgent;
sl@0
   275
sl@0
   276
	for (TInt i = 0; i < iAgentInfos.Count(); ++i)
sl@0
   277
		{
sl@0
   278
		if (iAgentInfos[i]->IsSupportedConsumer(aMimeType))
sl@0
   279
			{
sl@0
   280
			retVal = iAgentInfos[i];
sl@0
   281
			break;
sl@0
   282
			}
sl@0
   283
		}
sl@0
   284
sl@0
   285
	ASSERT(retVal);
sl@0
   286
	return *retVal;
sl@0
   287
	}
sl@0
   288
sl@0
   289
CAgentInfo& CAgentResolver::ResolveFileL(const TDesC& aURI, TDes& aActualUri, TContentShareMode aShareMode) const
sl@0
   290
	{
sl@0
   291
	// Go through all the agents and return the one which supports the file at the given URI	
sl@0
   292
	TBool thePrivateDir = EFalse;	
sl@0
   293
	TUid agentUid = ResolveDirectory(aURI, aActualUri, thePrivateDir);
sl@0
   294
	
sl@0
   295
	if(agentUid != iDefaultAgent->Agent().ImplementationUid())
sl@0
   296
		{
sl@0
   297
		// this file must be living in a private server directory
sl@0
   298
		// return the agent who owns the directory
sl@0
   299
		return AgentInfoL(agentUid);
sl@0
   300
		}
sl@0
   301
	else
sl@0
   302
		{
sl@0
   303
		TInt agentsCount(iAgentInfos.Count());
sl@0
   304
		CAgentManager* agentManager = NULL;
sl@0
   305
		for (TInt i = 0; i < agentsCount; ++i)
sl@0
   306
			{
sl@0
   307
			TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL());
sl@0
   308
			if(result != KErrNone)
sl@0
   309
				{
sl@0
   310
				if(KErrNoMemory == result)
sl@0
   311
					{
sl@0
   312
					User::Leave(result);
sl@0
   313
					}
sl@0
   314
				else
sl@0
   315
					{
sl@0
   316
					continue;	
sl@0
   317
					}
sl@0
   318
				}
sl@0
   319
			if (agentManager->IsRecognizedL(aURI, aShareMode))
sl@0
   320
				{
sl@0
   321
				return *iAgentInfos[i];
sl@0
   322
				}
sl@0
   323
			}
sl@0
   324
		}
sl@0
   325
	return *iDefaultAgent;
sl@0
   326
	}
sl@0
   327
sl@0
   328
CAgentInfo& CAgentResolver::ResolveFileL(RFile& aFile) const
sl@0
   329
	{
sl@0
   330
	// Go through all the agents and return the one which supports the file
sl@0
   331
sl@0
   332
	TInt agentsCount(iAgentInfos.Count());
sl@0
   333
	CAgentManager* agentManager = NULL;
sl@0
   334
	for (TInt i = 0; i < agentsCount; ++i)
sl@0
   335
		{
sl@0
   336
		TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL());
sl@0
   337
		if(result != KErrNone)
sl@0
   338
			{
sl@0
   339
			if(KErrNoMemory == result)
sl@0
   340
				{
sl@0
   341
				User::Leave(result);
sl@0
   342
				}
sl@0
   343
			else
sl@0
   344
				{
sl@0
   345
				continue;	
sl@0
   346
				}
sl@0
   347
			}
sl@0
   348
		if (agentManager->IsRecognizedL(aFile))
sl@0
   349
			{
sl@0
   350
			return *iAgentInfos[i];
sl@0
   351
			}
sl@0
   352
		}
sl@0
   353
	return *iDefaultAgent;
sl@0
   354
	}
sl@0
   355
sl@0
   356
#ifdef SYMBIAN_ENABLE_SDP_WMDRM_SUPPORT
sl@0
   357
sl@0
   358
CAgentInfo& CAgentResolver::ResolveFileL(const TDesC8& aHeaderData)
sl@0
   359
	{
sl@0
   360
	// Go through all the agents and return the one which supports the given WMDRM content.
sl@0
   361
	
sl@0
   362
	TInt agentsCount(iAgentInfos.Count());
sl@0
   363
	CAgentManager* agentManager = NULL;
sl@0
   364
	
sl@0
   365
	for (TInt i = 0; i < agentsCount; ++i)
sl@0
   366
		{
sl@0
   367
		TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL());
sl@0
   368
		if(result != KErrNone)
sl@0
   369
			{
sl@0
   370
			if(KErrNoMemory == result)
sl@0
   371
				{
sl@0
   372
				User::Leave(result);
sl@0
   373
				}
sl@0
   374
			else
sl@0
   375
				{
sl@0
   376
				continue;	
sl@0
   377
				}
sl@0
   378
			}
sl@0
   379
			
sl@0
   380
		if (agentManager->IsRecognizedL(aHeaderData))
sl@0
   381
			{
sl@0
   382
			return *iAgentInfos[i];
sl@0
   383
			}
sl@0
   384
		}
sl@0
   385
		
sl@0
   386
    // will never reach here	
sl@0
   387
	return *iDefaultAgent;
sl@0
   388
	}
sl@0
   389
	
sl@0
   390
	
sl@0
   391
EXPORT_C TBool CAgentResolver::DoRecognizeL(const TDesC8& aHeader, TDes8& aFileMimeType, TDes8& aContentMimeType)
sl@0
   392
	{
sl@0
   393
	// Go through all the agents and return the one which supports the given WMDRM content.
sl@0
   394
	TInt agentsCount(iAgentInfos.Count());
sl@0
   395
	CAgentManager* agentManager = NULL;
sl@0
   396
	for (TInt i = 0; i < agentsCount; ++i)
sl@0
   397
		{
sl@0
   398
		TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL());
sl@0
   399
		if(result != KErrNone)
sl@0
   400
			{
sl@0
   401
			if(KErrNoMemory == result)
sl@0
   402
				{
sl@0
   403
				User::Leave(result);
sl@0
   404
				}
sl@0
   405
			else
sl@0
   406
				{
sl@0
   407
				continue;	
sl@0
   408
				}
sl@0
   409
			}
sl@0
   410
			
sl@0
   411
		if (agentManager->RecognizeContentL(aHeader, aFileMimeType, aContentMimeType))
sl@0
   412
			{
sl@0
   413
			// force to lower case to ensure that chosen lower case scheme for mime types is maintained
sl@0
   414
			aFileMimeType.LowerCase();
sl@0
   415
			aContentMimeType.LowerCase();			
sl@0
   416
			return ETrue;
sl@0
   417
			}
sl@0
   418
		}
sl@0
   419
		
sl@0
   420
	return EFalse;
sl@0
   421
	}
sl@0
   422
	
sl@0
   423
#endif //#ifdef SYMBIAN_ENABLE_SDP_WMDRM_SUPPORT
sl@0
   424
	
sl@0
   425
TUid CAgentResolver::ResolveDirectory(const TDesC& aPath, TDes& aActualPath, TBool& aThePrivateDir) const
sl@0
   426
	{
sl@0
   427
	TInt i = 0;
sl@0
   428
	TInt pathLength = 0;
sl@0
   429
	TBuf <KPrivateDirAndDriveLength> pathLowerCase;
sl@0
   430
	
sl@0
   431
	// Assume it's a publicly accessable path
sl@0
   432
	aThePrivateDir = EFalse;
sl@0
   433
	
sl@0
   434
	// Find the length of the path and private directory
sl@0
   435
	pathLength = aPath.Length();
sl@0
   436
sl@0
   437
	// Check that the path is long enough to be within a private directory
sl@0
   438
	// and does not include "..\\".The  "..\\" sequence could be a security risk
sl@0
   439
	if(aPath.Find(KParentDir()) == KErrNotFound && pathLength >= KPrivateDirAndDriveLength)
sl@0
   440
		{
sl@0
   441
		// Create a lower case copy of the left hand side of the path
sl@0
   442
		TPtrC lowerCasePtr = aPath.Mid(KPrivateDirOffset, KPrivateDirLength);
sl@0
   443
		pathLowerCase.Copy(lowerCasePtr);
sl@0
   444
		pathLowerCase.LowerCase();
sl@0
   445
	
sl@0
   446
		// Compare the first directory in the path to \\private\\ 
sl@0
   447
		if(KPrivateDir() == pathLowerCase)
sl@0
   448
			{
sl@0
   449
			// It is a private directory of some sort
sl@0
   450
			if(pathLength > KPrivateDirAndDriveLength)
sl@0
   451
				{
sl@0
   452
				// It must be a server private directory data cage
sl@0
   453
				TPtrC serverDirectoryPath = aPath.Right(pathLength - KPrivateDirAndDriveLength);
sl@0
   454
				for(i = 0; i < AgentInfoCount(); i++)
sl@0
   455
					{
sl@0
   456
					// See if the part after \\private\\ matches the agent name
sl@0
   457
					TPtrC privateDirectoryName = AgentInfo(i).PrivateDirectoryName();
sl@0
   458
					TPtrC agentName = AgentInfo(i).Agent().Name();
sl@0
   459
					if(privateDirectoryName.Length() && agentName.Length() && agentName == serverDirectoryPath.Left(agentName.Length()))
sl@0
   460
						{
sl@0
   461
						// It must be this agent's private directory
sl@0
   462
						// Convert \\private\\agentName\\... to \\private\\SID\\...
sl@0
   463
						aActualPath.Copy(aPath.Left(KPrivateDirAndDriveLength));
sl@0
   464
						aActualPath.Append(privateDirectoryName);
sl@0
   465
						aActualPath.Append(aPath.Right(pathLength - KPrivateDirAndDriveLength - agentName.Length()));
sl@0
   466
						return AgentInfo(i).Agent().ImplementationUid();
sl@0
   467
						}
sl@0
   468
					}
sl@0
   469
				}
sl@0
   470
			else
sl@0
   471
				{
sl@0
   472
				// It's just the c:\\private\\ directory
sl@0
   473
				// Use the default agent, any calls will just fail
sl@0
   474
				aThePrivateDir = ETrue;
sl@0
   475
				}
sl@0
   476
			}
sl@0
   477
		}
sl@0
   478
	
sl@0
   479
	// Not an agent private directory so just return the default agent
sl@0
   480
	aActualPath.Copy(aPath);
sl@0
   481
	return iDefaultAgent->Agent().ImplementationUid();
sl@0
   482
	}
sl@0
   483
sl@0
   484
HBufC* CAgentResolver::ConvertAgentFileNameL(const TDesC& aFileName) const
sl@0
   485
	{
sl@0
   486
	TInt i = 0;
sl@0
   487
	TInt fileNameLength = 0;
sl@0
   488
	TBuf <KPrivateDirAndDriveLength> pathLowerCase;
sl@0
   489
	
sl@0
   490
	fileNameLength = aFileName.Length();
sl@0
   491
	
sl@0
   492
	// If the path is shorter than the x:\\private\\ it must be a F32 file
sl@0
   493
	if(fileNameLength  > KPrivateDirAndDriveLength)
sl@0
   494
		{
sl@0
   495
		// Create a lower case copy of the left hand side of the path
sl@0
   496
		TPtrC lowerCasePtr = aFileName.Mid(KPrivateDirOffset, KPrivateDirLength);
sl@0
   497
		pathLowerCase.Copy(lowerCasePtr);
sl@0
   498
		pathLowerCase.LowerCase();
sl@0
   499
	
sl@0
   500
		// Compare the first directory in the path to \\private\\ 
sl@0
   501
		if(KPrivateDir() == pathLowerCase)
sl@0
   502
			{
sl@0
   503
			// It is a private directory of some sort
sl@0
   504
			if(fileNameLength > KPrivateDirAndDriveLength)
sl@0
   505
				{
sl@0
   506
				// It must be a server private directory data cage
sl@0
   507
				TPtrC serverDirectoryPath = aFileName.Right(fileNameLength - KPrivateDirAndDriveLength);
sl@0
   508
				for(i = 0; i < AgentInfoCount(); i++)
sl@0
   509
					{
sl@0
   510
					// See if the part after \\private\\ matches the agent name
sl@0
   511
					TPtrC privateDirectoryName = AgentInfo(i).PrivateDirectoryName();
sl@0
   512
					TPtrC agentName = AgentInfo(i).Agent().Name();
sl@0
   513
					if(privateDirectoryName.Length() && agentName.Length() && privateDirectoryName == serverDirectoryPath.Left(privateDirectoryName.Length()))
sl@0
   514
						{
sl@0
   515
						// It is this agent's private directory
sl@0
   516
						// Convert \\private\\SID\\... \\private\\agentName\\... 
sl@0
   517
						HBufC* buffer = HBufC::NewL(fileNameLength - privateDirectoryName.Length() + agentName.Length());
sl@0
   518
						TPtr ptr = buffer->Des();
sl@0
   519
						ptr.Copy(aFileName.Left(KPrivateDirAndDriveLength));
sl@0
   520
						ptr.Append(agentName);
sl@0
   521
						ptr.Append(aFileName.Right(fileNameLength - KPrivateDirAndDriveLength - privateDirectoryName.Length()));
sl@0
   522
						return buffer;
sl@0
   523
						}
sl@0
   524
					}
sl@0
   525
				}
sl@0
   526
			}
sl@0
   527
		}
sl@0
   528
	return aFileName.AllocL();
sl@0
   529
	}
sl@0
   530
sl@0
   531
EXPORT_C TBool CAgentResolver::DoRecognizeL(const TDesC& aName, const TDesC8& aBuffer, TDes8& aFileMimeType, TDes8& aContentMimeType)
sl@0
   532
	{
sl@0
   533
sl@0
   534
	// Given the filename and buffer from apparc, ask the agents in turn if they recognize the file
sl@0
   535
	// Note this will not call the DefaultAgent (F32) because it won't be able to recognize anything
sl@0
   536
sl@0
   537
	TInt agentsCount(iAgentInfos.Count());
sl@0
   538
	CAgentManager* agentManager = NULL;
sl@0
   539
	for (TInt i = 0; i < agentsCount; ++i)
sl@0
   540
		{
sl@0
   541
		TRAPD(result, agentManager = &iAgentInfos[i]->AgentManagerL());
sl@0
   542
		if(result != KErrNone)
sl@0
   543
			{
sl@0
   544
			if(KErrNoMemory == result)
sl@0
   545
				{
sl@0
   546
				User::Leave(result);
sl@0
   547
				}
sl@0
   548
			else
sl@0
   549
				{
sl@0
   550
				continue;	
sl@0
   551
				}
sl@0
   552
			}
sl@0
   553
		if (agentManager->RecognizeFileL(aName, aBuffer, aFileMimeType, aContentMimeType))
sl@0
   554
			{
sl@0
   555
			// force to lower case to ensure that chosen lower case scheme for mime types is maintained
sl@0
   556
			aFileMimeType.LowerCase();
sl@0
   557
			aContentMimeType.LowerCase();			
sl@0
   558
			return ETrue;
sl@0
   559
			}
sl@0
   560
		}
sl@0
   561
	return EFalse;
sl@0
   562
	}
sl@0
   563
	
sl@0
   564
sl@0
   565
void CAgentResolver::CleanImplArray(TAny* aArray)
sl@0
   566
	{
sl@0
   567
	static_cast<RImplInfoPtrArray*>(aArray)->ResetAndDestroy();
sl@0
   568
	}
sl@0
   569
sl@0
   570
EXPORT_C TInt CAgentResolver::PreferredBufferSize()
sl@0
   571
	{
sl@0
   572
	TInt size=0;
sl@0
   573
sl@0
   574
	if(iDefaultAgent != NULL)
sl@0
   575
		{
sl@0
   576
		size = iDefaultAgent->PreferredBufferSize();
sl@0
   577
		}
sl@0
   578
sl@0
   579
	// Find out the maximum buffer requested by any agent
sl@0
   580
	for (TInt i = 0; i < iAgentInfos.Count(); ++i)
sl@0
   581
			{
sl@0
   582
			if(iAgentInfos[i]->PreferredBufferSize() > size)
sl@0
   583
				{
sl@0
   584
				size = iAgentInfos[i]->PreferredBufferSize();
sl@0
   585
				}
sl@0
   586
			}
sl@0
   587
	return size;
sl@0
   588
	}
sl@0
   589
sl@0
   590
sl@0
   591
EXPORT_C const RArray<TPtrC8>& CAgentResolver::ConsumerMimeTypes() const
sl@0
   592
	{
sl@0
   593
	return iConsumerMimeTypes;
sl@0
   594
	}
sl@0
   595
sl@0
   596
sl@0
   597
EXPORT_C const RArray<TPtrC8>& CAgentResolver::SupplierMimeTypes() const
sl@0
   598
	{
sl@0
   599
	return iSupplierMimeTypes;
sl@0
   600
	}
sl@0
   601
sl@0
   602
sl@0
   603
CAgentInfo& CAgentResolver::AgentInfoL(const TDesC& aAgentName) const
sl@0
   604
	{
sl@0
   605
	TBool found = EFalse;
sl@0
   606
	TInt i = 0;
sl@0
   607
	for(i = 0; i < iAgentInfos.Count(); i++)
sl@0
   608
		{
sl@0
   609
		if(iAgentInfos[i]->Agent().Name() == aAgentName)
sl@0
   610
			{
sl@0
   611
			found = ETrue;
sl@0
   612
			break;
sl@0
   613
			}
sl@0
   614
		}
sl@0
   615
	
sl@0
   616
	if(!found)
sl@0
   617
		{
sl@0
   618
		// Can't find the agent so leave
sl@0
   619
		User::Leave(KErrNotFound);
sl@0
   620
		}
sl@0
   621
	
sl@0
   622
	return *iAgentInfos[i];
sl@0
   623
	}
sl@0
   624
sl@0
   625
CAgentInfo& CAgentResolver::AgentInfoL(const TUid& aUid) const
sl@0
   626
	{
sl@0
   627
	TInt i = 0;
sl@0
   628
	TBool found = EFalse;
sl@0
   629
	
sl@0
   630
	// See if it's the F32 agent
sl@0
   631
	if(aUid == DefaultAgentUid())
sl@0
   632
		{
sl@0
   633
		return *iDefaultAgent;
sl@0
   634
		}
sl@0
   635
	
sl@0
   636
	for(i = 0; i < iAgentInfos.Count(); i++)
sl@0
   637
		{
sl@0
   638
		if(iAgentInfos[i]->Agent().ImplementationUid() == aUid)
sl@0
   639
			{
sl@0
   640
			found = ETrue;
sl@0
   641
			break;			
sl@0
   642
			}
sl@0
   643
		}
sl@0
   644
	
sl@0
   645
	if(!found)
sl@0
   646
		{
sl@0
   647
		// couldn't find the agent so leave
sl@0
   648
		User::Leave(KErrNotFound);
sl@0
   649
		}
sl@0
   650
	
sl@0
   651
	return *iAgentInfos[i];
sl@0
   652
	}
sl@0
   653
sl@0
   654
CAgentInfo& CAgentResolver::AgentInfo(TInt aIndex) const
sl@0
   655
		{
sl@0
   656
		return *iAgentInfos[aIndex];		
sl@0
   657
		}
sl@0
   658
sl@0
   659
TInt CAgentResolver::AgentInfoCount() const
sl@0
   660
	{
sl@0
   661
	return iAgentInfos.Count();	
sl@0
   662
	}
sl@0
   663
sl@0
   664
TUid CAgentResolver::DefaultAgentUid() const
sl@0
   665
	{
sl@0
   666
	return iDefaultAgent->Agent().ImplementationUid();
sl@0
   667
	}