diff -r 0efa10d348c0 -r a5a39a295112 homescreenpluginsrv/hspsmanager/src/hspsserverutil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/homescreenpluginsrv/hspsmanager/src/hspsserverutil.cpp Wed Sep 01 12:22:09 2010 +0100 @@ -0,0 +1,2252 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* 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". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility for common code. +* +*/ + + +#include "hspsthememanagement.h" +#include "hspsserverutil.h" +#include "hspsodt.h" +#include "hspsdomdepthiterator.h" +#include "hspsdomnode.h" +#include "hspsdomdocument.h" +#include "hspsconfiguration.h" +#include "hspsdomlist.h" +#include "hspsresource.h" +#include "hspsdomattribute.h" +#include "hspsmanifest.h" +#include "bautils.h" +#include "sysutil.h" +#include +#include + + +_LIT(KHspsFolder, "\\200159c0\\themes\\" ); +_LIT(KSourcesFolder, "\\sources\\"); +_LIT( KThemesFolder, "\\themes\\" ); +_LIT( KDoubleBackSlash, "\\" ); +_LIT8( KHexPrefix8, "0x" ); +_LIT( KClientSources, "c:\\private\\%x\\%D\\%D\\%D\\%S\\sources\\%S" ); + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GenerateConfigurationAttributesL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::GenerateConfigurationAttributesL( ChspsODT& aOdt ) + { + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + ChspsDomNode* prevNode = NULL; + ChspsDomNode* node = iter->First(); + while( node && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // Configuration element + if ( name == KConfigurationElement ) + { + // Add attributes for the configuration node + // NOTE! ID attribute is not set here + TPtrC8 ptr = KManifestTypeApp().Ptr(); + switch ( aOdt.ConfigurationType() ) + { + case EhspsViewConfiguration: + { + ptr.Set( KManifestTypeView ); + } + break; + case EhspsWidgetConfiguration: + { + ptr.Set( KManifestTypeWidget ); + } + break; + case EhspsTemplateConfiguration: + { + ptr.Set( KManifestTypeTemplate ); + } + break; + default: + { + } + } + + AddAttributeDescL( *node, KConfigurationAttrType, ptr ); + + AddAttributeNumericL( *node, KConfigurationAttrInterface, aOdt.RootUid(), EHex ); + + AddAttributeNumericL( *node, KConfigurationAttrUid, aOdt.ThemeUid(), EHex ); + + // Create "name" and "_name" attributes, of which latter holds the entity reference + // (logical key for finding localizad strings) + HBufC8* nameBuf = HBufC8::NewLC( aOdt.ThemeFullName().Length() ); + TPtr8 namePtr( nameBuf->Des() ); + namePtr.Copy( aOdt.ThemeFullName() ); + AddAttributeDescL( *node, KConfigurationAttrName, namePtr ); // will be updated when localized + AddAttributeDescL( *node, KConfigurationAttrNameEntity, namePtr ); // logical id + CleanupStack::PopAndDestroy( nameBuf ); + + // Create theme version attribute + HBufC8* tv = HBufC8::NewLC( aOdt.ThemeVersion().Length() ); + TPtr8 tvPtr( tv->Des() ); + tvPtr.Copy( aOdt.ThemeVersion() ); + AddAttributeDescL( *node, KConfigurationAttrVersion, tvPtr ); + CleanupStack::PopAndDestroy( tv ); + + AddAttributeNumericL ( *node, KConfigurationAttrMultiInstance, + aOdt.MultiInstance(), EDecimal ); + + AddAttributeDescL( *node, KConfigurationAttrState, KConfStateNotConfirmed ); + + const TInt descLength = aOdt.Description().Length(); + if ( descLength ) + { + // Add description of the widget (16 > 8bit conversion) + HBufC8* buf = HBufC8::NewLC( descLength ); + TPtr8 bufPtr( buf->Des() ); + bufPtr.Copy( aOdt.Description() ); + AddAttributeDescL( *node, KConfigurationAttrDesc, bufPtr ); // will be updated when localized + AddAttributeDescL( *node, KConfigurationAttrDescEntity, bufPtr ); // logical id + CleanupStack::PopAndDestroy( buf ); + } + else + { + AddAttributeDescL( *node, KConfigurationAttrDesc, KNullDesC8 ); + } + + } + + prevNode = node; + node = iter->NextL(); + } + CleanupStack::PopAndDestroy( iter ); + } + +// ----------------------------------------------------------------------------- +// ChspsInstallationHandler::GenerateObjectAttributesL() +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::GenerateObjectAttributesL( ChspsODT& aOdt ) + { + // Find the configuration node + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomNode* configurationNode = dom.RootNode(); + if ( !configurationNode ) + { +#ifdef _hsps_DEBUG_ + RDebug::Print( _L("hspsServerUtil::GenerateObjectAttributesL(): - invalid ODT!") ); +#endif + User::Leave( KErrGeneral ); + } + + // Find resources node from the XML definition (child of the configuration node) + ChspsDomList& childsList = configurationNode->ChildNodes(); + ChspsDomNode* resourcesNode = (ChspsDomNode *)childsList.FindByName( KResourcesElement ); + TInt popResources = EFalse; + if ( !resourcesNode ) + { + // Create a node and add it into the configuration node + resourcesNode = dom.CreateElementNSL( + KResourcesElement, + configurationNode->Namespace() + ); + CleanupStack::PushL( resourcesNode ); + popResources = ETrue; + configurationNode->AddChildL( resourcesNode ); + resourcesNode->SetParent( configurationNode ); + } + + // Loop ODT's resources (parsed ealier from the manifest file) + const TInt resourceCount = aOdt.ResourceCount(); + TBool addResource = EFalse; + for( TInt resourceIndex=0; resourceIndex < resourceCount; resourceIndex++ ) + { + ChspsResource& resource = aOdt.ResourceL( resourceIndex ); + + addResource = EFalse; + + // If resource is located under the sources folder + if ( resource.FileName().FindF( KSourcesFolder ) > 0 ) + { + // If resource is for the active device language or it's a locale independent resource + addResource = ( resource.Language() == aOdt.OdtLanguage() || resource.Language() == ELangNone ); + } + + if ( addResource ) + { + // Create an object node and add the object into the resources list + ChspsDomNode* objectNode = dom.CreateElementNSL( + KObjectElement, + resourcesNode->Namespace() + ); + CleanupStack::PushL( objectNode ); + resourcesNode->AddChildL( objectNode ); + objectNode->SetParent( resourcesNode ); + + // Name (16->8bit conversion) + HBufC8* nameBuf = HBufC8::NewLC( resource.ResourceId().Length() ); + TPtr8 namePtr( nameBuf->Des() ); + namePtr.Copy( GetFixedOdtName( resource.ResourceId() ) ); + + AddAttributeDescL( *objectNode, KObjectAttrFilename, namePtr ); + CleanupStack::PopAndDestroy( nameBuf ); + + // Media type + TPtrC8 mimePtr( resource.MimeType().Des8() ); + if ( mimePtr.Length() ) + { + AddAttributeDescL( *objectNode, KObjectAttrMediatype, mimePtr ); + } + + // Tag + TPtrC tagPtr( resource.Tags() ); + if ( tagPtr.Length() ) + { + // (16->8bit conversion) + HBufC8* buf = HBufC8::NewLC( tagPtr.Length() ); + TPtr8 bufPtr( buf->Des() ); + bufPtr.Copy( tagPtr ); + AddAttributeDescL( *objectNode, KObjectAttrTag, bufPtr ); + CleanupStack::PopAndDestroy( buf ); + } + + // Path + TInt pos = resource.FileName().FindF( KHspsFolder ); + if ( pos > 0 ) + { + // Remove filename and extension from the path + TParsePtrC parserPtr( resource.FileName() ); + TFileName path( parserPtr.DriveAndPath() ); + + // Remove path to the Definition repository + path.Copy( path.Mid( pos + KHspsFolder().Length() ) ); + + // Fix path references for localized resources + GetLocaleIndependentResourcePath( resource.Language(), path ); + + // 16->8bit conversion + HBufC8 *pathBuf = HBufC8::NewLC( path.Length() ); + pathBuf->Des().Copy( path ); + + AddAttributeDescL( *objectNode, KObjectAttrPath, pathBuf->Des() ); + CleanupStack::PopAndDestroy( pathBuf ); + } + + // Now the document has an ownership of the objectnode + CleanupStack::Pop( objectNode ); + + } + + } // for loop + + if ( popResources ) + { + // Now the document has an ownership of the resourcesNode + CleanupStack::Pop( resourcesNode ); + } + } + + +TFileName hspsServerUtil::GetFixedOdtName( + const TDesC& aNameAndExtension ) + { + TParsePtrC parsePtr( aNameAndExtension ); + TPtrC fileExtension = parsePtr.Ext(); + if ( fileExtension.Length() > 2 && fileExtension.Left(2).CompareF( _L(".o") ) == 0 ) + { + // Strip the first letter + TInt odtIndex(0); + TLex lex( fileExtension.Mid(3) ); + if ( lex.Val( odtIndex ) == KErrNone && odtIndex >= 0 ) + { + fileExtension.Set( _L(".o0000") ); + } + } + + TFileName fileName( parsePtr.Name() ); + fileName.Append( fileExtension ); + return fileName; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetLocaleIndependentResourcePath +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::GetLocaleIndependentResourcePath( + const TLanguage& aResourceLanguage, + TFileName& aPath ) + { + TBool isLocaleSpecificResource = ( aResourceLanguage != ELangNone ); + + // If locale specific resource + if ( isLocaleSpecificResource ) + { + // Remove locale specific subfolder from the path + TInt pos = aPath.FindF( KSourcesFolder ); + if ( pos ) + { + aPath.Copy( aPath.Left( pos + KSourcesFolder().Length() ) ); + } + } + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetRelativeResourcePath +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::GetRelativeResourcePath( + const TFileName& aSourceFile, + TPath& aRelativePath ) + { + // find last part (structure after "/themes/") + TInt pos = aSourceFile.FindF( KThemesFolder ); + if( pos != KErrNotFound ) + { + pos += KThemesFolder().Length(); + TInt len( aSourceFile.Length() - pos ); + aRelativePath.Copy( aSourceFile.Right( len ) ); + } + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::AddAttributeNumericL +// ----------------------------------------------------------------------------- +// +TInt hspsServerUtil::AddAttributeNumericL( + ChspsDomNode& aNode, + const TDesC8& aAttrName, + const TInt aValue, + const TRadix aFormat ) + { + // Format change + // Value string, 10 -> Max decimal 4294967295 , max hexadecimal 0xXXXXXXXX + const TInt KMaxLength = 10; + TBuf8 attValueDes8; + + if ( aFormat == EHex ) + { + _LIT8( KFormat8, "%X" ); + _LIT8( KHexPrefix, "0x" ); + attValueDes8.Append( KHexPrefix ); + attValueDes8.AppendFormat( KFormat8, aValue ); + } + else // EDecimal + { + _LIT8( KFormat8, "%d" ); + attValueDes8.AppendFormat( KFormat8, aValue ); + } + + ChspsDomList& attrList = aNode.AttributeList(); + ChspsDomAttribute* attr = static_cast( attrList.FindByName(aAttrName) ); + if ( attr ) + { + // Replace value of the attribute + attr->SetValueL( attValueDes8 ); + } + else + { + // Add an attribute + ChspsDomAttribute* attr = ChspsDomAttribute::NewL( aAttrName, aNode.StringPool() ); + CleanupStack::PushL( attr ); + attr->SetValueL( attValueDes8 ); + ChspsDomList& attrList = aNode.AttributeList(); + attrList.AddItemL( attr ); //takes ownership + CleanupStack::Pop( attr ); + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::AddAttributeDescL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::AddAttributeDescL( + ChspsDomNode& aNode, + const TDesC8& aAttrName, + const TDesC8& aValue ) + { + ChspsDomList& attrList = aNode.AttributeList(); + ChspsDomAttribute* attr = static_cast( attrList.FindByName(aAttrName) ); + if ( attr ) + { + // Replace value of the attribute + attr->SetValueL( aValue ); + } + else + { + // Add an attribute + ChspsDomAttribute* attr = ChspsDomAttribute::NewL( aAttrName, aNode.StringPool() ); + CleanupStack::PushL( attr ); + attr->SetValueL( aValue ); + ChspsDomList& attrList = aNode.AttributeList(); + attrList.AddItemL( attr ); //takes ownership + CleanupStack::Pop( attr ); + } + } + + +// ----------------------------------------------------------------------------- +// Finds a configuration node with the provided id attribute +// ----------------------------------------------------------------------------- +// +ChspsDomNode* hspsServerUtil::FindConfigurationNodeL( + ChspsODT& aOdt, + const TInt aConfigurationId ) + { + __UHEAP_MARK; + + ChspsDomNode *configurationNode = NULL; + + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + // Find a configuration node with an id attribute that matches the provided id + ChspsDomNode* node = iter->First(); + ChspsDomNode* prevNode = NULL; + TBool jobDone = EFalse; + while( node && !jobDone && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // An element was found + if ( name == KConfigurationElement ) + { + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* idAttr = static_cast( attrList.FindByName(KConfigurationAttrId) ); + if ( !idAttr ) + { + // Return with NULL + jobDone = ETrue; + } + else + { + TInt id(0); + const TDesC8& idValue = idAttr->Value(); + TLex8 lex( idValue ); + lex.Val( id ); + if ( aConfigurationId == id ) + { + configurationNode = node; + jobDone = ETrue; + } + } + } + + prevNode = node; + node = iter->NextL(); + } + CleanupStack::PopAndDestroy( iter ); + +#ifdef _hsps_DEBUG_ + if ( !configurationNode ) + { + RDebug::Print( _L("hspsServerUtil::FindConfigurationNodeL(): failed to find the configuration node") ); + } +#endif + + __UHEAP_MARKEND; + + return configurationNode; + } + +// ----------------------------------------------------------------------------- +// Finds a plugin node with the provided id +// ----------------------------------------------------------------------------- +// +ChspsDomNode* hspsServerUtil::FindPluginNodeL( + ChspsODT& aOdt, + const TInt aPluginId ) + { + __UHEAP_MARK; + + ChspsDomNode* pluginNode = NULL; + + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + // Find a plugin node with the provided id attribute + ChspsDomNode* node = iter->First(); + ChspsDomNode* prevNode = NULL; + TBool jobDone = EFalse; + while( node && !jobDone && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // Plugin element was found + if ( name == KPluginElement ) + { + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* idAttr = static_cast( attrList.FindByName(KPluginAttrId) ); + if ( !idAttr ) + { + // Mandatory information is missing for some reason (should be set at installation handler)! + // Exit with NULL + jobDone = ETrue; + } + else + { + TInt id(0); + const TDesC8& idValue = idAttr->Value(); + TLex8 lex( idValue ); + lex.Val( id ); + if ( aPluginId == id ) + { + pluginNode = node; + jobDone = ETrue; + } + } + } + + prevNode = node; + node = iter->NextL(); + } + CleanupStack::PopAndDestroy( iter ); + +#ifdef _hsps_DEBUG_ + if ( !pluginNode ) + { + RDebug::Print( _L("hspsServerUtil::FindPluginNodeL(): failed to find the plugin node") ); + } +#endif + + __UHEAP_MARKEND; + + return pluginNode; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetConfigurationNameFromDomL +// ----------------------------------------------------------------------------- +// +TPtrC8 hspsServerUtil::FindConfigurationAttrL( + const ChspsODT& aOdt, + const TDesC8& aAttr ) + { + TPtrC8 ptr; + + // Get ODT's DOM and find the 1st configuration node + ChspsDomNode* confNode = aOdt.DomDocument().RootNode(); + if( !confNode || confNode->Name().CompareF( KConfigurationElement) != 0 ) + { + User::Leave( KErrGeneral ); + } + + // Find the name attribute and return it's value + ChspsDomList& attrList = confNode->AttributeList(); + ChspsDomAttribute* attr = static_cast( attrList.FindByName(aAttr) ); + if ( !attr ) + { + User::Leave( KErrGeneral ); + } + ptr.Set( attr->Value() ); + + return ptr; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::RemoveResourceFilesL +// ----------------------------------------------------------------------------- +void hspsServerUtil::RemoveResourceFilesL( + CFileMan& aFilemanager, + RFs& aFs, + const TInt aAppUid, + const ChspsODT& aPluginODT ) + { + // Remove all plug-in resources + for( TInt i=0; i< aPluginODT.ResourceCount(); i++ ) + { + ChspsResource& r = aPluginODT.ResourceL( i ); + if( r.FileName().Find( KSourcesFolder ) > 0 ) + { + TPtrC id( GetFixedOdtName( r.ResourceId() ) ); + const TDesC& ver( aPluginODT.ThemeVersion() ); + TFileName resource; + resource.Format( + KClientSources, + aAppUid, + aPluginODT.RootUid(), + aPluginODT.ProviderUid(), + aPluginODT.ThemeUid(), + &ver, + &id ); + if( BaflUtils::FileExists( aFs, resource ) ) + { + aFilemanager.Delete( resource, 0 ); + } + } + } + } + + +// ----------------------------------------------------------------------------- +// hspsServerUtil::CopyResourceFilesL +// ----------------------------------------------------------------------------- +TInt hspsServerUtil::CopyResourceFilesL( + ChspsODT& aAppODT, + RFs& aFs, + CFileMan& aFilemanager, + const TInt aDeviceLanguage, + const TInt aConfUid, + const TDesC& aDestination, + const TBool aIsRelevant ) + { + TInt error( KErrNone ); + RPointerArray widgetResources; // Objects are not owned. + CleanupClosePushL( widgetResources ); + + // Find resources for the language or common to all languages or test resources + // if others couldn't be found + GetResourcesForLanguageL( + aAppODT, + aConfUid, + (TLanguage)aDeviceLanguage, + widgetResources ); + + // Copy the resources found + for( TInt i = 0; ( i < widgetResources.Count() && !error ); i++ ) + { + ChspsResource* resource = widgetResources[i]; + if( !resource ) + { + continue; + } + + // Get relative path under the themes folder + TPath relativePath; + GetRelativeResourcePath( + resource->FileName(), + relativePath ); + + // Strip language indicator from the relative path + GetLocaleIndependentResourcePath( + resource->Language(), + relativePath ); + + // Finalize target path + TPath targetPath; + targetPath.Copy( aDestination ); + targetPath.Append( relativePath ); + + // Create target path and copy files when required + error = CopyResourceFileL( + aFs, + aFilemanager, + targetPath, + resource->FileName(), + aIsRelevant ); + if ( error == KErrAlreadyExists ) + { + error = KErrNone; + } + + } // copy loop + + widgetResources.Reset(); + CleanupStack::PopAndDestroy( 1, &widgetResources ); + + return error; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::CopyResourceFileL +// ----------------------------------------------------------------------------- +// +TInt hspsServerUtil::CopyResourceFileL( + RFs& aFs, + CFileMan& aFilemanager, + const TPath& aTargetPath, + const TFileName& aSourceFile, + const TBool aIsRelevant ) + { + // Construct target file with full path. + TFileName targetFile; + + TParse targetParser; + targetParser.Set( aTargetPath, NULL, NULL ); + + if( targetParser.NamePresent() ) + { + targetFile = aTargetPath; + } + else + { + TParse sourceParser; + sourceParser.Set( aSourceFile, NULL, NULL ); + targetFile = targetParser.DriveAndPath(); + targetFile.Append( sourceParser.NameAndExt() ); + } + + TInt error = KErrNone; + + if ( aIsRelevant + || hspsServerUtil::ResourceCopyIsRelevantL( + aSourceFile, + targetFile, + aFs ) + ) + { + // Make target folder + error = aFs.MkDirAll( aTargetPath ); + if( error == KErrAlreadyExists ) + { + // lets ignore error if directory already exists + error = KErrNone; + } + + if( !error ) + { + // Slowish operation + error = aFilemanager.Copy( + aSourceFile, + aTargetPath ); + } + + if( !error ) + { + // Clear readonly file attribs that might be inherited from the source file + aFilemanager.Attribs( + aTargetPath, + 0, + KEntryAttReadOnly, + TTime( 0 ) ); // TTime(0) = preserve original time stamp. + } + } + + return error; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::ResourceCopyIsRelevant +// ----------------------------------------------------------------------------- +// +TBool hspsServerUtil::ResourceCopyIsRelevantL( + const TDesC& aSource, + const TDesC& aTarget, + RFs& aFs ) + { + // Basic sanity check. + if( aSource.Length() == 0 || aTarget.Length() == 0 ) + { + return EFalse; + } + + // Collect data from files. + + TEntry targetEntry; + TInt entryError = aFs.Entry( aTarget, targetEntry ); + if( entryError == KErrNotFound || + entryError == KErrPathNotFound ) + { + // Target does not exist. Copy needed. + return ETrue; + } + else if( entryError != KErrNone ) + { + // All other errors handled here. Better not to copy. + return EFalse; + } + + TEntry sourceEntry; + entryError = aFs.Entry( aSource, sourceEntry ); + if( entryError != KErrNone ) + { + // Problem. Do not copy. + return EFalse; + } + + TParse sourceParser; + sourceParser.Set( aSource, NULL, NULL ); + + TParse targetParser; + targetParser.Set( aTarget, NULL, NULL ); + + // We have tdesc of target drive but SysUtils need TDriveNumber instead + // so extract it from tdesc. default to C. + TInt targetDriveNumber = EDriveC; + + // Sanity checks before accessing descriptor (prevent "out of bounds" panic). + if( targetParser.DrivePresent() && + targetParser.Drive().Length() > 0 ) + { + // Use tmp variable so that CharToDrive does not mess our fallback + // value. (it should not do that in case of error... but better + // to do fool-proof.) + TInt tmpDriveNumber = EDriveC; + + // Convert from TDesC to enumeration of drives. + if( RFs::CharToDrive( targetParser.Drive()[0], tmpDriveNumber ) == KErrNone ) + { + targetDriveNumber = tmpDriveNumber; + } + } + + // Size and time stamp identical? + if( sourceEntry.iSize == targetEntry.iSize && + sourceEntry.iModified == targetEntry.iModified ) + { + return EFalse; + } + + // Check required disk space. + TInt requiredDiskSpace = 0; + if( sourceEntry.iSize > targetEntry.iSize ) + { + requiredDiskSpace = sourceEntry.iSize - targetEntry.iSize; + } + else + { + requiredDiskSpace = sourceEntry.iSize; + } + + if( requiredDiskSpace != 0 ) + { + if( SysUtil::DiskSpaceBelowCriticalLevelL( &aFs, requiredDiskSpace, targetDriveNumber ) ) + { + return EFalse; + } + } + + // All tests passed. + return ETrue; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::UpdateConfigurationStateL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::UpdateConfigurationStateL( + ChspsODT& aOdt, + TDesC8& aConfState, + TDesC8& aNextConfState, + TBool& aOdtUpdated ) + { + aOdtUpdated = EFalse; + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + ChspsDomNode* prevNode = NULL; + ChspsDomNode* node = iter->First(); + + while( node && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // Configuration element + if ( name == KConfigurationElement ) + { + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* attr = static_cast( + attrList.FindByName( KConfigurationAttrState ) ); + if ( attr && attr->Value().CompareF( aConfState ) == 0 ) + { + attr->SetValueL( aNextConfState ); + aOdtUpdated = ETrue; + } + } + + prevNode = node; + node = iter->NextL(); + } + + CleanupStack::PopAndDestroy( iter ); + + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::UpdateAppConfigurationStateL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::UpdateAppConfigurationStateL( + ChspsODT& aAppOdt, + const TDesC8& aConfState, + const TDesC8& aNextConfState ) + { + __ASSERT_DEBUG( aConfState.Length() > 0, User::Leave( KErrArgument) ); + __ASSERT_DEBUG( aNextConfState.Length() > 0, User::Leave( KErrArgument) ); + + // Update application configuration state + ChspsDomNode* appConfNode = hspsServerUtil::FindNodeByAttributeL( + aAppOdt, + KConfigurationElement, + KConfigurationAttrType, + KConfTypeApp ); + ChspsDomList& attrList = appConfNode->AttributeList(); + ChspsDomAttribute* attr = static_cast( + attrList.FindByName( KConfigurationAttrState ) ); + if ( attr && attr->Value().CompareF( aConfState ) == 0 ) + { + attr->SetValueL( aNextConfState ); + } + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::FindNodeByAttributeL +// ----------------------------------------------------------------------------- +// +ChspsDomNode* hspsServerUtil::FindNodeByAttributeL( + ChspsODT& aOdt, + const TDesC8& aNodeName, + const TDesC8& aAttrName, + const TDesC8& aAttrValue) + { + __UHEAP_MARK; + + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + ChspsDomNode* foundNode( NULL ); + ChspsDomNode* prevNode( NULL ); + ChspsDomNode* node = iter->First(); + while( node && + prevNode != node && + foundNode == NULL ) + { + const TDesC8& name = node->Name(); + if ( name.CompareF( aNodeName ) == 0 ) + { + // Node name match + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* attr = static_cast( + attrList.FindByName( aAttrName ) ); + if ( attr && attr->Value().CompareF( aAttrValue ) == 0 ) + { + // Attribute name and value match + foundNode = node; + } + } + // Get next node + prevNode = node; + node = iter->NextL(); + } + + CleanupStack::PopAndDestroy( iter ); + + __UHEAP_MARKEND; + + return foundNode; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::FindUniquePluginsL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::FindUniquePluginsL( + ChspsODT& aOdt, + RArray& aPluginArray ) + { + aPluginArray.Reset(); + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + ChspsDomNode* node = iter->First(); + ChspsDomNode* prevNode = NULL; + while( node && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // Plugin element was found + if ( name == KPluginElement ) + { + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* uidAttr = static_cast( attrList.FindByName(KPluginAttrUid) ); + if ( uidAttr ) + { + // Convert from hex to int + const TUid pluginUid = ConvertDescIntoUid( uidAttr->Value() ); + if ( pluginUid.iUid > 0 ) + { + TBool isUnique = ETrue; + for( TInt i=0; isUnique && iNextL(); + } + CleanupStack::PopAndDestroy( iter ); +} + +//---------------------------------------------------------------------------- +// CHspsServiceUtilities::HexString2Uint +// ---------------------------------------------------------------------------- +// +TInt hspsServerUtil::HexString2Uint( + const TDesC8& aStr, + TUint& aTrg ) + { + // Assign to lexer. + TLex8 lex( aStr ); + + // Ignore preceding "0x" if it exists. TLex does not know how to handle that + // and returns just zero. + if( aStr.Length() >= KHexPrefix8().Length() && + aStr.FindF( KHexPrefix8() ) == 0 ) + { + lex.Inc( KHexPrefix8().Length() ); + } + + // Actual conversion. + TInt status = KErrNone; + TUint val = 0; + status = lex.Val( val, EHex ); + + // Error check. + if( status == KErrNone ) + { + aTrg = val; + } + + return status; + } + +//---------------------------------------------------------------------------- +// CHspsServiceUtilities::DecString2Int +// ---------------------------------------------------------------------------- +// +TInt hspsServerUtil::DecString2Int( + const TDesC8& aStr ) + { + TLex8 lex( aStr ); + TUint value; + lex.Mark(); + + while ( lex.Peek().IsDigit() ) + { + lex.Inc(); + } + TPtrC8 uidToken = lex.MarkedToken(); + TLex8 uidLex( uidToken ); + TInt err = uidLex.Val( value, EDecimal ); + + return value; + } +// ----------------------------------------------------------------------------- +// Returns a count of plugin instances. +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::PluginInstanceCountL( + const ChspsODT& aAppODT, + const TInt aPluginUid, + TInt& aInstanceCount ) + { + aInstanceCount = 0; + + ChspsDomDocument& dom = aAppODT.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + // Find a plugin node with the provided id attribute + ChspsDomNode* node = iter->First(); + ChspsDomNode* prevNode = NULL; + TBool jobDone = EFalse; + while( node && !jobDone && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // Plugin element was found + if ( name == KPluginElement ) + { + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* attr = static_cast( attrList.FindByName(KPluginAttrUid) ); + if ( !attr ) + { + // Mandatory information is missing for some reason (should be set at installation handler)! + // Exit with NULL + jobDone = ETrue; + } + else + { + // Convert from (hex?) string into TUid presentation + const TUid uid = ConvertDescIntoUid( attr->Value() ); + if ( aPluginUid == uid.iUid ) + { + aInstanceCount++; + } + } + } + + prevNode = node; + node = iter->NextL(); + } + CleanupStack::PopAndDestroy( iter ); + } +// ----------------------------------------------------------------------------- +// hspsServerUtil::ConvertDescIntoUid() +//---------------------------------------------------------------------------- +// +TUid hspsServerUtil::ConvertDescIntoUid( + const TDesC8& aStr ) + { + TLex8 lex(aStr); + TUint pluginUid; + lex.Mark(); + + if(lex.Peek() == '0') + { + lex.Inc(); + } + if(lex.Peek() == 'x') + { + lex.Inc(); + } + lex.Mark(); + while (lex.Peek().IsHexDigit()) + { + lex.Inc(); + } + TPtrC8 uidToken = lex.MarkedToken(); + TLex8 uidLex(uidToken); + TInt err = uidLex.Val(pluginUid,EHex); + + return TUid::Uid(pluginUid); + } +//---------------------------------------------------------------------------- +// hspsServerUtil::FindChildNodeByTagL() +// ---------------------------------------------------------------------------- +// +ChspsDomNode* hspsServerUtil::FindChildNodeByTagL( + const TDesC8& aNodeTag, + ChspsDomNode& aParentNode, + TInt& aIndex ) + { + ChspsDomNode* node( NULL ); + ChspsDomList& items = aParentNode.ChildNodes(); + TInt length = items.Length(); + node = NULL; + for ( TInt i = aIndex; i < length && node == NULL; i++ ) + { + node = static_cast( items.Item( i ) ); + const TDesC8& name = node->Name(); + if( name.Compare( aNodeTag ) != 0 ) + { + node = NULL; + } + else + { + aIndex = i; + } + } + + return node; + } + +//---------------------------------------------------------------------------- +// hspsServerUtil::FindFilesL() +// ---------------------------------------------------------------------------- +// +void hspsServerUtil::FindFilesL( + const TDesC& aDirName, + const TDesC& aFileName, + RArray & aFiles ) + { + RFs fs; + CleanupClosePushL( fs ); + User::LeaveIfError( fs.Connect() ); + + // Find files from root directory + hspsServerUtil::FindFilesFromDirL( + aDirName, + aFileName, + aFiles ); + + // Directory scanner to browse directory structure + CDirScan* dirScan = CDirScan::NewL( fs ); + CleanupStack::PushL( dirScan ); + dirScan->SetScanDataL( + aDirName, + ( KEntryAttDir | KEntryAttMatchExclusive ), + ESortNone ); + + // Directory path where installation files are searched + TFileName dirName; + + // Get first directory list + CDir* dirList( NULL ); + dirScan->NextL( dirList ); + // Find files from root directories + while ( dirList ) + { + CleanupStack::PushL( dirList ); + for ( TInt i = 0; i < dirList->Count(); i++ ) + { + // Get directory path + dirName = dirScan->FullPath(); + // Append directory entry + const TEntry& dirEntry = ( *dirList )[ i ]; + dirName.Append( dirEntry.iName ); + dirName.Append( KDoubleBackSlash ); + hspsServerUtil::FindFilesFromDirL( + dirName, + aFileName, + aFiles ); + } + // Get next directory list + CleanupStack::PopAndDestroy( dirList ); + dirScan->NextL( dirList ); + } + + CleanupStack::PopAndDestroy( dirScan ); + + CleanupStack::PopAndDestroy(); // fs + + } + +//---------------------------------------------------------------------------- +// hspsServerUtil::FindFilesFromDirL() +// ---------------------------------------------------------------------------- +// +void hspsServerUtil::FindFilesFromDirL( + const TDesC& aDirName, + const TDesC& aFileName, + RArray & aFiles ) + { + RFs fs; + CleanupClosePushL( fs ); + User::LeaveIfError( fs.Connect() ); + + // File finder to search files from a directory + TFindFile fileFinder( fs ); + + // Define drives where files are searched + TInt driveNumber; + TParse dirParser; + dirParser.Set( aDirName, NULL, NULL ); + // Default drives C: and Z: + TInt findMask( + KDriveAttExclude | + KDriveAttRemovable | + KDriveAttRemote ); + if( RFs::CharToDrive( dirParser.Drive()[0], driveNumber ) == KErrNone ) + { + if ( driveNumber == EDriveC ) + { + // Search from C: drive + findMask = ( + KDriveAttExclude | + KDriveAttRemovable | + KDriveAttRemote | + KDriveAttRom ); + } + else if ( driveNumber == EDriveZ ) + { + // Search from Z: drive + findMask = KDriveAttRom; + } + } + fileFinder.SetFindMask( findMask ); + + // Find files from the directory entry + CDir* fileList( NULL ); + fileFinder.FindWildByDir( aFileName, aDirName, fileList ); + CleanupStack::PushL( fileList ); + for ( TInt k = 0; fileList && k < fileList->Count(); k++ ) + { + // Add found file with full path to file array + const TEntry& fileEntry = (*fileList)[k]; + TFileName file; + file.Append( aDirName ); + file.Append( fileEntry.iName ); + aFiles.Append( file ); + } + CleanupStack::PopAndDestroy( fileList ); + + CleanupStack::PopAndDestroy(); // fs + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::SetAttributeValueL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::SetAttributeValueL( + const ChspsODT& aOdt, + const TDesC8& aNodeName, + const TDesC8& aAttrName, + const TDesC8& aAttrValue, + const TDesC8& aSetAttrName, + const TDesC8& aSetAttrValue ) + { + + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + TBool nodeFound( EFalse ); + ChspsDomNode* prevNode( NULL ); + ChspsDomNode* node = iter->First(); + while( node && + prevNode != node ) + { + const TDesC8& name = node->Name(); + if ( name.CompareF( aNodeName ) == 0 ) + { + // Node name match + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* attr = static_cast( + attrList.FindByName( aAttrName ) ); + if ( attr && attr->Value().CompareF( aAttrValue ) == 0 ) + { + // Attribute name and value match - Defined node found + attr = static_cast( + attrList.FindByName( aSetAttrName ) ); + if ( attr ) + { + // Updated attribute found - Update attribute value + attr->SetValueL( aSetAttrValue ); + } + else + { + // Add new attribute + AddAttributeDescL( *node, aSetAttrName, aSetAttrValue ); + } + nodeFound = ETrue; + } + } + // Get next node + prevNode = node; + node = iter->NextL(); + } + + if ( !nodeFound ) + { + User::Leave( KErrNotFound ); + } + + CleanupStack::PopAndDestroy( iter ); + + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetAttributeValueL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::GetAttributeValueL( + const ChspsODT& aOdt, + const TDesC8& aNodeName, + const TDesC8& aAttrName, + const TDesC8& aAttrValue, + const TDesC8& aGetAttrName, + TPtrC8& aGetAttrValue ) + { + __UHEAP_MARK; + + ChspsDomDocument& dom = aOdt.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + TBool nodeFound( EFalse ); + ChspsDomNode* prevNode( NULL ); + ChspsDomNode* node = iter->First(); + while( node && + prevNode != node && + !nodeFound ) + { + const TDesC8& name = node->Name(); + if ( name.CompareF( aNodeName ) == 0 ) + { + // Node name match + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* attr = static_cast( + attrList.FindByName( aAttrName ) ); + if ( attr && attr->Value().CompareF( aAttrValue ) == 0 ) + { + // Attribute name and value match - Defined node found + attr = static_cast( + attrList.FindByName( aGetAttrName ) ); + if ( attr ) + { + // Updated + aGetAttrValue.Set( attr->Value() ); + nodeFound = ETrue; + } + } + } + // Get next node + prevNode = node; + node = iter->NextL(); + } + + if ( !nodeFound ) + { + User::Leave( KErrNotFound ); + } + + CleanupStack::PopAndDestroy( iter ); + + __UHEAP_MARKEND; + + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::CheckResourceFilesL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::CheckResourceFilesL( + const ChspsODT& aOdt, + const TInt aConfUid ) + { + __UHEAP_MARK; + + // Convert configuration UID to decimal string + TBuf<10> confUid; + _LIT( KFormat, "%D" ); + confUid.AppendFormat( KFormat, aConfUid ); + + RFs fs; + CleanupClosePushL( fs ); + User::LeaveIfError( fs.Connect() ); + + TInt resCount = aOdt.ResourceCount(); + for ( TInt i = 0; i < resCount; i++ ) + { + // Check if resource file belongs to defined configuration + // (file path contains configuration UID string) + ChspsResource& res = aOdt.ResourceL( i ); + TPtrC resFile = res.FileName(); + if ( resFile.FindC( confUid ) != KErrNotFound ) + { + // Check that resource files exists + if ( !BaflUtils::FileExists( fs, resFile ) ) + { + User::Leave( KErrNotFound ); + } + } + } + + CleanupStack::PopAndDestroy(); // fs + + __UHEAP_MARKEND; + + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetConfigurationVersionL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::CheckConfigurationVersionL( + ChspsODT& aOdt, + const TInt aConfUid, + const TDesC& aVersion ) + { + __UHEAP_MARK; + + // Create configuration UID string + TBuf8<10> confUid; + _LIT8( KFormat8, "%X" ); + _LIT8( KHexPrefix, "0x" ); + confUid.Append( KHexPrefix ); + confUid.AppendFormat( KFormat8, aConfUid ); + + // Find configuration node + ChspsDomNode* confNode = hspsServerUtil::FindNodeByAttributeL( + aOdt, + KConfigurationElement, + KConfigurationAttrUid, + confUid ); + + if ( confNode ) + { + ChspsDomList& attrList = confNode->AttributeList(); + ChspsDomAttribute* attr = static_cast( + attrList.FindByName( KConfigurationAttrVersion ) ); + if ( attr ) + { + HBufC8* tv = HBufC8::NewLC( aVersion.Length() ); + TPtr8 tvPtr( tv->Des() ); + tvPtr.Copy( aVersion ); + // Check configuration version + if ( attr->Value().Compare( tvPtr ) != 0 ) + { + // Configuration not supported + User::Leave( KErrNotSupported ); + } + CleanupStack::PopAndDestroy( tv ); + } + else + { + // Invalid configuration + User::Leave( KErrGeneral ); + } + } + else + { + // Configuration not found + User::Leave( KErrNotFound ); + } + + __UHEAP_MARKEND; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::EditPluginNodeActivityL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::EditPluginNodeActivityL( ChspsDomNode* aRootNode, + const TNodeEditMode aEditMode, + TInt aDepth ) + { + // This wrapper exists to prevent modification of original aDepth + // (_EditPluginNodeActivityL uses TInt reference for depth count and + // modifies it). + hspsServerUtil::_EditPluginNodeActivityL( aRootNode, aEditMode, aDepth ); + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::_EditPluginNodeActivityL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::_EditPluginNodeActivityL( ChspsDomNode* aRootNode, + const TNodeEditMode aEditMode, + TInt& aDepth ) + { + // Sanity check. + if( !aRootNode ) + { + return; + } + + // Recursion depth logic. + if( aDepth == RECURSION_DEPTH_INFINITE ) + { + // Work as normal. Recurse as far as object tree exists. + } + else if( aDepth > 0 ) + { + // Depth was defined. Decrement by one. + aDepth--; + } + else if( aDepth == 0 ) + { + // No more recursion. + return; + } + + // Iterate childs + ChspsDomList& childs = aRootNode->ChildNodes(); + for( int i = 0; i < childs.Length(); i++ ) + { + ChspsDomNode* child = static_cast( childs.Item( i ) ); + + // Modify node activity based on selected edit mode. + if( child->Name().CompareF( KPluginElement ) == 0 ) + { + if( aEditMode == EActivateFirst && i == 0 ) + { + hspsServerUtil::AddAttributeDescL( *child, + KPluginAttrActive, + KPluginActiveStateActive ); + } + else + { + hspsServerUtil::AddAttributeDescL( *child, + KPluginAttrActive, + KPluginActiveStateNotActive ); + } + } + + // Recurse. + _EditPluginNodeActivityL( child, + aEditMode, + aDepth ); + } + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetActivePluginNode +// ----------------------------------------------------------------------------- +// +ChspsDomNode* hspsServerUtil::GetActivePluginNode( ChspsDomNode* aParentNode ) + { + // Sanity check. + if( !aParentNode ) + { + return NULL; + } + + // Return structure. + ChspsDomNode* activeNode = NULL; + + // Iterate childs + ChspsDomList& childs = aParentNode->ChildNodes(); + for( int i = 0; i < childs.Length(); i++ ) + { + ChspsDomNode* child = static_cast( childs.Item( i ) ); + + // Only for plugin elements. + if( child->Name().CompareF( KPluginElement ) == 0 ) + { + // 1. Check if has activity attribute. + ChspsDomList& attrList = child->AttributeList(); + ChspsDomAttribute* pluginActivityAttr = + static_cast( attrList.FindByName( KPluginAttrActive ) ); + if( pluginActivityAttr ) + { + // 2. Check whether node is active. + if( pluginActivityAttr->Value().CompareF( KPluginActiveStateActive ) == 0 ) + { + // 3. Active node found. assign and break. + activeNode = child; + break; + } + } + } + } + + return activeNode; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetPluginId +// ----------------------------------------------------------------------------- +// +TInt hspsServerUtil::GetPluginId( ChspsDomNode* aNode ) + { + // Sanity check. + if( !aNode ) + { + return KErrArgument; + } + + // Return value. + TInt pluginId = KErrNotFound; + + // Find out plugin id. + ChspsDomList& attrList = aNode->AttributeList(); + ChspsDomAttribute* pluginIdAttr = + static_cast ( attrList.FindByName( KPluginAttrId ) ); + if( pluginIdAttr ) + { + // Found. + const TDesC8& pluginIdValue = pluginIdAttr->Value(); + pluginId = DecString2Int( pluginIdValue ); + } + + return pluginId; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetPluginUid +// ----------------------------------------------------------------------------- +// +TUid hspsServerUtil::GetPluginUid( ChspsDomNode* aNode ) + { + // Sanity check. + if( !aNode ) + { + return KNullUid; + } + + // Read Uid from attribute list. + ChspsDomList& attrList = aNode->AttributeList(); + ChspsDomAttribute* pluginUidAttr = + static_cast ( attrList.FindByName( KPluginAttrUid ) ); + + // Sanity check. + if( !pluginUidAttr ) + { + return KNullUid; + } + + // Convert uids from string to numeric format + const TDesC8& pluginUidValue = pluginUidAttr->Value(); + const TUid pluginUid = hspsServerUtil::ConvertDescIntoUid(pluginUidValue); + + // Return result. + return pluginUid; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetPluginIdsByUidL +// ----------------------------------------------------------------------------- +// +void hspsServerUtil::GetPluginIdsByUidL( + const ChspsODT& aAppODT, + const TUid aPluginUid, + RArray& aPluginIds ) + { + ChspsDomDocument& dom = aAppODT.DomDocument(); + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( *dom.RootNode() ); + CleanupStack::PushL( iter ); + + // Find a plugin node with the provided id attribute + ChspsDomNode* node = iter->First(); + ChspsDomNode* prevNode = NULL; + TBool jobDone = EFalse; + while( node && !jobDone && prevNode != node ) + { + const TDesC8& name = node->Name(); + + // Plugin element was found + if ( name == KPluginElement ) + { + ChspsDomList& attrList = node->AttributeList(); + ChspsDomAttribute* attr = static_cast( attrList.FindByName(KPluginAttrUid) ); + if ( !attr ) + { + // Mandatory information is missing for some reason (should be set at installation handler)! + // Exit with NULL + jobDone = ETrue; + } + else + { + // Convert from (hex?) string into TUid presentation + const TUid uid = ConvertDescIntoUid( attr->Value() ); + if ( aPluginUid == uid ) + { + const TDesC8& strPluginId = node->AttributeValue(KPluginAttrId); + TInt pluginId = DecString2Int( strPluginId ); + aPluginIds.AppendL( pluginId ); + } + } + } + + prevNode = node; + node = iter->NextL(); + } + + CleanupStack::PopAndDestroy( iter ); + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetParentNode +// ----------------------------------------------------------------------------- +// +ChspsDomNode* hspsServerUtil::GetParentNode( + const ChspsDomNode& aNode, + const TDesC8& aNodeName, + const TDesC8& aAttrName, + const TDesC8& aAttrValue ) + { + ChspsDomNode* parent = aNode.Parent(); + TBool found( EFalse ); + while ( parent && !found ) + { + if ( parent->Name().CompareF( aNodeName ) == 0 ) + { + ChspsDomList& attrList = parent->AttributeList(); + ChspsDomAttribute* attr = static_cast( attrList.FindByName( aAttrName ) ); + if ( attr && attr->Value().CompareF( aAttrValue ) == 0 ) + { + found = ETrue; + } + } + if ( !found ) + { + // Get next level parent node + parent = parent->Parent(); + } + } + + return parent; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::IsLogoFile +// ----------------------------------------------------------------------------- +// +TBool hspsServerUtil::IsLogoFile( + const TDesC& aFileDeclaration, + TFileName& aFilename ) + { + _LIT(KDeclarationSkin, "SKIN("); // prefixes for filelogo/filepreview values + _LIT(KDeclarationMif, "MIF("); + _LIT(KDeclarationUid, "UID("); + + aFilename = KNullDesC(); + if ( aFileDeclaration.FindF( KDeclarationSkin ) >= 0 + || aFileDeclaration.FindF( KDeclarationMif ) >= 0 + || aFileDeclaration.FindF( KDeclarationUid ) >= 0 ) + { + // pick filename from the mif declaration if it's available (e.g. "skin( ):mif( )") + TInt mifOffset = aFileDeclaration.FindF( KDeclarationMif ); + if ( mifOffset >= 0 ) + { + aFilename = aFileDeclaration.Mid( mifOffset + KDeclarationMif().Length() ); + aFilename.TrimAll(); + + // drop everything before the first bitmap index + TInt endPos = aFilename.Locate( ' ' ); + if ( endPos > 1 ) + { + aFilename = aFilename.Left( endPos ); + } + } + } + else + { + // store possible icon path + aFilename.Copy( aFileDeclaration ); + } + + return ( aFilename.Length() > 0 ); + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetResourcesForLanguageL +// ----------------------------------------------------------------------------- +void hspsServerUtil::GetResourcesForLanguageL( + ChspsODT& aODT, + const TInt aConfUid, + const TLanguage aActiveLanguage, + RPointerArray& aWidgetResources ) + { + const TInt resourceCount = aODT.ResourceCount(); + + // pick resources with the active language + for( TInt resourceIndex = 0; resourceIndex < resourceCount; resourceIndex++ ) + { + ChspsResource& resource = aODT.ResourceL( resourceIndex ); + if ( resource.ConfigurationUid() == aConfUid && + resource.Language() == aActiveLanguage && + resource.FileName().FindF( KSourcesFolder ) > 0 ) + { + aWidgetResources.Append( &resource ); + } + } + + // Resources for language none or language test. + for( TInt resourceIndex = 0; resourceIndex < resourceCount; resourceIndex++ ) + { + ChspsResource& resource = aODT.ResourceL( resourceIndex ); + if ( resource.ConfigurationUid() == aConfUid && + resource.FileName().FindF( KSourcesFolder ) > 0 ) + { + if( resource.Language() == ELangTest || resource.Language() == ELangNone ) + { + // Checking also that not going to overwrite existing localized resource. + TBool localizedVersionAvailable = EFalse; + for( TInt checkIndex = 0; checkIndex < aWidgetResources.Count(); checkIndex++ ) + { + ChspsResource* checkResource = aWidgetResources[ checkIndex ]; + if( !checkResource ) + { + continue; + } + + TParsePtrC resource1FullPath( resource.FileName() ); + TParsePtrC resource2FullPath( checkResource->FileName() ); + + if( resource1FullPath.NameAndExt().CompareF( resource2FullPath.NameAndExt() ) == 0 ) + { + localizedVersionAvailable = ETrue; + break; + } + } + + if( !localizedVersionAvailable ) + { + aWidgetResources.Append( &resource ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::EnoughDiskSpaceAvailable +// ----------------------------------------------------------------------------- +TInt hspsServerUtil::EnoughDiskSpaceAvailableL( + ChspsODT& aODT, + const TLanguage aActiveLanguage, + RFs& aFs, + const TDriveNumber aDriveNumber, + const TInt aAdditionalDiskSpace ) + { + __UHEAP_MARK; + + TInt err = KErrNone; + + // Retrieve data for needed resource files. + RPointerArray widgetResources; // Objects are not owned. + CleanupClosePushL( widgetResources ); + + GetResourcesForLanguageL( + aODT, + aODT.ThemeUid(), + aActiveLanguage, + widgetResources ); + + TInt requiredDiskSpace = aAdditionalDiskSpace; + + // Calculate disk space required for resources. + for( TInt i = 0; i < widgetResources.Count() && !err; i++ ) + { + ChspsResource* resource = widgetResources[i]; + if( !resource ) + { + continue; + } + + TEntry entryData; + err = aFs.Entry( resource->FileName(), entryData ); + requiredDiskSpace += entryData.iSize; + } + + widgetResources.Reset(); + CleanupStack::PopAndDestroy( 1, &widgetResources ); + + // Check if calculated space is available. + if( !err && + SysUtil::DiskSpaceBelowCriticalLevelL( &aFs, + requiredDiskSpace, + aDriveNumber ) ) + { + err = KErrDiskFull; + } + + __UHEAP_MARKEND; + + return err; + } +// ----------------------------------------------------------------------------- +// Finds a node from a dom document. +// Looks for the next node tag. +// ----------------------------------------------------------------------------- +ChspsDomNode* hspsServerUtil::FindNodeByTagL( + const TDesC8& aNodeTag, + ChspsDomNode& aDomNode ) + { + ChspsDomDepthIterator* iter = ChspsDomDepthIterator::NewL( aDomNode ); + CleanupStack::PushL( iter ); + ChspsDomNode* targetNode( NULL ); + ChspsDomNode* node = iter->First(); + TBool found = EFalse; + while( !found && node ) + { + const TDesC8& name = node->Name(); + if ( name.Compare( aNodeTag ) == 0 ) + { + found = ETrue; + targetNode = node; + } + node = iter->NextL(); + } + CleanupStack::PopAndDestroy( iter ); + return targetNode; + } + + +// ----------------------------------------------------------------------------- + // hspsServerUtil::FindFile + // Eclipsing support for customization + // ----------------------------------------------------------------------------- + // + TInt hspsServerUtil::FindFile( + RFs& aFs, + const TDesC& aPath, + const TDesC& aFilename, + const TBool aFindFromUdaEmmcDrives, + TFileName& aDrivePathName ) + { + TInt err = KErrNotFound; + + TParsePtrC parser( aPath ); + const TPath path = parser.Path(); + + TFileName filename( aFilename ); + if( filename.Length() == 0 ) + { + filename.Copy( parser.NameAndExt() ); + } + + if( filename.Length() > 0 && path.Length() > 0 ) + { + // Find the input file, search from the user area (UDA) first, + // exclude external/remote drives from the search - otherwise end-users + // could introduce fixed configurations (e.g. operator locks wouldn't work) + TFindFile fileFinder( aFs ); + fileFinder.SetFindMask( + KDriveAttExclude|KDriveAttRemovable|KDriveAttRemote|KDriveAttSubsted ); + if( aFindFromUdaEmmcDrives ) + { + TInt drive = hspsServerUtil::GetEmmcDrivePath( aFs ); + if ( drive != KErrNotFound ) + { + aFs.SetSessionToPrivate( drive ); + } + } + else + { + aFs.SetSessionToPrivate( EDriveZ ); + } + err = fileFinder.FindByDir( filename, path ); + aFs.SetSessionToPrivate( EDriveC ); + if( !err ) + { + // Return the path with a drive reference + aDrivePathName = fileFinder.File(); + TParsePtrC drvParser( aDrivePathName ); + if( !drvParser.DrivePresent() ) + { + err = KErrNotFound; + } + } + } + + return err; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::ResolveLogoPathL +// ----------------------------------------------------------------------------- +void hspsServerUtil::PopulateLogoPathsL( + const TDesC& aLogoDeclaration, + const TUint aAppUid, + RBuf& aTargetPath, + RBuf& aSourcePath, + RBuf& aUpdatedDeclaration) + { + // Process widget types only + if ( aLogoDeclaration.Length() && aAppUid > 0 ) + { + // Get possible file name from the optional logo declaration + // and if found, populate the paths and update the declaration + TFileName filename; + if( IsLogoFile( aLogoDeclaration, filename ) ) + { + // Get client's private directory + _LIT( KClientPrivatePath, "c:\\private\\%X\\"); + TPath clientPath; + clientPath.Format( KClientPrivatePath, aAppUid ); + + // Updated logo declaration + TInt offset = aLogoDeclaration.FindF( filename ); + __ASSERT_DEBUG( offset != KErrNotFound, User::Leave( KErrCorrupt ) ); + if( aLogoDeclaration.Length() + aLogoDeclaration.Mid( offset ).Length() < KMaxFileName ) + { + aUpdatedDeclaration.Copy( aLogoDeclaration ); + aUpdatedDeclaration.Insert( offset, clientPath ); + + // Set path and name of the target file + if( clientPath.Length() + filename.Length() < KMaxFileName ) + { + aTargetPath.Copy( clientPath ); + aTargetPath.Append( filename ); + + // Set name of the source file + _LIT( KServerPrivateFolder, "c:\\private\\200159c0\\themes\\" ); + if( KServerPrivateFolder().Length() + filename.Length() < KMaxFileName ) + { + aSourcePath.Copy( KServerPrivateFolder ); + aSourcePath.Append( filename ); + } + } + } + + } + } + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::FindResourcesL +// ----------------------------------------------------------------------------- +void hspsServerUtil::FindResourcesL( + RFs& aFs, + const RArray& aDriveArray, + const TDesC& aPath, + RPointerArray& aFileArray, + CArrayFixFlat* aDeviceLanguages, + TBool aRecursive ) + { + // Scan internal drives only + TFindFile fileFinder( aFs ); + fileFinder.SetFindMask( KDriveAttExclude|KDriveAttRemovable|KDriveAttRemote|KDriveAttSubsted ); + + TParsePtrC parser( aPath ); + + // Loop the provided disk drives + for( TInt driveIndex=0; driveIndex < aDriveArray.Count(); driveIndex++ ) + { + TChar driveChar; + User::LeaveIfError( RFs::DriveToChar( aDriveArray[driveIndex], driveChar ) ); + TBuf16<2> driveBuf(2); + driveBuf[0] = TUint( driveChar ); + driveBuf[1] = TUint( TChar(':') ); + + TPath path; + path.Copy( driveBuf ); + path.Append( parser.Path() ); + + // Find files from the drive and path + CDir* dirList( NULL ); + fileFinder.FindWildByPath( path, NULL, dirList ); + if ( dirList ) + { + CleanupStack::PushL( dirList ); + + const TInt count = dirList->Count(); + for( TInt entryIndex = 0; entryIndex < count; entryIndex++ ) + { + const TEntry& entry = (*dirList)[ entryIndex ]; + + TFileName file( path ); + file.Append( entry.iName ); + + if( entry.IsDir() ) + { + if( aDeviceLanguages ) + { + TInt dirLanguage = 0; + TLex lex( entry.iName ); + TBool skipDir = ETrue; + if( lex.Val( dirLanguage ) == KErrNone && dirLanguage >= ELangTest ) + { + for( TInt i=0; i < aDeviceLanguages->Count(); i++ ) + { + TInt supportedLanguage = aDeviceLanguages->At( i ); + if( supportedLanguage == dirLanguage ) + { + skipDir = EFalse; + break; + } + } + } + if( skipDir ) + { + continue; + } + } + + file.Append( KDoubleBackSlash ); + } + + if( entry.IsDir() && aRecursive ) + { + // Find files from the directory and drive + RArray driveArray; + CleanupClosePushL( driveArray ); + driveArray.Append( aDriveArray[driveIndex] ); + FindResourcesL( aFs, driveArray, file, aFileArray, NULL ); + CleanupStack::PopAndDestroy( &driveArray ); + } + else + { + HBufC* nameBuf = file.AllocLC(); + aFileArray.AppendL( nameBuf ); + CleanupStack::Pop( nameBuf ); + } + } + + CleanupStack::PopAndDestroy( dirList ); + dirList = 0; + } // dirlist + + } // driveIndex + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetInstalledLanguagesL +// ----------------------------------------------------------------------------- +void hspsServerUtil::GetInstalledLanguagesL( + CArrayFixFlat*& aLanguages ) + { + User::LeaveIfError( SysLangUtil::GetInstalledLanguages( aLanguages ) ); + CleanupStack::PushL( aLanguages ); + + const TInt testLang = (TInt)ELangTest; + + TBool isIncluded = EFalse; + for( TInt i = 0; i < aLanguages->Count(); i++ ) + { + if( aLanguages->At( i ) == testLang ) + { + isIncluded = ETrue; + break; + } + } + + if( !isIncluded ) + { + aLanguages->InsertL( 0, testLang ); + } + + CleanupStack::Pop( aLanguages ); + } + + +// ----------------------------------------------------------------------------- +// hspsServerUtil::GetEmmcDrivePathL +// ----------------------------------------------------------------------------- +// +TInt hspsServerUtil::GetEmmcDrivePath( RFs& aFs ) + { + TInt drive = KErrNotFound; + if ( DriveInfo::GetDefaultDrive( + DriveInfo::EDefaultMassStorage, drive ) == KErrNone ) + { + TUint status; + if ( DriveInfo::GetDriveStatus( aFs, drive, status ) == KErrNone ) + { + if ( status & DriveInfo::EDriveInternal ) + { + return drive; + } + } + } + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// Removes plugin resources from the provided ODT +// ----------------------------------------------------------------------------- +// +TInt hspsServerUtil::RemovePluginResourcesL( + ChspsODT& aAppODT, + const TInt aPluginUid ) + { + // Loop resources of the application configuration + for(TInt aresIndex = 0; aresIndex < aAppODT.ResourceCount(); aresIndex++ ) + { + ChspsResource& ares = aAppODT.ResourceL( aresIndex ); + + // If the plugin resource was found at resource list of the application configuration + if ( ares.ConfigurationUid() == aPluginUid ) + { + // Deletes resource from the application configuration + aAppODT.DeleteResourceL( aresIndex ); + aresIndex--; + } + + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// hspsServerUtil::hspsServerUtil +// ----------------------------------------------------------------------------- +// +hspsServerUtil::hspsServerUtil() + { + // Empty. Should never be called. + } + +// end of file