diff -r aa99f2208aad -r b8d18c84f71c localisation/apparchitecture/apparc/APPARC.CPP --- a/localisation/apparchitecture/apparc/APPARC.CPP Wed Jul 28 16:03:37 2010 +0100 +++ b/localisation/apparchitecture/apparc/APPARC.CPP Tue Aug 03 10:20:34 2010 +0100 @@ -1,7 +1,7 @@ // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). // All rights reserved. // This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" +// under the terms of "Eclipse Public License v1.0" // which accompanies this distribution, and is available // at the URL "http://www.eclipse.org/legal/epl-v10.html". // @@ -11,1377 +11,67 @@ // Contributors: // // Description: +// apparc.cpp // #include // stuff everyone will want ie most things -#include // CleanupStack protection for CApaDocument -#include "APADLL.H" // CApaDll CApaExe CApaAppHolder +#include "APADLL.H" // RApaApplication #include "APASTD.H" // Panics etc. -#include // KExecutableImageUid - -#include -#include -#include - -#ifdef USING_ECOM_RECOGS -#include -#include -#endif -#include "../apparc/TRACE.H" - -const TInt KAppProcessArrayGranularity(1); + +// +// RApaApplication +// -_LIT(KApplicationLocation,"\\sys\\bin\\"); - -///////////////////////////// -// Doc cleanup method -///////////////////////////// +RApaApplication::RApaApplication() : iApplication(NULL), iScheduledForDeletion(EFalse) + {} -EXPORT_C void TApaDocCleanupItem::DoCleanup(TAny* aPtr) +void RApaApplication::Close() { - __ASSERT_ALWAYS(aPtr,Panic(EPanicNoCleanupItem)); - TApaDocCleanupItem* cleanup = reinterpret_cast(aPtr); - __ASSERT_ALWAYS(cleanup->iApaProcess,Panic(EPanicNoCleanupItem));//lint !e613 Possible use of null pointer - Asserted above - cleanup->iApaProcess->DestroyDocument(cleanup->iApaDoc); //lint !e613 Possible use of null pointer - Asserted above + delete this; } - -///////////////////////////// -// CApaAppHolder -///////////////////////////// - -CApaAppHolder::CApaAppHolder() - {} - - -CApaAppHolder::~CApaAppHolder() - { - } - -void CApaAppHolder::UpdateAppsRefToThis() +RApaApplication::~RApaApplication() { - CApaApplication* app = Application(); - __ASSERT_ALWAYS(app,Panic(EPanicNoApplication)); - app->iAppHolder = this; //lint !e613 Possible use of null pointer - Asserted above - } - -#ifdef USING_ECOM_RECOGS -///////////////////////////// -// CApaExe -///////////////////////////// - -CApaExe::CApaExe() - {} - -CApaExe::~CApaExe() - { - delete iAppName; + iAppName.Close(); delete iApplication; } -TFileName CApaExe::FileName()const +void RApaApplication::CreateApplicationL(TApaApplicationFactory aApplicationFactory) { - if (iAppName) - { - return *iAppName; - } - else - { - return KNullDesC(); - } + __ASSERT_ALWAYS(!iApplication, Panic(EPanicApplicationAlreadyExists)); + iApplication = aApplicationFactory.CreateApplicationL(); + User::LeaveIfNull(iApplication); + + iFileUid = aApplicationFactory.AppFileUid(); + iAppName.Assign(aApplicationFactory.AppFileNameL()); + + iApplication->SetAppFileNameRef(iAppName); } -TUid CApaExe::Uid()const +TFileName RApaApplication::AppFileName() const + { + return iAppName; + } + +TUid RApaApplication::AppFileUid()const { return iFileUid; } -CApaApplication* CApaExe::Application() const +CApaApplication* RApaApplication::Application() { return iApplication; } -void CApaExe::CreateApplicationL(TApaApplicationFactory aApplicationFactory) - { - __ASSERT_ALWAYS(!iApplication,Panic(EPanicApplicationAlreadyExists)); - iApplication = aApplicationFactory.CreateApplicationL(); - iFileUid = aApplicationFactory.AppFileUid(); - User::LeaveIfNull(iApplication); - iAppName = aApplicationFactory.AppFileNameL(); - UpdateAppsRefToThis(); - } - -#endif // USING_ECOM_RECOGS - -EXPORT_C void CApaDocument::OpenFileL(CFileStore*&, RFile&) - { - } - -EXPORT_C void CApaDocument::Reserved_2() - {} - - -///////////////////// -// CApaApplication -///////////////////// - -/** Constructor for CApaApplication */ -EXPORT_C CApaApplication::CApaApplication() - { - } - -EXPORT_C TFileName CApaApplication::AppFullName()const -/** Returns the full name and path of the application. - -The default implementation returns the full path name of the application DLL. - -An application can provide its own implementation. - -@return Full path name of the application. -@see CApaApplication::DllName() */ - { - return DllName(); - } - - -EXPORT_C TFileName CApaApplication::DllName()const -/** Returns the full name and path of the loaded application DLL. - -@return Full path name of the application DLL. */ - { - __ASSERT_DEBUG(iAppHolder, Panic(EDPanicNoAppHolder)); - return iAppHolder->FileName(); - } - - -EXPORT_C TInt CApaApplication::GenerateFileName(RFs& aFs,TFileName& aRootName) -/** Generates a unique filename based on the file name contained within the specified -full path name. - -If necessary, the function creates the directory structure that is defined -in the specified full path name. - -If the file name does not yet exist, then this is the file name chosen. If -this file name already exists, then a file name of the form: name(nn) is generated, -where nn are decimal digits. The value of nn is incremented until a name is -generated that is unique within the directory structure. A minimum of two -decimal digits is generated. - -The function is used by the UI framework. - -@param aFs Handle to a file server session. -@param aRootName The full path name. -@return KErrNone if successful, otherwise one of the other system-wide error -codes. Specifically: KErrBadName if the file name portion of the specified -full path name has invalid format; KErrArgument if the drive, path or file -name parts are missing from the specified full path name; KErrOverflow if -the generated filename becomes too long; KErrNoMemory if there is insufficient -memory to perform the operation. -@see CEikAppUi */ - { - // check that filename is valid - if (!aFs.IsValidName(aRootName)) - return KErrBadName; - // - // check that a drive, path and root filename have been specified - TParsePtr parsePtr(aRootName); - if (!parsePtr.DrivePresent() || !parsePtr.PathPresent() || !parsePtr.NamePresent()) - return KErrArgument; - // - // create the path if necessary - TInt ret=aFs.MkDirAll(parsePtr.DriveAndPath()); - if (ret!=KErrNone && ret!=KErrAlreadyExists) - return ret; - // - // Create the Rbuf object to hold a filename (return if no mem available) - RBuf newName; - ret = newName.Create(aRootName, KMaxFileName+8); - if (ret!=KErrNone) - return KErrNoMemory; - // - // generate a valid filename that doesn't already exist... - TEntry entry; - TInt i=1; - _LIT(KFormatStringOne,"%S%S(%02d)%S"); - TBuf<16> format; - format=KFormatStringOne; - while (aFs.Entry(newName,entry)==KErrNone) // Continue until DoesNotExist or PathDoesNotExist, etc - { - if (i>=100) - { - _LIT(KFormatStringTwo,"%S%S(%d)%S"); - format=KFormatStringTwo; - } - TPtrC driveAndPath=parsePtr.DriveAndPath(); - TPtrC name=parsePtr.Name(); - TPtrC ext=parsePtr.Ext(); - newName.Format(format,&driveAndPath,&name,i++,&ext); - if (newName.Length()>KMaxFileName) - { - newName.Close(); - return KErrOverflow; - } - } - // - // set the new filename and return - aRootName = newName; - newName.Close(); - return KErrNone; - } - - -EXPORT_C CDictionaryStore* CApaApplication::OpenIniFileL(RFs& aFs)const -/** Opens the .ini file associated with the application, constructs the dictionary -store object and returns a pointer to it. - -The implementation of this function is provided by the OpenIniFileLC() function. -The function pops the pointer returned by OpenIniFileLC() from the cleanup -stack. - -@param aFs Handle to a file server session. -@return A pointer to the dictionary store object representing the application's -.ini file. -@see CApaApplication::OpenIniFileLC() */ - { - CDictionaryStore* store=OpenIniFileLC(aFs); - CleanupStack::Pop(); // store - return store; - } - -EXPORT_C CApaApplication::~CApaApplication() - { -#ifdef USING_ECOM_RECOGS - if (iDtorKey!=TUid::Null()) // only some CApaApplication objects are ECom objects (i.e. only those corresponding to embedded applications, not top-level applications) - { - REComSession::DestroyedImplementation(iDtorKey); - } -#endif // USING_ECOM_RECOGS - iAppHolder = NULL; - } - -EXPORT_C void CApaApplication::NewAppServerL(CApaAppServer*& /*aAppServer*/) -/** Virtual function called by the framework when the application -has been launched as a server application. -Applications that wish to be used as server applications must -override this function to return their implemetation of the server. -@param aAppServer The server pointer to be set. */ - { - User::Leave(KErrNotSupported); - } - -/** Reserved for future use */ -EXPORT_C void CApaApplication::CApaApplication_Reserved1() - { - } - -/** Reserved for future use */ -EXPORT_C void CApaApplication::CApaApplication_Reserved2() - { - } - -///////////////////////////// -// CApaDocument -///////////////////////////// - -/** Constructor for CApaDocument */ -EXPORT_C CApaDocument::CApaDocument() - { - } - -EXPORT_C CApaDocument::CApaDocument(CApaApplication& aApp,CApaProcess& aProcess) - : iApplication(&aApp), - iApaProcess(&aProcess) -/** Constructs the document object with the specified application and process. - -Derived classes must define and implement a constructor through which both -the associated application and process can be specified. A typical implementation -calls this constructor through a constructor initialization list. - -@param aApp The application. -@param aProcess The process. -@see CEikDocument */ - {} - - -EXPORT_C CApaDocument::~CApaDocument() -/** Destructor. - -The implementation is empty. */ - { - iContainer = NULL; - iApplication = NULL; - iApaProcess = NULL; - } - - -EXPORT_C CApaDocument::TCapability CApaDocument::Capability() const -/** Gets the document's capabilities. - -Capabilities are encapsulated by an instance of a TCapability class, a public -class defined inside this class. - -The default implementation returns a default TCapability object, indicating -that the document does not support any of the defined capabilities. - -If a document does support one or more of the capabilities, it should override -this function to return a suitably initialised object. - -@return The document's capabilities */ - { - return TCapability(); - } - - -EXPORT_C void CApaDocument::ValidatePasswordL() const -/** Checks the document password. - -The default implementation is empty. - -If a document is intended to be password protected, the UI application should -provide an implementation that forces the user to enter the password and validate -the input. - -If the document is protected by a password and the password entered by the -user is incorrect, the function should leave with KErrLocked, otherwise it -should just return. */ - {} - - -EXPORT_C CPicture* CApaDocument::GlassPictureL() -// Return handle to glass picture, creating one if not already created. -// returns NULL as glass pictures are not supported by default -/** Gets an object that can draw a representation of the document's content. - -If the document supports being embedded as a glass door, then the UI application -must provide an implementation for this function. - -The default implementation raises an APPARC 8 panic. - -@return A pointer to a glass door. */ - { - Panic(EPanicNoGlassDoorMethodSupplied); - // - return NULL; - } - - -EXPORT_C void CApaDocument::ExternalizeL(RWriteStream& /*aStream*/)const - {} - -EXPORT_C CApaDocument::TCapability::TCapability() - :iCapability(0),TCapability_Reserved1(0) -/** Constructs a default capability object. - -All capabilities are marked as "not supported". */ - {} - -///////////////////////////// -// TApaAppHolderInfo -///////////////////////////// - -class TApaAppHolderInfo - { -public: - TApaAppHolderInfo(CApaAppHolder* aAppHolder); -public: - CApaAppHolder* iAppHolder; - TBool iToBeRemoved; - }; - -TApaAppHolderInfo::TApaAppHolderInfo(CApaAppHolder* aAppHolder) - :iAppHolder(aAppHolder), iToBeRemoved(EFalse) - { - } - -///////////////////////////// -// CApaParentProcessMonitor -///////////////////////////// - -class CApaParentProcessMonitor : public CActive - { -public: // Construction / destruction - static CApaParentProcessMonitor* NewL(TProcessId aProcessId); - ~CApaParentProcessMonitor(); - void ConstructL(); -private: - CApaParentProcessMonitor(TProcessId aProcessId); -public: // From CActive - void RunL(); - void DoCancel(); -private: - TProcessId iProcessId; - RProcess iProcess; - }; - -CApaParentProcessMonitor* CApaParentProcessMonitor::NewL(TProcessId aProcessId) +void RApaApplication::ScheduleForAsyncDeletion(TBool aDoDelete) { - CApaParentProcessMonitor* self=new (ELeave) CApaParentProcessMonitor(aProcessId); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(self); - return self; - } - -CApaParentProcessMonitor::CApaParentProcessMonitor(TProcessId aProcessId) - : CActive(EPriorityLow) - { - iProcessId=aProcessId; - } - -CApaParentProcessMonitor::~CApaParentProcessMonitor() - { - Cancel(); - } - -void CApaParentProcessMonitor::ConstructL() - { - User::LeaveIfError(iProcess.Open(iProcessId)); - iProcess.Logon(iStatus); - if(iStatus==KErrNoMemory) - { - User::WaitForRequest(iStatus); - User::Leave(KErrNoMemory); - } - CActiveScheduler::Add(this); - SetActive(); - } - -void CApaParentProcessMonitor::RunL() - { - // Do something that will kill the child when the parent process terminates - if(iStatus==KErrNone) - { - RProcess proc; - proc.Terminate(KErrNone); - } - } - -void CApaParentProcessMonitor::DoCancel() - { - iProcess.LogonCancel(iStatus); - } - -///////////////////////////// -// CApaProcess -///////////////////////////// - -/** Constructor for CApaProcess */ -EXPORT_C CApaProcess::CApaProcess() - { - } - -EXPORT_C CApaProcess* CApaProcess::NewL(const RFs& aFs) -/** Creates and returns a pointer to a new application process. - -This function is not used by UI applications. - -@param aFs Handle to a file server session. -@return Pointer to the new application process. */ - { - CApaProcess* self=new(ELeave) CApaProcess(aFs); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(); - return self; - } - -EXPORT_C CApaProcess::CApaProcess(const RFs& aFs) - :iFsSession(aFs) -/** Constructs the application process object with the specified file session handle. - -Derived classes must define and implement a constructor through which -the file session handle can be specified. A -typical implementation calls this constructor through a constructor initialization -list. - -This constructor is used by the UI framework. - -@deprecated -@param aFs Handle to a file server session */ - {} - -const TInt KPriorityGreaterThanShutter=102; - -EXPORT_C void CApaProcess::ConstructL() -/** Completes construction of the application process object. - -Implementers of derived classes must call this function as part of the second -stage construction of an object. Typically, derived classes implement their -own NewL() function and call ConstructL() as part of that implementation. */ - { - // - iAppList = new(ELeave) CArrayFixFlat(KAppProcessArrayGranularity); - iDocList = new(ELeave) CArrayFixFlat(KAppProcessArrayGranularity); - iMainDocFileName = HBufC::NewL(KMaxFileName); - iApplicationRemover=CIdle::NewL(KPriorityGreaterThanShutter); // Use an idle object so that app has chance to clear its call stack - } - -EXPORT_C void CApaProcess::ConstructL(TProcessId aParentProcessId) -/** Completes construction of the application process object, passing in a Parent Process Identifier. - -Implementers of derived classes must call this function as part of the second -stage construction of an object. Typically, derived classes implement their -own NewL() function and call ConstructL() as part of that implementation. - -@param aParentProcessId Id of the parent process. This process will terminate when the parent does. */ - { - ConstructL(); - if(KNullProcessId!=aParentProcessId) - { - iMonitor=CApaParentProcessMonitor::NewL(aParentProcessId); - } - } - -EXPORT_C CApaProcess::~CApaProcess() -// If this is called without calling ResetL() or CApaDocument::SaveL() first, data may be lost -// -/** Frees resources prior to destruction. - -Documents must be saved before the application process is deleted, otherwise -data may be lost. - -In debug mode, the destructor raises an APPARC 6 panic if documents still -exist, and an APPARC 5 panic if applications still exist. */ - { - if (iMainDoc) - { - DestroyDocument(iMainDoc); - iMainDoc = NULL; - } - if (iDocList) - { - __ASSERT_DEBUG(iDocList->Count()==0,Panic(EPanicDocListNotEmpty)); - for (TInt i=iDocList->Count()-1 ; i>=0 ; i--) - { - delete (*iDocList)[i]; // delete stray doc's in release mode, just to be tidy - } - } - if (iAppList) - { - for (TInt i=iAppList->Count()-1 ; i>=0 ; i--) - { - delete ((*iAppList)[i]).iAppHolder; - } - } - delete iAppList; - delete iDocList; - delete iMainDocFileName; - delete iApplicationRemover; - delete iMonitor; + iScheduledForDeletion = aDoDelete; } - - -EXPORT_C void CApaProcess::ResetL() -/** Resets the the application process to its initial state. - -Specifically, it saves the main document, deletes the main and all embedded -documents from memory, resets the main document filename and deletes all applications -except the main application. - -The function can leave if saving the main document fails. */ - { - if (iMainDoc) - { - iMainDoc->SaveL(); - DeleteAllDocs(); // sets iMainDoc to NULL, deletes all apps except main - } - __ASSERT_DEBUG(iMainDocFileName, Panic(EPanicNoDocument)); - *iMainDocFileName=KNullDesC; - } - - -void CApaProcess::DeleteAllDocs() -// deletes all docs -// deletes all apps except main app -// sets iMainDoc* to NULL -// - { - CApaAppHolder* mainAppHolder=NULL; - if (iMainDoc) - { - __ASSERT_DEBUG(iMainDoc->Application(), Panic(EDPanicNoApp)); - mainAppHolder = iMainDoc->Application()->iAppHolder; - for (TInt i=iDocList->Count()-1 ; i>=0 ; i--) - if ((*iDocList)[i]==iMainDoc) - { - iDocList->Delete(i); // removes from array, but doesnt destroy - delete iMainDoc; - iMainDoc = NULL; - } - } - __ASSERT_ALWAYS(iDocList->Count()==0,Panic(EPanicDocListNotEmpty)); - iDocList->Reset(); - if (iAppList) - { - for (TInt ii=iAppList->Count()-1 ; ii>=0 ; ii--) // need to iterate backwards as the array changes size during the loop - { - if ((*iAppList)[ii].iAppHolder!=mainAppHolder) - { - delete (*iAppList)[ii].iAppHolder; - iAppList->Delete(ii); - } - } - iAppList->Compress(); - } - } - - -EXPORT_C void CApaProcess::SetMainDocFileName(const TDesC& aMainDocFileName) -/** Sets the filename of the main document. - -@param aMainDocFileName The filename to be set. -@panic APPARC 7 If the length of aMainDocFileName is greater than KMaxFileName or the -length of the last filename set by SetMainDocFileNameL if greater -@see KMaxFileName */ - { - __ASSERT_DEBUG( iMainDocFileName, Panic(EPanicNullPointer)); - __ASSERT_ALWAYS( aMainDocFileName.Length()<=iMainDocFileName->Des().MaxLength() ,Panic(EPanicFileNameTooLong)); - *iMainDocFileName = aMainDocFileName; - } - -EXPORT_C void CApaProcess::SetMainDocFileNameL(const TDesC& aMainDocFileName) -/** Sets the filename of the main document. - -@param aMainDocFileName The filename to be set. There is no restriction on the -length of this descriptor. */ + +TBool RApaApplication::IsScheduleForAsyncDeletion() const { - __ASSERT_ALWAYS( iMainDocFileName, Panic(EPanicNullPointer)); - const TInt newLength = aMainDocFileName.Length() < KMaxFileName ? KMaxFileName : aMainDocFileName.Length(); - if (newLength != iMainDocFileName->Des().MaxLength()) - { - HBufC* const newMainDocFileName = HBufC::NewL(newLength); - delete iMainDocFileName; - iMainDocFileName = newMainDocFileName; - } - SetMainDocFileName(aMainDocFileName); - } - -EXPORT_C void CApaProcess::SetMainDocument(CApaDocument* aDocument) -/** Sets the main document. - -@param aDocument A pointer to the document to be set as the main document -of the application process. This must be a an object created by the AddNewDocumentL() -or OpenNewDocumentL() functions -@see CApaProcess::AddNewDocumentL() -@see CApaProcess::OpenNewDocumentL() */ - { - __ASSERT_ALWAYS( iDocList, Panic(EPanicNullPointer)); - // check that the prospective main doc has actually been added to the array - for (TInt i=iDocList->Count()-1 ; i>=0 ; i--) - { - if ((*iDocList)[i]==aDocument) - break; - if (i==0) - Panic(EPanicNoDocument); - } - // assign it once it has checked out - iMainDoc = aDocument; - } - -EXPORT_C CApaDocument* CApaProcess::AddNewDocumentL(TApaApplicationFactory aApplicationFactory) -/** Creates and adds a new document using the specified application factory. - -The document may be a main document or an embedded document. - -Any document created with this function must be destroyed using DestroyDocument(). - -@param aApplicationFactory Should be created implicitly by passing a pointer to -a factory function, an ECOM plugin UID, or a CImplementationInformation reference. -@return A pointer to the new document. -@see CApaProcess::DestroyDocument() -@see CApaApplication */ - { -#ifdef USING_ECOM_RECOGS - __SHOW_TRACE(_L("Starting CApaProcess::AddNewDocumentL")); - __APA_PROFILE_START(0); - - CApaAppHolder* appHolder = AddAppExeL(aApplicationFactory); - - // use the app to create a doc - CApaDocument* doc=NULL; - TRAPD(ret,doc=CreateDocL(appHolder->Application())); - if (ret!=KErrNone) - // remove app as it has been orphaned - RemoveApp(appHolder); - User::LeaveIfError(ret); - __PROFILE_END(0); - return doc; -#else // USING_ECOM_RECOGS - (void)aApplicationFactory; - return NULL; -#endif // USING_ECOM_RECOGS - } //lint !e1762 Member function could be made const - Not true - - - -void CApaProcess::RemoveApp(CApaAppHolder* aAppHolder) -// removes app holder from the list if it exists, panics otherwise - { - __ASSERT_ALWAYS(iAppList, Panic(EPanicNullPointer)); - TInt i = 0; - for (i=iAppList->Count()-1 ; i>=0 ; i--) - { - if ((*iAppList)[i].iAppHolder==aAppHolder) // the main app may be alive on its own if Reset() has just been called - { - delete aAppHolder; // the main app may be alive on its own if Reset() has just been called - iAppList->Delete(i); - break; - } - } - if (i<0) - Panic(EPanicAppNotInList); + return iScheduledForDeletion; } -EXPORT_C CApaDocument* CApaProcess::OpenNewDocumentL(CFileStore*& aStore,CStreamDictionary*& aStreamDic,const TDesC& aDocFullFileName,TUint aFileMode) -/** Opens the specified file and restores the content as a document. - -The created document can be merged into or embedded in another document. - -Any document created with this function must be destroyed using DestroyDocument(). - -@param aStore On return, this contains a pointer to the store object created -during the restore. -@param aStreamDic On return, this contains a pointer to the stream dictionary -object created during the restore. -@param aDocFullFileName The name of the file containing the document. -@param aFileMode The mode in which to open the file. -@return A pointer to the restored document. -@see TFileMode -@see CApaProcess::DestroyDocument() */ - { - __SHOW_TRACE(_L("Starting CApaProcess::OpenNewDocumentL")); - __APA_PROFILE_START(1); - TParse parser; - User::LeaveIfError(iFsSession.Parse(aDocFullFileName,parser)); - // open doc as a file store & read in the header - CFileStore* docStore; - CStreamDictionary* streamDic = ReadRootStreamLC(FsSession(),docStore,parser.FullName(),aFileMode); - CleanupStack::PushL(docStore); - // read in the app id info - TApaAppIdentifier appId=ReadAppIdentifierL(*docStore,*streamDic); - // create the doc - CApaDocument* importedDoc = AddNewDocumentL(appId.iAppUid); - // restore the document - TApaDocCleanupItem cleanup(this,importedDoc); - CleanupStack::PushL(cleanup); - importedDoc->RestoreL(*docStore,*streamDic); - CleanupStack::Pop(3); //docStore,importedDoc,streamDic - aStore = docStore; - aStreamDic = streamDic; - __PROFILE_END(1); - return importedDoc; - } - -EXPORT_C TApaAppIdentifier CApaProcess::ReadAppIdentifierL(const CStreamStore& aStore,const CStreamDictionary& aStreamDic) -// this is a static method -/** Reads the application identifier from its stream in the specified store and -returns it. - -The location of the stream is found in the specified stream dictionary. - -@param aStore The store from which the application identifier should be read. -@param aStreamDic The stream dictionary containing the stream ID of the application -identifier stream. The stream dictionary can be found in the root stream of -the store. -@return The application identifier. */ - { - __SHOW_TRACE(_L("Starting CApaProcess::ReadAppIdentifierL")); - TStreamId infoStreamId=aStreamDic.At(KUidAppIdentifierStream); - TApaAppIdentifier appId; - // create a stream and read in the data - RStoreReadStream stream; - stream.OpenLC(aStore,infoStreamId); - stream>> appId; - stream.Close(); - CleanupStack::PopAndDestroy(); // stream - return appId; - } - - -EXPORT_C void CApaProcess::WriteAppIdentifierL(CStreamStore& aStore,CStreamDictionary& aStreamDic,const TApaAppIdentifier& aAppId) -// this is a static method -/** Writes the application identifier to a new stream in the specified store and -records the location of this stream in the specified stream dictionary. - -@param aStore The store to which the application identifier should be written. - -@param aStreamDic The stream dictionary. -@param aAppId The application identifier to be externalised to a stream. */ - { - __SHOW_TRACE(_L("Starting CApaProcess::WriteAppIdentifierL")); - // create a stream - RStoreWriteStream stream; - TStreamId streamId=stream.CreateLC(aStore); - // stream the header - stream<< aAppId; - stream.CommitL(); - CleanupStack::PopAndDestroy(); // id stream - // enter the stream in the dictionary - aStreamDic.AssignL(KUidAppIdentifierStream,streamId); - } - - -EXPORT_C CStreamDictionary* CApaProcess::ReadRootStreamLC(RFs& aFs,CFileStore*& aStore,const TDesC& aDocFullFileName,TUint aFileMode) -/** Reads the stream dictionary contained as the root stream in the specified document -file. - -The function constructs, and returns a pointer to the stream dictionary object -and puts the pointer to the stream dictionary object onto the cleanup stack. -It also returns a pointer to the created file store object through an argument -reference. - -The file must be a valid document file; otherwise the function leaves with one of -the system-wide error codes. - -@param aFs Handle to a file server session. -@param aStore On return, a pointer to the newly created file store object. -@param aDocFullFileName The full path name of the document file. -@param aFileMode The mode in which to open the file. -@return A pointer to the stream dictionary object read from the root stream -of the store. -@see TFileMode */ - { // static - __SHOW_TRACE(_L("Starting CApaProcess::ReadRootStreamLC (file-name overload)")); - CStreamDictionary* const streamDictionary=CStreamDictionary::NewLC(); - CFileStore* const store=CFileStore::OpenLC(aFs,aDocFullFileName,aFileMode); - DoReadRootStreamL(*streamDictionary, *store); - aStore=store; // delay assignment until nothing can go wrong to avoid destroying the store twice if a leave occurs - CleanupStack::Pop(store); - return streamDictionary; - } - - -EXPORT_C CStreamDictionary* CApaProcess::ReadRootStreamLC(CFileStore*& aStore, const RFile& aFile) -/** -@internalTechnology -*/ - { // static - __SHOW_TRACE(_L("Starting CApaProcess::ReadRootStreamLC (file-handle overload)")); - CStreamDictionary* const streamDictionary=CStreamDictionary::NewLC(); - RFile duplicateFile; - CleanupClosePushL(duplicateFile); - User::LeaveIfError(duplicateFile.Duplicate(aFile)); // this is because CFileStore::FromLC closes the file its passed (and stores its own duplicate) - CFileStore* const store=CFileStore::FromL(duplicateFile); - CleanupStack::PopAndDestroy(&duplicateFile); - CleanupStack::PushL(store); - DoReadRootStreamL(*streamDictionary, *store); - aStore=store; // delay assignment until nothing can go wrong to avoid destroying the store twice if a leave occurs - CleanupStack::Pop(store); - return streamDictionary; - } - - -void CApaProcess::DoReadRootStreamL(CStreamDictionary& aStreamDictionary, const CFileStore& aStore) - { // static - const TStreamId rootStreamId=aStore.Root(); - if ((aStore.Type()[1]!=KUidAppDllDoc) || (rootStreamId==KNullStreamId)) - { - User::Leave(KErrCorrupt); - } - RStoreReadStream rootStream; - rootStream.OpenLC(aStore, rootStreamId); - rootStream>>aStreamDictionary; - CleanupStack::PopAndDestroy(&rootStream); - } - - -EXPORT_C void CApaProcess::WriteRootStreamL(CPersistentStore& aStore,CStreamDictionary& aStreamDic,const CApaApplication& aApp) -// this is a static method -/** Writes the application identifier (derived from the application object CApaApplication) -followed by the stream dictionary to the store and makes the stream dictionary the root stream of the -store. - -Typically, the function is called by the application when it -implements a file create or file save type operation. It is called after all -model and UI data has been persisted. The IDs of the streams containing the -model and UI data should have been lodged in the stream dictionary. - -In effect, the function finishes off the file save or file -create type operation, leaving the file containing the store in a valid state -with the standard interface. - -@param aStore The store to which the root stream is to be written. Before -calling this function, a reference to the store must be saved by putting a -pointer onto the cleanup stack or by making it member data of a class. This -ensures that it is not orphaned in the event of this function leaving. -@param aStreamDic The stream dictionary containing the locations and associated -UIDs of other streams in the store. -@param aApp The application used to create the main document in the file -being written. The application identifier to be written is constructed from -this application object. */ - { - __SHOW_TRACE(_L("Starting CApaProcess::WriteRootStreamL(app)")); - // get the app dll name - TParse dllPath; - dllPath.SetNoWild(aApp.DllName(),NULL,NULL); - // set up an app identifier - TApaAppIdentifier appId(aApp.AppDllUid(),dllPath.NameAndExt()); - // Write the root stream - WriteRootStreamL(aStore,aStreamDic,appId); - } - - -EXPORT_C void CApaProcess::WriteRootStreamL(CPersistentStore& aStore,CStreamDictionary& aStreamDic,const TApaAppIdentifier& aAppId) -// this is a static method -/** Writes the application identifier followed by the stream dictionary -to the store and makes the stream dictionary the root stream of the store. - -Typically, the function is called by the application when it -implements a file create or file save type operation. It is called after all -model and UI data has been persisted. The IDs of the streams containing the -model and UI data should have been lodged in the stream dictionary. - -In effect, the function finishes off the file save or file -create type operation, leaving the file containing the store in a valid state -with the standard interface. - -@param aStore The store to which the root stream is to be written. Before -calling this function, a reference to the store must be saved by putting a -pointer onto the cleanup stack or by making it member data of a class. This -ensures that it is not orphaned in the event of this function leaving. -@param aStreamDic The stream dictionary containing the locations and associated -UIDs of other streams in the store. -@param aAppId The application identifier to be written into the application -identifier stream. */ - { - __SHOW_TRACE(_L("Starting CApaProcess::WriteRootStreamL(id)")); - // create a stream - WriteAppIdentifierL(aStore,aStreamDic,aAppId); - // externalize the dictionary - RStoreWriteStream stream; - TStreamId streamId=stream.CreateLC(aStore); - stream<< aStreamDic; - stream.CommitL(); - CleanupStack::PopAndDestroy(); // dictionary stream - // set the dictionary stream as the root stream - aStore.SetRootL(streamId); - } - - -EXPORT_C void CApaProcess::DestroyDocument(CApaDocument* aDoc) -/** Destroys the specified document. - -All references to the document are removed, and associated resources are freed. -Specifically, the function deletes any associated application and unloads -the application DLL, provided that no other documents of that application -type are still open. - -All document objects created through CApaProcess must be deleted using this -function. - -@param aDoc A pointer to the document to be destroyed. -@see CApaApplication -@see CApaProcess */ - { - __SHOW_TRACE(_L("Starting CApaProcess::DestroyDocument(app)")); - // - if (aDoc) - { - // delete the doc, keeping a handle to its app - CApaApplication* app=aDoc->Application(); - __ASSERT_DEBUG(app!=NULL,Panic(EDPanicDocWithNoApp)); - // remove the doc from the list, keeping a handle to the doc - TBool appStillRequired=EFalse; - __ASSERT_ALWAYS(iDocList, Panic(EPanicNullPointer)); - for (TInt i=iDocList->Count()-1 ; i>=0 ; i--) - {//check through the list, remove the right doc, and see if the app is used by any other docs - if ((*iDocList)[i]==aDoc) - { - iDocList->Delete(i); // removes from array, but doesnt destroy - iDocList->Compress(); - } - else if ((*iDocList)[i]->Application()==app) - appStillRequired = ETrue; - } - // null the main doc handle if we delete the main doc - if (aDoc==iMainDoc) - iMainDoc = NULL; - - delete aDoc; // del - - // remove app if no other doc's use it and it's not the main app - if ((!appStillRequired)&&(iMainDoc)&&(app!=iMainDoc->Application())) - { - MarkApplicationForRemoval(app); - __ASSERT_DEBUG(iApplicationRemover, Panic(EDPanicNoAppRemover)); - if (!iApplicationRemover->IsActive()) - { - iApplicationRemover->Start(TCallBack(CApaProcess::IdleRemoveApplications,this)); - } - } - } - } - - -TInt CApaProcess::IdleRemoveApplications(TAny* aThis) -// Remove applications on callback of idle object. Using an idle object gives an embedded application a chance to clear -// its call stack before its dll is closed -// - { - CApaProcess* process=reinterpret_cast(aThis); - __ASSERT_DEBUG(process, Panic(EDPanicNoProcess)); - process->RemoveMarkedApplications(); - return 0; - } - - -void CApaProcess::RemoveMarkedApplications() -// Remove any applications that have been marked for removal, closing their dlls also -// - { - __ASSERT_DEBUG(iAppList, Panic(EPanicNullPointer)); - for (TInt i=iAppList->Count()-1 ; i>=0 ; i--) - if ((*iAppList)[i].iToBeRemoved) - { - delete (*iAppList)[i].iAppHolder; - iAppList->Delete(i); // remove from array - iAppList->Compress(); - } - } - - -void CApaProcess::MarkApplicationForRemoval(const CApaApplication* aApp) -// Mark the application in the app list for removal by idle object -// - { - __ASSERT_DEBUG(aApp!=NULL,Panic(EDPanicRemovingNullApp)); - __ASSERT_DEBUG(iAppList, Panic(EPanicNullPointer)); - // remove the app from the list, keeping a handle to it - for (TInt i=iAppList->Count()-1 ; i>=0 ; i--) - { - __ASSERT_DEBUG((*iAppList)[i].iAppHolder, Panic(EDPanicNoAppHolder)); - if ((*iAppList)[i].iAppHolder->Application()==aApp) - { - (*iAppList)[i].iToBeRemoved=ETrue; - } - } - - } - - -CApaDocument* CApaProcess::CreateDocL(CApaApplication* aApp) -// creates a new doc with aApp and adds it to the list before returning a handle to it -// - { - __SHOW_TRACE(_L("Starting CApaProcess::CreateDocL")); - __ASSERT_DEBUG(aApp,Panic(EDPanicNoApp)); - // - // create a new doc with the app - CApaDocument* doc=aApp->CreateDocumentL(this); //lint !e613 Possible use of null pointer - Asserted above - __ASSERT_ALWAYS(doc!=NULL,Panic(EPanicDocumentNotCreated)); - // add the doc to the list - CleanupStack::PushL(doc); - iDocList->AppendL(doc); - CleanupStack::Pop(); // doc - // return a handle to the doc - return doc; - } - - -CApaAppHolder* CApaProcess::FindAppInListL(const TDesC& aAppFileName,TUid aUid)const -// returns pointer to a matching app, or NULL if not in list -// - { - __ASSERT_DEBUG(iAppList, Panic(EPanicNullPointer)); - TInt index=iAppList->Count(); - if (aUid!=KNullUid) - {// search by UID - while (--index>=0) - { - __ASSERT_DEBUG((*iAppList)[index].iAppHolder, Panic(EDPanicNoAppHolder)); - if ((*iAppList)[index].iAppHolder->Uid()==aUid) - { - (*iAppList)[index].iToBeRemoved = FALSE; - return (*iAppList)[index].iAppHolder; // match found - } - } - } - else - {// search by name as no UID has been supplied - TParse app; TParse suspect; - User::LeaveIfError(app.Set(aAppFileName,NULL,NULL)); - while (--index>=0) - { - __ASSERT_DEBUG((*iAppList)[index].iAppHolder, Panic(EDPanicNoAppHolder)); - suspect.SetNoWild((*iAppList)[index].iAppHolder->FileName(),NULL,NULL); - if (!app.Name().CompareF(suspect.Name())) - { - (*iAppList)[index].iToBeRemoved = FALSE; - return (*iAppList)[index].iAppHolder; // match found - } - } - } - return NULL; // no match found - } - -#ifdef USING_ECOM_RECOGS -CApaExe* CApaProcess::AddAppExeL(TApaApplicationFactory aApplicationFactory) - { - CApaExe* exe = new(ELeave) CApaExe(); - CleanupStack::PushL(exe); - - // create the app - exe->CreateApplicationL(aApplicationFactory); - __ASSERT_DEBUG(exe->Application(), Panic(EPanicNullPointer)); - exe->Application()->PreDocConstructL(); - - // add the application to the list and return a pointer to it - TApaAppHolderInfo info(exe); - __ASSERT_DEBUG(iAppList, Panic(EPanicNullPointer)); - iAppList->AppendL(info); - CleanupStack::Pop(exe); - - return exe; - } -#endif // USING_ECOM_RECOGS - - -EXPORT_C TPtrC CApaProcess::MainDocFileName()const -/** Returns the filename of the main document. - -@return A non-modifiable pointer descriptor to the main document filename. -For non file-based applications, the length of this descriptor is zero. */ - { - if (iMainDocFileName!=NULL) - { - return *iMainDocFileName; - } - return KNullDesC(); - } - -/** Reserved for future use */ -EXPORT_C void CApaProcess::CApaProcess_Reserved1() - { - } - -/** Reserved for future use */ -EXPORT_C void CApaProcess::CApaProcess_Reserved2() - { - } - -///////////////////////////// -// TApaApplicationFactory -///////////////////////////// - -/** -Default constructor -*/ - -/** Constructor for TApaApplicationFactory */ -EXPORT_C TApaApplicationFactory::TApaApplicationFactory() - :iType(ETypeFunction), - iData(0), - iApplication(NULL) - { - } - -/** -Constructor. -@publishedAll -@released -@param aFunction The function from which the application is to be created. -*/ -EXPORT_C TApaApplicationFactory::TApaApplicationFactory(TFunction aFunction) - :iType(ETypeFunction), - iData(reinterpret_cast(aFunction)), - iApplication(NULL) - { - } - -/** -Constructor. Use this constructor in preference to the constructor taking a "TUid" parameter -if at all possible as it is much more efficient. -@publishedAll -@released -@param aEmbeddedApplicationInformation The ECOM implementation-information of the embedded application to be created. -*/ -EXPORT_C TApaApplicationFactory::TApaApplicationFactory(const CImplementationInformation& aEmbeddedApplicationInformation) - :iType(ETypeEmbeddedApplicationInformation), - iData(reinterpret_cast(&aEmbeddedApplicationInformation)), - iApplication(NULL) - { - } - -/** -Constructor. Use the constructor taking a "const CImplementationInformation&" parameter in preference -to this constructor if at all possible as it is much more efficient. -@publishedAll -@released -@param aEmbeddedApplicationUid The ECOM implementation-UID of the embedded application to be created. -*/ -EXPORT_C TApaApplicationFactory::TApaApplicationFactory(TUid aEmbeddedApplicationUid) - :iType(ETypeEmbeddedApplicationUid), - iData(aEmbeddedApplicationUid.iUid), - iApplication(NULL) - { - } - -#ifdef USING_ECOM_RECOGS -CApaApplication* TApaApplicationFactory::CreateApplicationL() const - { - CApaApplication* application = NULL; - - switch (iType) - { - case ETypeFunction: - { - __ASSERT_DEBUG(iData, Panic(EPanicNullPointer)); - application=(*reinterpret_cast(iData))(); - break; - } - case ETypeEmbeddedApplicationInformation: - { - __ASSERT_DEBUG(iData, Panic(EPanicNullPointer)); - const CImplementationInformation& embeddedApplicationInformation=*reinterpret_cast(iData); - TUid uid = embeddedApplicationInformation.ImplementationUid(); - application=CreateEmbeddedApplicationL(uid); - break; - } - case ETypeEmbeddedApplicationUid: - { - TUid uid = TUid::Uid(iData); - application=CreateEmbeddedApplicationL(uid); - break; - } - default: - Panic(EPanicBadApplicationFactoryType); - } - - return application; - } - -HBufC* TApaApplicationFactory::AppFileNameL() const - { - HBufC* appFileName = NULL; - switch (iType) - { - case ETypeFunction: - { - // Assume that if the type is a function pointer then the app is not embedded (so - // the filename is the filename of this process). - appFileName = RProcess().FileName().AllocL(); - break; - } - case ETypeEmbeddedApplicationInformation: - { - const CImplementationInformation& embeddedApplicationInformation=*REINTERPRET_CAST(const CImplementationInformation*,iData); - appFileName = FullAppFileNameL(embeddedApplicationInformation.DisplayName()); - break; - } - case ETypeEmbeddedApplicationUid: - { - TUid uid = TUid::Uid(iData); - HBufC* displayName = EmbeddedApplicationDisplayNameLC(uid); - appFileName = FullAppFileNameL(*displayName); - CleanupStack::PopAndDestroy(displayName); - break; - } - default: - Panic(EPanicBadApplicationFactoryType); - } - - return appFileName; - } - -TUid TApaApplicationFactory::AppFileUid() const - { - TUid uid=KNullUid; - switch (iType) - { - case ETypeFunction: - { - uid = RProcess().Type()[2]; - break; - } - case ETypeEmbeddedApplicationInformation: - { - const CImplementationInformation& embeddedApplicationInformation=*REINTERPRET_CAST(const CImplementationInformation*,iData); - uid = embeddedApplicationInformation.ImplementationUid(); - break; - } - case ETypeEmbeddedApplicationUid: - { - uid = TUid::Uid(iData); - break; - } - default: - Panic(EPanicBadApplicationFactoryType); - } - return uid; - } - -HBufC* TApaApplicationFactory::FullAppFileNameL(const TDesC& aAppName) - { - // This was appropriately changed for data caging (binaries placed in \sys\bin\) - TFileName fileName; - Dll::FileName(fileName); - - TParse parse; - parse.SetNoWild(aAppName, &KApplicationLocation, &fileName); - return parse.FullName().AllocL(); - } - -CApaApplication* TApaApplicationFactory::CreateEmbeddedApplicationL(TUid aUid) - { // static - CApaApplication* const application=static_cast(REComSession::CreateImplementationL(aUid,_FOFF(CApaApplication,iDtorKey))); - const TUid appUid = application->AppDllUid(); - __ASSERT_ALWAYS(appUid==aUid, Panic(EPanicUidsDoNotMatch)); - return application; - } - - -HBufC* TApaApplicationFactory::EmbeddedApplicationDisplayNameLC(TUid aUid) - { // static - HBufC* displayName=NULL; - - RImplInfoPtrArray implementationArray; - CleanupStack::PushL(TCleanupItem(CleanupImplementationArray,&implementationArray)); - REComSession::ListImplementationsL(KUidFileEmbeddedApplicationInterfaceUid,implementationArray); - for (TInt i=implementationArray.Count()-1; i>=0; --i) - { - const CImplementationInformation& implementationInformation=*implementationArray[i]; - if (implementationInformation.ImplementationUid().iUid==aUid.iUid) - { - displayName=implementationInformation.DisplayName().AllocL(); - break; - } - } - CleanupStack::PopAndDestroy(&implementationArray); - if (displayName==NULL) - { - User::Leave(KErrNotFound); - } - CleanupStack::PushL(displayName); - - return displayName; - } - -void TApaApplicationFactory::CleanupImplementationArray(TAny* aImplementationArray) - { // static - __ASSERT_DEBUG(aImplementationArray, Panic(EPanicNullPointer)); - RImplInfoPtrArray& implementationArray=*static_cast(aImplementationArray); - implementationArray.ResetAndDestroy(); - implementationArray.Close(); - } - -// -// MApaEmbeddedDocObserver -// - -/** Constructor for MApaEmbeddedDocObserver */ -EXPORT_C MApaEmbeddedDocObserver::MApaEmbeddedDocObserver() - { - } - -/** Reserved for future use */ -EXPORT_C void MApaEmbeddedDocObserver::MApaEmbeddedDocObserver_Reserved1() - { - } - -/** Reserved for future use */ -EXPORT_C void MApaEmbeddedDocObserver::MApaEmbeddedDocObserver_Reserved2() - { - } -#endif // USING_ECOM_RECOGS