terminalsecurity/SCP/SCPClient/src/SCPParamObject.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 04 Oct 2010 01:40:31 +0300
changeset 72 8ee66fcd0a7c
parent 24 bf47f3b79154
permissions -rw-r--r--
Revision: 201037 Kit: 201039

/*
* Copyright (c) 2000 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: Implementation of terminalsecurity components
*
*/

#include <e32debug.h>
#include <f32file.h>

#include "SCPParamObject.h"
#include "SCPClient.h"

#include "SCPDebug.h"
/*#ifdef _DEBUG
#define __SCP_DEBUG
#endif // _DEBUG

// Define this so the precompiler in CW 3.1 won't complain about token pasting,
// the warnings are not valid
#pragma warn_illtokenpasting off

#ifdef __SCP_DEBUG
#define Dprint(a) RDebug::Print##a
#else
#define Dprint(a)
#endif // _DEBUG*/

// ================= MEMBER FUNCTIONS =======================
//
// ----------------------------------------------------------
// CSCPParamObject::CSCPParamObject()
// C++ constructor
//
// Status: Approved
// ----------------------------------------------------------
CSCPParamObject::CSCPParamObject()
	{
	// No implementation required
	}
	

// ----------------------------------------------------------
// CSCPParamObject::NewL()
// Static constructor
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C CSCPParamObject* CSCPParamObject::NewL()
	{	
	CSCPParamObject* self = CSCPParamObject::NewLC();
	CleanupStack::Pop( self );
		
	return self;	
	}
	

// ----------------------------------------------------------
// CSCPParamObject::NewLC()
// Static constructor, leaves object pointer to the cleanup stack.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C CSCPParamObject* CSCPParamObject::NewLC()
	{
	Dprint( (_L("--> CSCPParamObject::NewLC()")) );

	CSCPParamObject* self = new (ELeave) CSCPParamObject();

    CleanupStack::PushL( self );
    self->ConstructL();	
    
    Dprint( (_L("<-- CSCPParamObject::NewLC()") ));
    return self;	
    }

// ----------------------------------------------------------
// CSCPParamObject::ConstructL()
// Symbian 2nd phase constructor
//
// Status: Approved
// ----------------------------------------------------------
void CSCPParamObject::ConstructL()
    {            
	iParamIDs.Reset();
	iParamValues.Reset();
    }


// ----------------------------------------------------------
// CSCPParamObject::GetParamLength()
// Return the length of the given parameter.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::GetParamLength( TInt aParamID )
    {    
    TInt ret = iParamIDs.Find( aParamID );
    if ( ( ret != KErrNotFound ) && ( ret >= 0 ) )
        {
        ret = ( iParamValues[ret]->Des() ).Length();
        } 
        
    return ret;   
    }


// ----------------------------------------------------------
// CSCPParamObject::Get()
// Retrieve the given value from the arrays
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Get( TInt aParamID, TDes& aValue )
    {
    TInt ret = KErrNone;
    
    // Find the object
    TInt index = iParamIDs.Find( aParamID );
    if ( ( index != KErrNotFound ) && ( index >= 0 ) )
        {
        // Retrieve the value
        if ( aValue.MaxLength() < ( iParamValues[index]->Des() ).Length() )
            {
            ret = KErrOverflow;
            }
        else
            {
            aValue.Copy( iParamValues[index]->Des() );
            }                    
        }
    else
        {
        ret = index;
        }
        
    return ret;
    }
    
// ----------------------------------------------------------
// CSCPParamObject::Get()
// Retrieve the given value from the arrays, trying to 
// convert it to an integer.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Get( TInt aParamID, TInt& aValue )
    {
    TBuf<KSCPMaxIntLength> convBuf;
    convBuf.Zero();
    
    // An integer should fit into 16chars, if not, it's an error
    TInt ret = Get( aParamID, convBuf );
    
    if ( ret == KErrNone )
        {
        TLex lex( convBuf );
        ret = lex.Val( aValue );
        }        
    
    return ret;
    }    
    
    
    
// ----------------------------------------------------------
// CSCPParamObject::Set()
// Insert or replace the parameter value of aParamID with 
// aValue.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Set( TInt aParamID, TDes& aValue )
    {
    TBool isNewParam = ETrue;
    TInt ret = KErrNone;
    
    // Create a buffer for the value
    HBufC* newValue = NULL;
    TRAPD( err, newValue = HBufC::NewL( aValue.Length() ) );        
    
    if ( err != KErrNone )
        {
        return err;
        }    
    
    TPtr newValPtr = newValue->Des(); 
    newValPtr.Copy( aValue );

    if ( err != KErrNone )
        {
        Dprint( (_L("CSCPParamObject::Set(): ERROR: \
            HBufC Allocation failed") ));
        ret = err;
        }
                
    // Check if we've got this ID already         
    for ( TInt i = 0; i < iParamIDs.Count(); i++ )
        {
        if ( iParamIDs[i] == aParamID )
            {            
            // Remove the old entry
            HBufC* tmpValue = iParamValues[ i ];            
            iParamValues.Remove( i );
            delete tmpValue;
                
            iParamValues.InsertL( newValue, i );
            isNewParam = EFalse;
            }
        }
        
    if ( isNewParam )
        {
        // Create a new value
        TInt err = KErrNone;
        TRAP(err, iParamIDs.AppendL( aParamID ));
        if(err != KErrNone)
            {
            delete newValue;
            ret = err;
            }
        else 
            {
            TRAP(err, iParamValues.AppendL( newValue ));
            if(err != KErrNone)
                {
                delete newValue;
                //Rollback append.
                iParamIDs.Remove(iParamIDs.Count()-1);
                ret = err;
                }
            }
        }

    return ret;
    }    
    
// ----------------------------------------------------------
// CSCPParamObject::Set()
// Convert the int into a descriptor and propagate to Set.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Set( TInt aParamID, TInt aValue )
    {
    // Convert the value
    TBuf<KSCPMaxIntLength> convBuf;
    convBuf.Zero();    
    convBuf.AppendNum( aValue );
    
    return Set( aParamID, convBuf );
    }  
    
    
// ----------------------------------------------------------
// CSCPParamObject::Unset()
// Remove the given ID along with its value from the arrays.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Unset( TInt aParamID )
    {
    TInt ret = KErrNotFound;
    
    // Check if we've got this ID
    for ( TInt i = 0; i < iParamIDs.Count(); i++ )
        {
        if ( iParamIDs[i] == aParamID )
            {            
            // Remove the entry
            HBufC* tmpValue = iParamValues[ i ];            
            iParamValues.Remove( i );
            delete tmpValue;                        
                       
            iParamIDs.Remove( i );
            ret = KErrNone;
            }
        }
        
    return ret;
    }
        
      
// ----------------------------------------------------------
// CSCPParamObject::Reset()
// Reset the ID and value arrays.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Reset()
    {
    iParamIDs.Reset();
	iParamValues.ResetAndDestroy();
	iFailedPolicyIDs.Reset();	
	return KErrNone;
    }
   
    
// ----------------------------------------------------------
// CSCPParamObject::Parse()
// Parse a previously compiled buffer, and add the parameters
// found to the arrays.
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::Parse( TDes8& aBuffer )
    {        
    TInt ret = KErrNone;
    
    TInt intSize = sizeof( TInt );
    
#ifdef UNICODE
    TInt charSize = 2;
#else
    TInt charSize = 1;
#endif // __UNICODE    
        
    if ( aBuffer.Length() == 0 )
        {
        // OK, nothing to parse
        return KErrNone;
        }
    
    if ( aBuffer.Length() < intSize )
        {
        return KErrArgument;
        }    
        
    // The number of parameters is the first TInt in the buffer
    TInt numParams = *(reinterpret_cast<TInt*>( &aBuffer[0] ) );
        
    TInt curOffset = ( 1 + numParams * 2 ) * intSize; 
    
    if ( aBuffer.Length() < curOffset )
        {
        // The buffer must not be shorter than the header
        return KErrArgument;
        }    
        
    for ( TInt i = 0; i < numParams; i++ )
        { 
        // 2 ints per param, offset 1 = ID, offset 2 = length       
        TInt curID = *(reinterpret_cast<TInt*>( &aBuffer[ (i * 2 + 1) * intSize ]) );
        TInt curLen = *(reinterpret_cast<TInt*>( &aBuffer[ (i * 2 + 2) * intSize ]) );
        
#ifdef UNICODE
        TPtr curDes( reinterpret_cast<TUint16*>(&aBuffer[ curOffset ]), curLen/charSize );
#else
        TPtr curDes( &aBuffer[ curOffset ], curLen/charSize );
#endif // __UNICODE                                 
        curDes.SetLength( curDes.MaxLength() );
        
        curOffset += curLen;
        
        if ( aBuffer.Length() < curOffset )
            {        
            ret =  KErrArgument;
            break;
            } 
        
        ret = Set( curID, curDes );
        
        if ( ret != KErrNone )
            {
            break;
            }
        }
    
    return ret;
    }



// ----------------------------------------------------------
// CSCPParamObject::GetBuffer()
// Form a buffer containing the stored parameters
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C TInt CSCPParamObject::GetBuffer( HBufC8*& aBuffer )
    { 
    // Calculate the space required
    // The format is: 
    // <numparams> + <numparams>*(<paramid><paramlen>) + 
    // <numparams>*<paramvalue>
    TInt intSize = sizeof( TInt );
    
#ifdef UNICODE
    TInt charSize = 2;
#else
    TInt charSize = 1;
#endif // __UNICODE    

    TInt headerSpace = ( 1 + iParamIDs.Count() * 2) * intSize;
    TInt dataSpace = 0;
    
    TInt i;
    for ( i = 0; i < iParamValues.Count(); i++ )
        {
        // Add the size of each value
        dataSpace += ( iParamValues[i]->Des() ).Length() * charSize;
        }
    TInt spaceNeeded = headerSpace + dataSpace; 
    
    HBufC8* buffer = NULL;
    
    TRAPD( ret, buffer = HBufC8::NewL( spaceNeeded ) );        
    if ( ret != KErrNone )
        {
        Dprint( (_L("--> CSCPParamObject::GetBuffer(): Allocation FAILED") ));
        }
    else
        {                          
        TPtr8 bufPtr = buffer->Des();
        TUint8* theBuffer = const_cast<TUint8*>( bufPtr.Ptr() );
        
        // Header
        *(reinterpret_cast<TInt*>( &theBuffer[0] )) = iParamIDs.Count();    
    
        for ( i = 0; i < iParamIDs.Count(); i++ )
            {
            // 2 ints per param, offset 1 = ID, offset 2 = length
            *(reinterpret_cast<TInt*>( &theBuffer[ (i * 2 + 1) * intSize ] ))
                = iParamIDs[i]; // ID
            *(reinterpret_cast<TInt*>( &theBuffer[ (i * 2 + 2) * intSize ] ))
                = ( iParamValues[i]->Des() ).Length() * charSize; // length                    
            }
    
        TInt curOffset = headerSpace;    
    
        // Copy the values after the header
        for ( i = 0; i < iParamIDs.Count(); i++ )
            {
            TAny* target = &theBuffer[ curOffset ];
            TPtr sourceDes = iParamValues[i]->Des();
            const TAny* source = static_cast<const TAny*>( sourceDes.Ptr() );
        
            memcpy( target, source, sourceDes.Length() * charSize );
            
            curOffset += sourceDes.Length() * charSize;
            }
        
        bufPtr.SetLength( curOffset );
        aBuffer = buffer;
        }
    
    return ret;
    }
                                         

      
// ----------------------------------------------------------
// CSCPParamObject::WriteToFile()
// Write the output from GetBuffer to a file
//
// Status: Approved
// ----------------------------------------------------------
//
EXPORT_C void CSCPParamObject::WriteToFileL( TDesC& aFilename, RFs* aRfs /*= NULL*/ )
    {
    HBufC8* paramBuffer;
    
    TInt ret = GetBuffer( paramBuffer );
    if ( ret != KErrNone )
        {
        Dprint( (_L("CSCPPluginEventHandler::WritePluginConfigurationL(): FAILED \
            to get the configuration buffer: %d"), ret ));
        User::Leave( ret );
        }
    CleanupStack::PushL( paramBuffer );
            
    RFs* fsSessionPtr;
    RFs fsSession;
    
    if ( aRfs != NULL )
        {
        fsSessionPtr = aRfs;
        }
    else
        {
        User::LeaveIfError( fsSession.Connect() );
        CleanupClosePushL( fsSession );
        fsSessionPtr = &fsSession;
        }
        
    TPtr8 paramDes = paramBuffer->Des();        
       
    RFile configFile;
       
    // Make sure that the target directory exists
    ret = fsSessionPtr->MkDirAll( aFilename );
    if ( ( ret != KErrNone ) && ( ret != KErrAlreadyExists ) )
        {
        Dprint( (_L("CSCPPluginEventHandler::WritePluginConfigurationL(): FAILED \
            to create the target directory: %d"), ret ));
        User::Leave( ret );
        }    
          
    // Create or replace the existing file
    ret = configFile.Replace( *fsSessionPtr, 
            aFilename, 
            EFileShareAny | EFileWrite
        );
        
    if ( ret != KErrNone )
        {
        Dprint( (_L("CSCPPluginEventHandler::WritePluginConfigurationL():\
            FAILED to replace configuration file: %d"), ret ));                   
        User::Leave( ret );
        }
            
    CleanupClosePushL( configFile );
        
    // Write the data
    ret = configFile.Write( paramDes );    
                
    if ( aRfs != NULL )
        {
        CleanupStack::PopAndDestroy(); // configFile
        }
    else
        {
        CleanupStack::PopAndDestroy( 2 ); // configFile - fsSession  
        }              
    
    CleanupStack::PopAndDestroy( paramBuffer );    
    
    if ( ret != KErrNone )
        {
        Dprint( (_L("CSCPPluginEventHandler::WritePluginConfigurationL():\
            FAILED to write configuration file: %d"), ret ));
        User::Leave( ret );
        }                                                        
    }
        
       
// ----------------------------------------------------------
// CSCPParamObject::ReadFromFile()
// Fetch the configuration from disk
//
// Status: Approved
// ---------------------------------------------------------- 
//
EXPORT_C void CSCPParamObject::ReadFromFileL( TDesC& aFilename, RFs* aRfs /*= NULL*/ )
    {    
    TInt ret;
      
    RFs* fsSessionPtr;
    RFs fsSession;
    
    if ( aRfs != NULL )
        {
        fsSessionPtr = aRfs;
        }
    else
        {
        User::LeaveIfError( fsSession.Connect() );
        CleanupClosePushL( fsSession );
        fsSessionPtr = &fsSession;
        }           
    
    RFile configFile;        
    
    ret = configFile.Open( *fsSessionPtr, 
                aFilename, 
                EFileShareAny | EFileRead 
            );
    
    if ( ret != KErrNone )
        {                                    
        Dprint( (_L("CSCPParamObject::ReadFromFileL(): Failed \
            to open config file: %d"), ret ));        
        User::Leave( ret );                    
        }
            
    CleanupClosePushL( configFile );
    
    TInt size;
    ret = configFile.Size( size );
    if ( ret != KErrNone )
        {
        Dprint( (_L("CSCPParamObject::ReadFromFile(): Failed \
            to get config file size: %d"), ret ));
        User::Leave( ret );
        }        
    
    HBufC8* paramBuf = HBufC8::NewL( size );
    CleanupStack::PushL( paramBuf );
    
    TPtr8 paramDes = paramBuf->Des();
    ret = configFile.Read( paramDes );
    if ( ret != KErrNone )
        {
        Dprint( (_L("CSCPParamObject::ReadFromFile(): Failed \
            read configuration data: %d"), ret ));
        User::Leave( ret );
        }        
    
    // Parse the parameters from the buffer
    ret = Parse( paramDes );            
    
    CleanupStack::PopAndDestroy( paramBuf );
    
    if ( aRfs != NULL )
        {
        CleanupStack::PopAndDestroy(); // configFile
        }
    else
        {
        CleanupStack::PopAndDestroy( 2 ); // configFile - fsSession  
        }          
    
	if ( ret != KErrNone )
        {
        Dprint( (_L("CSCPParamObject::ReadFromFile(): Failed \
            to parse buffer for parameters: %d"), ret ));
        User::Leave( ret );
        }    
    }

EXPORT_C TInt CSCPParamObject::AddtoFailedPolices( TInt aFailedpolicyID )
    {
    return iFailedPolicyIDs.Append(aFailedpolicyID);
    }
	
EXPORT_C const RArray<TInt>& CSCPParamObject::GetFailedPolices( )
    {
    return iFailedPolicyIDs;
    }
// ----------------------------------------------------------
// CSCPParamObject::~CSCPParamObject()
// Destructor
//
// Status: Approved
// ----------------------------------------------------------
EXPORT_C CSCPParamObject::~CSCPParamObject()
	{
	Dprint( (_L("--> CSCPParamObject::~CSCPParamObject()") ));
	
	Reset();
	
	Dprint( (_L("<-- CSCPParamObject::~CSCPParamObject()") ));
	}

// End of file