localisation/apparchitecture/apparc/apaapp.cpp
branchSymbian3
changeset 57 b8d18c84f71c
equal deleted inserted replaced
56:aa99f2208aad 57:b8d18c84f71c
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // apaapp.cpp
       
    15 //
       
    16 
       
    17 #include <apaapp.h> // stuff everyone will want ie most things
       
    18 #include <apacln.h> // CleanupStack protection for CApaDocument
       
    19 #include "APASTD.H" // Panics etc.
       
    20 #include <ecom/ecom.h>
       
    21 #include <ecom/implementationinformation.h>
       
    22 
       
    23 #include "../apparc/TRACE.H"
       
    24 
       
    25 _LIT(KApplicationLocation,"\\sys\\bin\\");
       
    26 
       
    27 //
       
    28 // CApaApplication
       
    29 //
       
    30 
       
    31 /** Constructor for CApaApplication */
       
    32 EXPORT_C CApaApplication::CApaApplication()
       
    33 	{
       
    34 	}
       
    35 
       
    36 /** Returns the full name and path of the application.
       
    37 
       
    38 The default implementation returns the full path name of the application DLL.
       
    39 
       
    40 An application can provide its own implementation. 
       
    41 
       
    42 @return Full path name of the application.
       
    43 @see CApaApplication::DllName() */
       
    44 EXPORT_C TFileName CApaApplication::AppFullName()const
       
    45 	{
       
    46 	return DllName();
       
    47 	}
       
    48 
       
    49 
       
    50 /** Returns the full name and path of the loaded application DLL.
       
    51 
       
    52 @return Full path name of the application DLL. */
       
    53 EXPORT_C TFileName CApaApplication::DllName()const
       
    54 	{
       
    55 	ASSERT(iAppFileNameRef);
       
    56 	return *iAppFileNameRef;
       
    57 	}
       
    58 
       
    59 
       
    60 /** Generates a unique filename based on the file name contained within the specified 
       
    61 full path name.
       
    62 
       
    63 If necessary, the function creates the directory structure that is defined 
       
    64 in the specified full path name.
       
    65 
       
    66 If the file name does not yet exist, then this is the file name chosen. If 
       
    67 this file name already exists, then a file name of the form: name(nn) is generated, 
       
    68 where nn are decimal digits. The value of nn is incremented until a name is 
       
    69 generated that is unique within the directory structure. A minimum of two 
       
    70 decimal digits is generated.
       
    71 
       
    72 The function is used by the UI framework.
       
    73 
       
    74 @param aFs Handle to a file server session. 
       
    75 @param aRootName The full path name.
       
    76 @return KErrNone if successful, otherwise one of the other system-wide error 
       
    77 codes. Specifically: KErrBadName if the file name portion of the specified 
       
    78 full path name has invalid format; KErrArgument if the drive, path or file 
       
    79 name parts are missing from the specified full path name; KErrOverflow if 
       
    80 the generated filename becomes too long; KErrNoMemory if there is insufficient 
       
    81 memory to perform the operation.
       
    82 @see CEikAppUi */
       
    83 EXPORT_C TInt CApaApplication::GenerateFileName(RFs& aFs, TFileName& aRootName)
       
    84 	{
       
    85 	// check that filename is valid
       
    86 	if (!aFs.IsValidName(aRootName))
       
    87 		return KErrBadName;
       
    88 	//
       
    89 	// check that a drive, path and root filename have been specified
       
    90 	TParsePtr parsePtr(aRootName);
       
    91 	if (!parsePtr.DrivePresent() || !parsePtr.PathPresent() || !parsePtr.NamePresent())
       
    92 		return KErrArgument;
       
    93 	//
       
    94 	// create the path if necessary
       
    95 	TInt ret=aFs.MkDirAll(parsePtr.DriveAndPath());
       
    96 	if (ret!=KErrNone && ret!=KErrAlreadyExists)
       
    97 		return ret;
       
    98 	//
       
    99 	// Create the Rbuf object to hold a filename (return if no mem available)
       
   100 	RBuf newName;
       
   101 	ret = newName.Create(aRootName, KMaxFileName+8);
       
   102 	if (ret!=KErrNone)
       
   103 		return KErrNoMemory;
       
   104 	//	
       
   105 	// generate a valid filename that doesn't already exist...
       
   106 	TEntry entry;
       
   107 	TInt i = 1;
       
   108 	_LIT(KFormatStringOne,"%S%S(%02d)%S");
       
   109 	_LIT(KFormatStringTwo,"%S%S(%d)%S");
       
   110 	TBuf<16> format(KFormatStringOne);
       
   111 	while (aFs.Entry(newName, entry) == KErrNone)		// Continue until DoesNotExist or PathDoesNotExist, etc
       
   112 		{ 
       
   113 		// If the file does already exist...
       
   114 		// ... then create a "/path/filename(nn)" sting and try again.
       
   115 		if (i == 100)
       
   116 			format = KFormatStringTwo;
       
   117 			
       
   118 		TPtrC driveAndPath = parsePtr.DriveAndPath();
       
   119 		TPtrC name = parsePtr.Name();
       
   120 		TPtrC ext = parsePtr.Ext();
       
   121 		newName.Format(format, &driveAndPath, &name, i++, &ext);
       
   122 		if (newName.Length() > KMaxFileName)
       
   123 			{
       
   124 			newName.Close();
       
   125 			return KErrOverflow;
       
   126 			}
       
   127 		}
       
   128 	
       
   129 	// Set the new filename and return
       
   130 	aRootName = newName;
       
   131 	newName.Close();
       
   132 	return KErrNone;
       
   133 	}
       
   134 
       
   135 
       
   136 /** Opens the .ini file associated with the application, constructs the dictionary 
       
   137 store object and returns a pointer to it.
       
   138 
       
   139 The implementation of this function is provided by the OpenIniFileLC() function. 
       
   140 The function pops the pointer returned by OpenIniFileLC() from the cleanup 
       
   141 stack.
       
   142 
       
   143 @param aFs Handle to a file server session. 
       
   144 @return A pointer to the dictionary store object representing the application's 
       
   145 .ini file. 
       
   146 @see CApaApplication::OpenIniFileLC() */
       
   147 EXPORT_C CDictionaryStore* CApaApplication::OpenIniFileL(RFs& aFs)const
       
   148 	{
       
   149 	CDictionaryStore* store = OpenIniFileLC(aFs);
       
   150 	CleanupStack::Pop(); // store
       
   151 	return store;
       
   152 	}
       
   153 
       
   154 EXPORT_C CApaApplication::~CApaApplication()
       
   155 	{
       
   156 	if (iEComDtorKey != TUid::Null()) 
       
   157 		REComSession::DestroyedImplementation(iEComDtorKey);
       
   158 
       
   159 	iAppFileNameRef = NULL;
       
   160 	}
       
   161 
       
   162 /** Virtual function called by the framework when the application
       
   163 has been launched as a server application.
       
   164 Applications that wish to be used as server applications must
       
   165 override this function to return their implemetation of the server.
       
   166 @param aAppServer The server pointer to be set. */
       
   167 EXPORT_C void CApaApplication::NewAppServerL(CApaAppServer*& /*aAppServer*/)
       
   168 	{
       
   169 	User::Leave(KErrNotSupported);
       
   170 	}
       
   171 
       
   172 /** Reserved for future use */
       
   173 EXPORT_C void CApaApplication::CApaApplication_Reserved1()
       
   174 	{
       
   175 	}
       
   176 
       
   177 /** Reserved for future use */
       
   178 EXPORT_C void CApaApplication::CApaApplication_Reserved2()
       
   179 	{
       
   180 	}
       
   181 
       
   182 void CApaApplication::SetAppFileNameRef(const RBuf& aFileName)
       
   183 	{
       
   184 	iAppFileNameRef = &aFileName;
       
   185 	}
       
   186 
       
   187 
       
   188 
       
   189 //
       
   190 // TApaApplicationFactory
       
   191 //
       
   192 
       
   193 /**
       
   194 Default constructor
       
   195 */
       
   196 
       
   197 /** Constructor for TApaApplicationFactory */
       
   198 EXPORT_C TApaApplicationFactory::TApaApplicationFactory()
       
   199 	: iType(ETypeFunction), iData(0), iApplication(NULL)
       
   200 	{
       
   201 	}
       
   202 
       
   203 /** 
       
   204 Constructor.
       
   205 @publishedAll
       
   206 @released
       
   207 @param aFunction The function from which the application is to be created.
       
   208 */
       
   209 EXPORT_C TApaApplicationFactory::TApaApplicationFactory(TFunction aFunction)
       
   210 	: iType(ETypeFunction), iData(reinterpret_cast<TUint>(aFunction)), iApplication(NULL)
       
   211 	{
       
   212 	}
       
   213 
       
   214 /** 
       
   215 Constructor. Use this constructor in preference to the constructor taking a "TUid" parameter 
       
   216 if at all possible as it is much more efficient.
       
   217 @publishedAll
       
   218 @released
       
   219 @param aEmbeddedApplicationInformation The ECOM implementation-information of the embedded application to be created.
       
   220 */
       
   221 EXPORT_C TApaApplicationFactory::TApaApplicationFactory(const CImplementationInformation& aEmbeddedApplicationInformation)
       
   222 	: iType(ETypeEmbeddedApplicationInformation),
       
   223 	 iData(reinterpret_cast<TUint>(&aEmbeddedApplicationInformation)),
       
   224 	 iApplication(NULL)
       
   225 	{
       
   226 	}
       
   227 
       
   228 /** 
       
   229 Constructor. Use the constructor taking a "const CImplementationInformation&" parameter in preference 
       
   230 to this constructor if at all possible as it is much more efficient.
       
   231 @publishedAll
       
   232 @released
       
   233 @param aEmbeddedApplicationUid The ECOM implementation-UID of the embedded application to be created.
       
   234 */
       
   235 EXPORT_C TApaApplicationFactory::TApaApplicationFactory(TUid aEmbeddedApplicationUid)
       
   236 	: iType(ETypeEmbeddedApplicationUid), iData(aEmbeddedApplicationUid.iUid), iApplication(NULL)
       
   237 	{
       
   238 	}
       
   239 
       
   240 CApaApplication* TApaApplicationFactory::CreateApplicationL() const
       
   241 	{
       
   242 	CApaApplication* application = NULL;
       
   243 
       
   244 	switch (iType)
       
   245 		{
       
   246 		case ETypeFunction:
       
   247 			{
       
   248 			__ASSERT_DEBUG(iData, Panic(EPanicNullPointer));
       
   249 			application = (*reinterpret_cast<TFunction>(iData))();
       
   250 			break;
       
   251 			}
       
   252 		case ETypeEmbeddedApplicationInformation:
       
   253 			{
       
   254 			__ASSERT_DEBUG(iData, Panic(EPanicNullPointer));
       
   255 			const CImplementationInformation& embeddedApplicationInformation = *reinterpret_cast<const CImplementationInformation*>(iData);
       
   256 			TUid uid = embeddedApplicationInformation.ImplementationUid();
       
   257 			application = CreateEmbeddedApplicationL(uid);
       
   258 			break;
       
   259 			}
       
   260 		case ETypeEmbeddedApplicationUid:
       
   261 			{
       
   262 			TUid uid = TUid::Uid(iData);
       
   263 			application = CreateEmbeddedApplicationL(uid);
       
   264 			break;
       
   265 			}
       
   266 		default:
       
   267 			Panic(EPanicBadApplicationFactoryType);
       
   268 		}
       
   269 
       
   270 	return application;
       
   271 	}
       
   272 
       
   273 HBufC* TApaApplicationFactory::AppFileNameL() const
       
   274 	{
       
   275 	HBufC* appFileName = NULL;
       
   276 	switch (iType)
       
   277 		{
       
   278 		case ETypeFunction:
       
   279 			{
       
   280 			// Assume that if the type is a function pointer then the app is not embedded (so
       
   281 			// the filename is the filename of this process).
       
   282 			appFileName = RProcess().FileName().AllocL();
       
   283 			break;
       
   284 			}
       
   285 		case ETypeEmbeddedApplicationInformation:
       
   286 			{
       
   287 			const CImplementationInformation& embeddedApplicationInformation = *reinterpret_cast<const CImplementationInformation*>(iData);
       
   288 			appFileName = FullAppFileNameL(embeddedApplicationInformation.DisplayName());
       
   289 			break;
       
   290 			}
       
   291 		case ETypeEmbeddedApplicationUid:
       
   292 			{
       
   293 			const TUid uid = TUid::Uid(iData);
       
   294 			HBufC* displayName = EmbeddedApplicationDisplayNameLC(uid);
       
   295 			appFileName = FullAppFileNameL(*displayName);
       
   296 			CleanupStack::PopAndDestroy(displayName);
       
   297 			break;
       
   298 			}
       
   299 		default:
       
   300 			Panic(EPanicBadApplicationFactoryType);
       
   301 		}
       
   302 
       
   303 	return appFileName;
       
   304 	}
       
   305 
       
   306 TUid TApaApplicationFactory::AppFileUid() const
       
   307 	{
       
   308 	TUid uid=KNullUid;
       
   309 	switch (iType)
       
   310 		{
       
   311 		case ETypeFunction:
       
   312 			{
       
   313 			uid = RProcess().Type()[2];
       
   314 			break;
       
   315 			}
       
   316 		case ETypeEmbeddedApplicationInformation:
       
   317 			{
       
   318 			const CImplementationInformation& embeddedApplicationInformation=*REINTERPRET_CAST(const CImplementationInformation*,iData);
       
   319 			uid = embeddedApplicationInformation.ImplementationUid();
       
   320 			break;
       
   321 			}
       
   322 		case ETypeEmbeddedApplicationUid:
       
   323 			{
       
   324 			uid = TUid::Uid(iData);
       
   325 			break;
       
   326 			}
       
   327 		default:
       
   328 			Panic(EPanicBadApplicationFactoryType);
       
   329 		}
       
   330 		
       
   331 	return uid;
       
   332 	}
       
   333 
       
   334 HBufC* TApaApplicationFactory::FullAppFileNameL(const TDesC& aAppName)
       
   335 	{
       
   336 	// This was appropriately changed for data caging (binaries placed in \sys\bin\)
       
   337 	TFileName fileName;
       
   338 	Dll::FileName(fileName);
       
   339 
       
   340 	TParse parse;
       
   341 	parse.SetNoWild(aAppName, &KApplicationLocation, &fileName);
       
   342 	return parse.FullName().AllocL();
       
   343 	}
       
   344 
       
   345 CApaApplication* TApaApplicationFactory::CreateEmbeddedApplicationL(TUid aUid)
       
   346 	{ // static
       
   347 	CApaApplication* const application=static_cast<CApaApplication*>(REComSession::CreateImplementationL(aUid,_FOFF(CApaApplication,iEComDtorKey)));
       
   348 	const TUid appUid = application->AppDllUid();
       
   349 	__ASSERT_ALWAYS(appUid==aUid, Panic(EPanicUidsDoNotMatch));
       
   350 	return application;
       
   351 	}
       
   352 
       
   353 
       
   354 HBufC* TApaApplicationFactory::EmbeddedApplicationDisplayNameLC(TUid aUid)
       
   355 	{ // static
       
   356 	HBufC* displayName = NULL;
       
   357 
       
   358 	RImplInfoPtrArray implementationArray;
       
   359 	CleanupStack::PushL(TCleanupItem(CleanupImplementationArray,&implementationArray));
       
   360 	REComSession::ListImplementationsL(KUidFileEmbeddedApplicationInterfaceUid,implementationArray);
       
   361 	
       
   362 	for (TInt i = implementationArray.Count()-1; i >= 0; --i)
       
   363 		{
       
   364 		const CImplementationInformation& implementationInformation=*implementationArray[i];
       
   365 		if (implementationInformation.ImplementationUid().iUid==aUid.iUid)
       
   366 			{
       
   367 			displayName=implementationInformation.DisplayName().AllocL();
       
   368 			break;
       
   369 			}
       
   370 		}
       
   371 		
       
   372 	CleanupStack::PopAndDestroy(&implementationArray);
       
   373 	if (!displayName)
       
   374 		User::Leave(KErrNotFound);
       
   375 
       
   376 	CleanupStack::PushL(displayName);
       
   377 
       
   378 	return displayName;
       
   379 	}
       
   380 
       
   381 void TApaApplicationFactory::CleanupImplementationArray(TAny* aImplementationArray)
       
   382 	{ // static
       
   383 	__ASSERT_DEBUG(aImplementationArray, Panic(EPanicNullPointer));
       
   384 	RImplInfoPtrArray& implementationArray=*static_cast<RImplInfoPtrArray*>(aImplementationArray);
       
   385 	implementationArray.ResetAndDestroy();
       
   386 	implementationArray.Close();
       
   387 	}
       
   388 	
       
   389 
       
   390