commonservices/PlatformEnv/sysversioninfo/src/sysversioninfo.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commonservices/PlatformEnv/sysversioninfo/src/sysversioninfo.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,712 @@
+/*
+* Copyright (c) 2007 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:  Provides version information
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <f32file.h>
+#include <extendedversioninfoplugin.h>
+#include <extendedversioninfoplugin.hrh>
+#include <data_caging_paths_strings.hrh>
+#include "sysversioninfo.h"
+#include "sysversioninfodebug.h"
+
+// MACROS
+// needed because _LIT macro does not expand parameter, which is also macro
+#define _SYSVERSION_CREATE_LIT(a,b) _LIT(a,b)
+
+// CONSTANTS
+const TInt KMaxTextLineLength = 256;
+_LIT( KNewLinePattern, "\\n" );
+_LIT( KNewline, "\n" );
+
+// Model version string
+_LIT( KModelVersionFileName, "Z:\\resource\\versions\\model.txt" );
+
+// Firmware version
+_LIT( KFWIDVersionFileName, "Z:\\resource\\versions\\fwid*.txt" );
+_LIT( KFWIDVersionTag, "version=" );
+_LIT( KFWIDVersionSeparator, " " );
+
+// Customer variant version
+_LIT( KOPIDVersionFileName, "Z:\\resource\\versions\\customersw.txt" );
+
+// Product version
+_LIT( KProductVersionFileName, "Z:\\resource\\versions\\product.txt" );
+_LIT( KManufacturerTag, "Manufacturer=" );
+_LIT( KModelTag, "Model=" );
+_LIT( KProductTag, "Product=" );
+_LIT( KRevisionTag, "Revision=" );
+
+// Platform version
+_LIT( KPlatformVersionFileName, "Z:\\resource\\versions\\platform.txt" );
+_LIT( KSymbianOSMajorVersionTag, "SymbianOSMajorVersion=" );
+_LIT( KSymbianOSMinorVersionTag, "SymbianOSMinorVersion=" );
+
+
+// ======== LOCAL FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// AppendTillMax
+// ---------------------------------------------------------------------------
+//
+static TInt AppendTillMax( TDes& aDst, const TDesC& aSrc )
+    {
+    FUNC_LOG
+
+    TInt ret( KErrNone );
+    TInt maxLen( aDst.MaxLength() - aDst.Length() );
+    if ( aSrc.Length() <= maxLen )
+        {
+        aDst.Append( aSrc );
+        }
+    else
+        {
+        aDst.Append( aSrc.Left( maxLen ) );
+        ret = KErrTooBig;
+        }
+    LOG_IF_ERROR1( ret, "AppendTillMax-ret=%d", ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// RemoveNewLines
+// ---------------------------------------------------------------------------
+//
+static void RemoveNewLines( TDes& aValue )
+    {
+    FUNC_LOG
+
+    // Replace new-line patterns with real ones
+    TInt lnPatLen( KNewLinePattern().Length() );
+    TInt lnLen( KNewline().Length() );
+    TInt lnDiff( lnPatLen - lnLen );
+    TInt len( aValue.Length() );
+    TPtr ptr( aValue.MidTPtr( 0 ) );
+    TInt pos( ptr.Find( KNewLinePattern ) );
+    while ( pos != KErrNotFound )
+        {
+        ptr.Replace( pos, lnPatLen, KNewline );
+        len -= lnDiff;
+        ptr.Set( ptr.MidTPtr( pos ) );
+        pos = ptr.Find( KNewLinePattern );
+        }
+    aValue.SetLength( len );
+    }
+
+// ---------------------------------------------------------------------------
+// GetTextFromFile
+// ---------------------------------------------------------------------------
+//
+static TInt GetTextFromFile(
+        RFile& aFile,
+        TDes& aValue,
+        const TDesC& aTag = KNullDesC )
+    {
+    FUNC_LOG
+
+    // Create line buffer and fetch text from file
+    HBufC* buffer = HBufC::New( KMaxTextLineLength );
+    if ( !buffer )
+        {
+        ERROR_LOG1( "GetTextFromFile-ret=%d", KErrNoMemory )
+        return KErrNoMemory;
+        }
+    TPtr ptr( buffer->Des() );
+    TFileText tf;
+    tf.Set( aFile );
+    TInt tagLen( aTag.Length() );
+    TInt ret( KErrNone );
+    for( ;; )
+        {
+        // Fetch next text line
+        ptr.Zero();
+        ret = tf.Read( ptr );
+        if ( ret != KErrNone && ret != KErrTooBig )
+            {
+            break; // Unexpected error did happen
+            }
+        if ( !tagLen || !ptr.Left( tagLen ).CompareF( aTag ) )
+            {
+            TInt ret2( AppendTillMax( aValue, ptr.Mid( tagLen ) ) );
+            if ( ret == KErrNone && ret2 != KErrNone )
+                {
+                ret = ret2;
+                }
+            break; // Text read was successful
+            }
+        }
+    if ( ret == KErrEof )
+        {
+        ret = KErrNone; // Suppress end of file
+        }
+    delete buffer;
+    LOG_IF_ERROR1( ret, "GetTextFromFile-ret=%d", ret )
+    return ret;
+    }
+// ---------------------------------------------------------------------------
+// GetTextFromFile
+// ---------------------------------------------------------------------------
+//
+static TInt GetTextFromFile(
+        RFs& aFs,
+        const TDesC& aFilename,
+        TDes& aValue,
+        TBool aRemoveNewLines,
+        const TDesC& aTag = KNullDesC )
+    {
+    FUNC_LOG
+
+    RFile file;
+    TInt ret( file.Open( aFs, aFilename,
+        EFileRead | EFileStreamText | EFileShareReadersOnly ) );
+    if ( ret == KErrNone )
+        {
+        ret = GetTextFromFile( file, aValue, aTag );
+        file.Close();
+        }
+    else if ( ret == KErrNotFound || ret == KErrPathNotFound )
+        {
+        ret = KErrNotSupported;
+        }
+    if ( aRemoveNewLines &&
+        ( ret == KErrNone || ret == KErrTooBig ) )
+        {
+        RemoveNewLines( aValue );
+        }
+    LOG_IF_ERROR1( ret, "GetTextFromFile-2-ret=%d", ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// GetFWIDTextFromFile
+// ---------------------------------------------------------------------------
+//
+static TInt GetFWIDTextFromFile( RFs& aFs, TDes& aValue )
+    {
+    FUNC_LOG
+
+    // Solve file names and concatenate tagged info from each file
+    HBufC* buffer = HBufC::New( KMaxFileName );
+    if ( !buffer )
+        {
+        ERROR_LOG1( "GetFWIDTextFromFile-ret=%d", KErrNoMemory )
+        return KErrNoMemory;
+        }
+    TPtr ptr( buffer->Des() );
+    TFindFile find( aFs );
+    CDir* files = NULL;
+    TInt ret( find.FindWildByPath( KFWIDVersionFileName, NULL, files ) );
+    if ( ret == KErrNone && files )
+        {
+        TPtrC driveAndPath(
+            TParsePtrC( KFWIDVersionFileName ).DriveAndPath() );
+        TInt count( files->Count() );
+        for ( TInt i( 0 ); i < count; ++i )
+            {
+            // Setup file name and read info
+            ptr.Copy( driveAndPath );
+            ptr.Append( ( *files )[ i ].iName );
+            TInt ret2( GetTextFromFile(
+                aFs, ptr, aValue, EFalse, KFWIDVersionTag ) );
+            if ( ret2 != KErrNone )
+                {
+                ret = ret2;
+                }
+            else if ( i + 1 < count )
+                {
+                // Separate infos read from different files
+                ret = AppendTillMax( aValue, KFWIDVersionSeparator );
+                }
+            if ( ret != KErrNone )
+                {
+                break;
+                }
+            }
+        if ( !count )
+            {
+            ret = KErrNotSupported;
+            }
+        }
+    else if ( ret == KErrNotFound || ret == KErrPathNotFound )
+        {
+        ret = KErrNotSupported;
+        }
+    delete files;
+    delete buffer;
+    if ( ret == KErrNone || ret == KErrTooBig )
+        {
+        RemoveNewLines( aValue );
+        }
+    LOG_IF_ERROR1( ret, "GetFWIDTextFromFile-ret=%d", ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ReadTextFile
+// ---------------------------------------------------------------------------
+//
+static TInt ReadTextFile(
+        RFile& aFile,
+        TDes& aBuffer,
+        RArray< TPtrC >& aLineBuffer )
+    {
+    FUNC_LOG
+
+    // Read text file into buffers
+    TInt ret( KErrNone );
+    TFileText tf;
+    tf.Set( aFile );
+    aBuffer.SetMax();
+    TPtr ptr( aBuffer.MidTPtr( 0 ) );
+    TInt used( 0 );
+    do
+        {
+        ret = tf.Read( ptr );
+        TInt len( ptr.Length() );
+        if ( ( ret == KErrNone || ret == KErrEof ) && len > 0 )
+            {
+            // Store non empty text line
+            TInt err( aLineBuffer.Append( ptr ) );
+            if ( err == KErrNone )
+                {
+                ptr.SetMax();
+                ptr.Set( ptr.MidTPtr( len ) );
+                ptr.Zero();
+                used += len;
+                }
+            else
+                {
+                ret = err;
+                }
+            }
+        }
+    while ( ret == KErrNone );
+    if ( ret == KErrEof )
+        {
+        ret = KErrNone;
+        }
+    aBuffer.SetLength( used );
+    LOG_IF_ERROR1( ret, "ReadTextFile-ret=%d", ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ReadTextFile
+// ---------------------------------------------------------------------------
+//
+static HBufC* ReadTextFile(
+        RFs& aFs,
+        const TDesC& aFullPath,
+        RArray< TPtrC >& aLineBuffer,
+        TInt& aError )
+    {
+    FUNC_LOG
+
+    RFile file;
+    aError = file.Open( aFs, aFullPath,
+        EFileRead | EFileStreamText | EFileShareReadersOnly );
+    if ( aError != KErrNone )
+        {
+        ERROR_LOG1( "ReadTextFile-2-aError=%d", aError )
+        return NULL;
+        }
+    TInt size( 0 );
+    aError = file.Size( size );
+    if ( aError != KErrNone )
+        {
+        file.Close();
+        ERROR_LOG1( "ReadTextFile-3-aError=%d", aError )
+        return NULL;
+        }
+    // Get text size, create buffer for text and read text file
+    HBufC* ret = HBufC::New( ( size + sizeof( TText ) - 1 ) / sizeof( TText ) );
+    if ( !ret )
+        {
+        aError = KErrNoMemory;
+        file.Close();
+        ERROR_LOG2( "ReadTextFile-4-aError=%d,size=%d", aError, size )
+        return NULL;
+        }
+    TPtr ptr( ret->Des() );
+    aError = ReadTextFile( file, ptr, aLineBuffer );
+    file.Close();
+    if ( aError != KErrNone )
+        {
+        delete ret;
+        aLineBuffer.Reset();
+        ERROR_LOG1( "ReadTextFile-5-aError=%d", aError )
+        return NULL;
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// GetTagValue
+// ---------------------------------------------------------------------------
+//
+static TPtrC GetTagValue(
+        const TDesC& aTag,
+        const RArray< TPtrC >& aLineBuffer,
+        TInt& aError )
+    {
+    FUNC_LOG
+
+    aError = KErrNotFound;
+    TPtrC ret( KNullDesC );
+    TInt tagLen( aTag.Length() );
+    TInt count( aLineBuffer.Count() );
+    for( TInt i( 0 ); i < count; ++i )
+        {
+        TPtrC line( aLineBuffer[ i ] );
+        if ( !line.Left( tagLen ).CompareF( aTag ) )
+            {
+            ret.Set( line.Mid( tagLen ) );
+            aError = KErrNone;
+            break;
+            }
+        }
+    LOG_IF_ERROR1( aError, "GetTagValue-aError=%d", aError )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// GetTagValue
+// ---------------------------------------------------------------------------
+//
+static TInt GetTagValue(
+        TDes& aValue,
+        const TDesC& aTag,
+        const RArray< TPtrC >& aLineBuffer )
+    {
+    FUNC_LOG
+
+    aValue.Zero();
+    TInt ret( KErrNotFound );
+    TPtrC value( GetTagValue( aTag, aLineBuffer, ret ) );
+    if ( ret == KErrNone )
+        {
+        aValue.Copy( value.Left(
+            Min( aValue.MaxLength(), value.Length() ) ) );
+        RemoveNewLines( aValue );
+        }
+    LOG_IF_ERROR1( ret, "GetTagValue-ret=%d", ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// GetTagValue
+// ---------------------------------------------------------------------------
+//
+static TInt GetTagValue(
+        TInt& aValue,
+        const TDesC& aTag,
+        const RArray< TPtrC >& aLineBuffer )
+    {
+    FUNC_LOG
+
+    aValue = 0;
+    TInt ret( KErrNotFound );
+    TPtrC value( GetTagValue( aTag, aLineBuffer, ret ) );
+    if ( ret == KErrNone )
+        {
+        TLex lex( value );
+        ret = lex.Val( aValue );
+        if ( ret != KErrNone )
+            {
+            aValue = 0;
+            }
+        }
+    LOG_IF_ERROR1( ret, "GetTagValue-2-ret=%d", ret )
+    return ret;
+    }
+
+// ----------------------------------------------------------------------------
+// ReadSymbianOSVersion
+// ----------------------------------------------------------------------------
+//
+static TInt ReadSymbianOSVersion(
+        SysVersionInfo::TSymbianOSVersion& aOSVersion, RFs& aFs )
+    {
+    FUNC_LOG
+
+    RArray< TPtrC > lineBuffer;
+    TInt value( 0 );
+    TInt ret( KErrNone );
+    HBufC* buffer = ReadTextFile(
+        aFs, KPlatformVersionFileName, lineBuffer, ret );
+    if ( buffer )
+        {
+        ret = GetTagValue( value, KSymbianOSMajorVersionTag, lineBuffer );
+        if ( ret == KErrNone )
+            {
+            aOSVersion.iMajorVersion = value;
+            }
+        if ( ret == KErrNone )
+            {
+            ret = GetTagValue( value, KSymbianOSMinorVersionTag, lineBuffer );
+            if ( ret == KErrNone )
+                {
+                aOSVersion.iMinorVersion = value;
+                }
+            }
+        delete buffer;
+        }
+    lineBuffer.Close();
+    if ( ret == KErrNotFound || ret == KErrPathNotFound )
+        {
+        ret = KErrNotSupported;
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ReadProductVersion
+// ---------------------------------------------------------------------------
+//
+static TInt ReadProductVersion(
+        SysVersionInfo::TProductVersion& aProductVersion, RFs& aFs )
+    {
+    FUNC_LOG
+
+    RArray< TPtrC > lineBuffer;
+    TInt ret( KErrNone );
+    HBufC* buffer = ReadTextFile(
+        aFs, KProductVersionFileName, lineBuffer, ret );
+    if ( buffer )
+        {
+        // Ignore value not found errors, value just stays empty
+        GetTagValue(
+            aProductVersion.iManufacturer, KManufacturerTag, lineBuffer );
+        GetTagValue(
+            aProductVersion.iModel, KModelTag, lineBuffer );
+        GetTagValue(
+            aProductVersion.iProduct, KProductTag, lineBuffer );
+        GetTagValue(
+            aProductVersion.iRevision, KRevisionTag, lineBuffer );
+        delete buffer;
+        }
+    lineBuffer.Close();
+    if ( ret == KErrNotFound || ret == KErrPathNotFound )
+        {
+        ret = KErrNotSupported;
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// ReadProductInformation
+// ---------------------------------------------------------------------------
+//
+static TInt ReadProductInformation(
+    SysVersionInfo::TVersionInfoType aType,
+    TDes& aValue )
+    {
+    FUNC_LOG;
+
+    using namespace ExtendedVersionInfoPluginApi;
+
+    TFileName prodInfoDllPath;
+
+    _SYSVERSION_CREATE_LIT( KPluginDllName, EXTVERSIONINFO_PLUGIN_STRING );
+    _SYSVERSION_CREATE_LIT( KPluginFolder, SHARED_LIB_DIR );
+    _LIT( KExtPluginPathFormat, "z:%S\\%S" );
+
+    prodInfoDllPath.Format(
+        KExtPluginPathFormat, &KPluginFolder, &KPluginDllName );
+
+    RLibrary prodInfoDll;
+
+    TInt ret = prodInfoDll.Load( prodInfoDllPath );
+
+
+    if ( ret == KErrNone )
+        {
+        TLibraryFunction libFunc =
+            prodInfoDll.Lookup( EGetProductInformationFuncL );
+
+        if ( libFunc )
+            {
+            GetProductInformationFuncL getL =
+                reinterpret_cast<GetProductInformationFuncL>(libFunc);
+            TRAP( ret, ((*getL)( aType, aValue )) );
+            }
+        else
+            {
+            ret = KErrNotSupported;
+            }
+        prodInfoDll.Close();
+        }
+    else
+        {
+        ret = KErrNotSupported;
+        }
+
+    return ret;
+    }
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// SysVersionInfo::GetVersionInfo
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt SysVersionInfo::GetVersionInfo(
+        const TVersionInfoType aType, TDes& aValue )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    RFs fs;
+    TInt ret( fs.Connect() );
+    if ( ret == KErrNone )
+        {
+        ret = GetVersionInfo( aType, aValue, fs );
+        fs.Close();
+        }
+    else
+        {
+        aValue.Zero();
+        }
+    LOG_IF_ERROR2(
+        ret,
+        "SysVersionInfo::GetVersionInfo-aType=%d,ret=%d",
+        aType, ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// SysVersionInfo::GetVersionInfo
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt SysVersionInfo::GetVersionInfo(
+        const TVersionInfoType aType, TDes& aValue, RFs& aFs )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    aValue.Zero();
+
+    TInt ret( KErrNotSupported );
+    // if a version info text file does not exist attempt to read from
+    // the adaptation interface
+    TBool readProductInfo( EFalse );
+
+    switch ( aType )
+        {
+        case EFWVersion:
+            {
+            ret = GetFWIDTextFromFile( aFs, aValue );
+            readProductInfo = (ret == KErrNotSupported);
+            break;
+            }
+        case EOPVersion:
+            {
+            ret = GetTextFromFile(
+                aFs, KOPIDVersionFileName, aValue, ETrue );
+            readProductInfo = (ret == KErrNotSupported);
+            break;
+            }
+        case EModelVersion:
+            {
+            ret = GetTextFromFile(
+                aFs, KModelVersionFileName, aValue, ETrue );
+            readProductInfo = (ret == KErrNotSupported);
+            break;
+            }
+        case EProductCode: // product code is fetched only from the plugin
+            readProductInfo = ETrue;
+            break;
+
+        default:
+            {
+            break;
+            }
+        }
+
+    if ( readProductInfo )
+        {
+        ret = ReadProductInformation( aType, aValue );
+        }
+
+    if ( ret != KErrNone && ret != KErrTooBig )
+        {
+        aValue.Zero();
+        }
+    LOG_IF_ERROR2(
+        ret,
+        "SysVersionInfo::GetVersionInfo-2-aType=%d,ret=%d",
+        aType, ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// SysVersionInfo::GetVersionInfo
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt SysVersionInfo::GetVersionInfo( TVersionBase& aVersion )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    RFs fs;
+    TInt ret( fs.Connect() );
+    if ( ret == KErrNone )
+        {
+        ret = GetVersionInfo( aVersion, fs );
+        fs.Close();
+        }
+    LOG_IF_ERROR2(
+        ret,
+        "SysVersionInfo::GetVersionInfo-3-iType=%d,ret=%d",
+        aVersion.iType, ret )
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// SysVersionInfo::GetVersionInfo
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt SysVersionInfo::GetVersionInfo(
+        TVersionBase& aVersion, RFs& aFs )
+    {
+    FUNC_LOG_WITH_CLIENT_NAME
+
+    TInt ret( KErrNotSupported );
+    switch( aVersion.iType )
+        {
+        case ESymbianOSVersion:
+            {
+            ret = ReadSymbianOSVersion(
+                static_cast< TSymbianOSVersion& >( aVersion ), aFs );
+            break;
+            }
+        case EProductVersion:
+            {
+            ret = ReadProductVersion(
+                static_cast< TProductVersion& >( aVersion ), aFs );
+            break;
+            }
+        default:
+            {
+            break;
+            }
+        }
+    LOG_IF_ERROR2(
+        ret,
+        "SysVersionInfo::GetVersionInfo-4-iType=%d,ret=%d",
+        aVersion.iType, ret )
+    return ret;
+    }
+
+// End of File