--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/dcf/src/Oma1Dcf.cpp Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,570 @@
+/*
+* Copyright (c) 2002-2004 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: ?Description
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <e32base.h>
+#include <f32file.h>
+#include <utf.h>
+#include <WSPDecoder.h>
+#include "Oma1Dcf.h"
+#include "DRMRightsClient.h"
+#include <centralrepository.h>
+#include <UTF.h>
+
+#include "DrmUtilityInternalcrkeys.h" // Cenrep extension for OmaBased
+
+// LOCAL CONSTANTS AND MACROS
+_LIT8(KMimeApplication, "application");
+_LIT8(KMimeText, "text");
+_LIT8(KMimeAudio, "audio");
+_LIT8(KMimeImage, "image");
+_LIT8(KMimeVideo, "video");
+_LIT8(KMimeModel, "model");
+_LIT8(KMimeMessage, "message");
+_LIT8(KMimeMultipart, "multipart");
+_LIT8(KXHeader, "x-");
+_LIT8(KColon, ":");
+//_LIT8(KSemiColon, ";");
+//_LIT8(KNewLine, "\n");
+_LIT8(KEndLine, "\r\n");
+
+const TInt KCenRepDataLength( 50 );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::COma1Dcf
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+COma1Dcf::COma1Dcf():
+ iHeaders(NULL)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void COma1Dcf::ConstructL(const RFile& aFile)
+ {
+ CDcfCommon::ConstructL(aFile);
+ User::LeaveIfError(ReadHeaderL());
+ }
+
+void COma1Dcf::ConstructL(const TDesC8& aMemoryBlock)
+ {
+ User::LeaveIfError(ReadHeaderL(aMemoryBlock));
+ iData = aMemoryBlock.AllocL();
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::FetchOmaBasedInfoL
+// -----------------------------------------------------------------------------
+//
+HBufC8* COma1Dcf::FetchOmaBasedInfoL()
+ {
+ CRepository* repository( NULL );
+ RBuf bOmaBasedMimeType;
+ HBufC8* mimetype = NULL;
+
+ CleanupClosePushL(bOmaBasedMimeType);
+ bOmaBasedMimeType.CreateL( KCenRepDataLength );
+
+ repository = CRepository::NewL( KCRUidOmaBased );
+
+ CleanupStack::PushL( repository );
+
+ User::LeaveIfError(repository->Get( KOmaBasedMimeType, bOmaBasedMimeType ));
+ mimetype = CnvUtfConverter::ConvertFromUnicodeToUtf8L( bOmaBasedMimeType );
+ CleanupStack::PopAndDestroy( repository );
+
+ CleanupStack::PopAndDestroy();
+
+ return mimetype;
+
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C COma1Dcf* COma1Dcf::NewL(const RFile& aFile)
+ {
+ COma1Dcf* self = new(ELeave) COma1Dcf;
+
+ CleanupStack::PushL(self);
+ self->ConstructL(aFile);
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C COma1Dcf* COma1Dcf::NewL(const TDesC8& aMemoryBlock)
+ {
+ COma1Dcf* self = new(ELeave) COma1Dcf;
+
+ CleanupStack::PushL(self);
+ self->ConstructL(aMemoryBlock);
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C COma1Dcf::~COma1Dcf()
+ {
+ delete iHeaders;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+TInt COma1Dcf::ReadHeaderL(const TDesC8& aMemoryBlock)
+ {
+ TInt r = KErrNone;
+ TInt cidLength = 0;
+ TInt mimeLength = 0;
+ TInt fieldLength = 0;
+ TBuf8<10> lengthFields;
+ TUint32 length;
+ TPtr8 ptr(NULL,0,0);
+
+ if (aMemoryBlock.Length()<3)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iVersion = aMemoryBlock[0];
+
+ if (iVersion!=1)
+ {
+ // for OMA Version 1, DCF version must be 1
+ User::Leave(KErrArgument);
+ }
+
+ mimeLength = aMemoryBlock[1];
+ cidLength = aMemoryBlock[2];
+
+ if (mimeLength + cidLength + 3 + 5 + 5 > aMemoryBlock.Length())
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ if (mimeLength!=0)
+ {
+ iMimeType = aMemoryBlock.Mid(3, mimeLength).AllocL();
+ ptr.Set(iMimeType->Des());
+ r = ptr.FindF(_L8("/"));
+ if (r==KErrNotFound)
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ if (cidLength!=0)
+ {
+ iContentID = aMemoryBlock.Mid(3 + mimeLength, cidLength).AllocL();
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+
+
+ lengthFields.Copy(aMemoryBlock.Mid(3 + mimeLength + cidLength, 10));
+ TWspPrimitiveDecoder decoder(lengthFields);
+ fieldLength = decoder.UintVar(length);
+ if( fieldLength < 0 )
+ {
+ User::Leave(KErrArgument);
+ }
+ iHeaderLength = length;
+ fieldLength += decoder.UintVar(length);
+ if( fieldLength < 0 )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iDataLength = length;
+ iOffset = 3 + mimeLength + cidLength + fieldLength + iHeaderLength;
+ if (iDataLength == 0)
+ {
+ iDataLength = aMemoryBlock.Length() - iOffset;
+ }
+ iPlainTextLength = iDataLength - KDCFKeySize;
+ iPlainTextLengthValid = EFalse;
+
+ if (mimeLength + cidLength + 3 + 5 + 5 + iHeaderLength <=
+ aMemoryBlock.Length())
+ {
+ iHeaders = aMemoryBlock.Mid(3 + mimeLength + cidLength +
+ fieldLength, iHeaderLength).AllocL();
+
+ ReadHeaderValuesL();
+ }
+ return r;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::ReadHeaderValuesL
+//
+// -----------------------------------------------------------------------------
+//
+void COma1Dcf::ReadHeaderValuesL(void)
+ {
+ TPtrC8 ptr(NULL, 0);
+
+ if (GetHeaderL(KRightsIssuer, ptr) == KErrNone)
+ {
+ if( iRightsIssuerURL )
+ {
+ delete iRightsIssuerURL;
+ iRightsIssuerURL = NULL;
+ }
+ iRightsIssuerURL = ptr.AllocL();
+ }
+ if (GetHeaderL(KContentName, ptr) == KErrNone)
+ {
+ if( iTitle )
+ {
+ delete iTitle;
+ iTitle = NULL;
+ }
+ iTitle = ptr.AllocL();
+ }
+ if (GetHeaderL(KContentDescription, ptr) == KErrNone)
+ {
+ if( iDescription )
+ {
+ delete iDescription;
+ iDescription = NULL;
+ }
+ iDescription = ptr.AllocL();
+ }
+ if (GetHeaderL(KIconURI, ptr) == KErrNone)
+ {
+ if( iIconUri )
+ {
+ delete iIconUri;
+ iIconUri = NULL;
+ }
+ iIconUri = ptr.AllocL();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+TInt COma1Dcf::ReadHeaderL(void)
+ {
+ TInt r = KErrNone;
+ TInt pos = 0;
+ TUint8 v = 0;
+ TPtr8 p(&v, 1, 1);
+ TInt cidLength = 0;
+ TInt mimeLength = 0;
+ TInt fieldLength = 0;
+ TBuf8<10> lengthFields;
+ TUint32 length;
+ TInt size;
+
+ iFile.Size(size);
+ if (size<3)
+ {
+ User::Leave(KErrArgument);
+ }
+ iFile.Seek(ESeekStart, pos);
+
+ iFile.Read(p);
+ iVersion = v;
+ if (iVersion!=1)
+ {
+ // for OMA Version 1, DCF version must be 1
+ User::Leave(KErrArgument);
+ }
+
+ iFile.Read(p);
+ mimeLength = v;
+ if (mimeLength==0)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iFile.Read(p);
+ cidLength = v;
+ if (cidLength==0)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iMimeType = HBufC8::NewMax(mimeLength);
+ User::LeaveIfNull(iMimeType);
+ p.Set(iMimeType->Des());
+ iFile.Read(p, mimeLength);
+ p.Set(iMimeType->Des());
+ r = p.FindF(_L8("/"));
+ if (r==KErrNotFound)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iContentID = HBufC8::NewMax(cidLength);
+ User::LeaveIfNull(iContentID);
+ p.Set(iContentID->Des());
+ iFile.Read(p, cidLength);
+
+ pos = 0;
+ iFile.Seek(ESeekCurrent, pos);
+ iFile.Read(lengthFields);
+ TWspPrimitiveDecoder decoder(lengthFields);
+ fieldLength = decoder.UintVar(length);
+ if( fieldLength < 0 )
+ {
+ User::Leave(KErrArgument);
+ }
+ iHeaderLength = length;
+ fieldLength += decoder.UintVar(length);
+ if( fieldLength < 0 )
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iDataLength = length;
+ iOffset = pos + fieldLength + iHeaderLength;
+ if (iDataLength == 0)
+ {
+ iDataLength = size - iOffset;
+ }
+ iPlainTextLength = iDataLength - KDCFKeySize;
+ iPlainTextLengthValid = EFalse;
+
+ pos = pos + fieldLength;
+ iFile.Seek(ESeekStart, pos);
+ iHeaders = HBufC8::NewL(iHeaderLength);
+ p.Set(iHeaders->Des());
+ iFile.Read(p, iHeaderLength);
+
+ ReadHeaderValuesL();
+
+ return r;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool COma1Dcf::IsValidDcf(const TDesC8& aDcfFragment)
+ {
+ TPtrC8 mimeType;
+ TInt i;
+ TBool r = EFalse;
+ TInt error = KErrNone;
+ HBufC8* omaBasedBuf = NULL;
+
+ if (aDcfFragment.Length() > 15)
+ {
+ i = aDcfFragment.Right(aDcfFragment.Length() - 3).Locate('/');
+ if (aDcfFragment[0] == 1 && i != KErrNotFound)
+ {
+ mimeType.Set(aDcfFragment.Mid(3, i));
+ if (mimeType.CompareF(KMimeImage) == 0 ||
+ mimeType.CompareF(KMimeAudio) == 0 ||
+ mimeType.CompareF(KMimeApplication) == 0 ||
+ mimeType.CompareF(KMimeText) == 0 ||
+ mimeType.CompareF(KMimeModel) == 0 ||
+ mimeType.CompareF(KMimeMessage) == 0 ||
+ mimeType.CompareF(KMimeVideo) == 0 ||
+ mimeType.CompareF(KMimeMultipart) == 0 ||
+ aDcfFragment.Mid(3, 2).CompareF(KXHeader) == 0)
+ {
+ r = ETrue;
+ // Check for specific mimetype
+
+ TRAP( error, omaBasedBuf = FetchOmaBasedInfoL() );
+
+ if( !error )
+ {
+ mimeType.Set(aDcfFragment.Mid(3,
+ omaBasedBuf->Length()));
+
+
+ if (mimeType.CompareF( *omaBasedBuf ) == 0)
+ {
+ r = EFalse;
+ }
+ }
+ delete omaBasedBuf;
+ }
+ }
+ }
+ return r;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+TInt COma1Dcf::CheckUniqueId(const TDesC& aUniqueId)
+ {
+ TInt r = CDcfCommon::CheckUniqueId(aUniqueId);
+
+ if (r == KErrNotFound)
+ {
+ HBufC8* id = NULL;
+ TRAPD(err, id = CnvUtfConverter::ConvertFromUnicodeToUtf8L(aUniqueId));
+ if (err == KErrNone)
+ {
+ if (iContentID->Compare(*id) == 0)
+ {
+ r = 0;
+ }
+ }
+ else
+ {
+ r = err;
+ }
+ delete id;
+ }
+ return r;
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+TInt COma1Dcf::OpenPart(const TDesC& aUniqueId)
+ {
+ return OpenPart(CheckUniqueId(aUniqueId));
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+TInt COma1Dcf::OpenPart(TInt aPart)
+ {
+ if (aPart == 0)
+ {
+ return KErrNone;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::
+//
+// -----------------------------------------------------------------------------
+//
+void COma1Dcf::GetPartIdsL(RPointerArray<HBufC8>& aPartList)
+ {
+ aPartList.ResetAndDestroy();
+ aPartList.AppendL(iContentID->Des().AllocL());
+ }
+
+// -----------------------------------------------------------------------------
+// COma1Dcf::GetHeaderL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt COma1Dcf::GetHeaderL(
+ const TDesC8& aHeaderName,
+ TPtrC8& aHeaderValue)
+ {
+ TInt i;
+ TInt j;
+ TPtrC8 ptr( iHeaders->Des() );
+
+ // Add Room for CRLF and Semicolon:
+ HBufC8* buffer = HBufC8::NewMaxLC( aHeaderName.Length() + 3 );
+ TPtr8 searchBuf( const_cast<TUint8*>(buffer->Ptr()), 0, buffer->Des().MaxSize() );
+
+ searchBuf.Copy(aHeaderName);
+ searchBuf.Append(KColon);
+
+ // First see if the
+ i = ptr.Find(searchBuf);
+ if( i < 0 )
+ {
+ CleanupStack::PopAndDestroy(); // buffer
+ return KErrNotFound;
+ }
+
+ if( i > 0 )
+ {
+ // if it's not the first one, use the search buffer:
+ // Create the search buffer
+ searchBuf.Copy(KEndLine);
+ searchBuf.Append(aHeaderName);
+ searchBuf.Append(KColon);
+
+ // First see if the
+ i = ptr.Find(searchBuf);
+ if ( i < 0 )
+ {
+ CleanupStack::PopAndDestroy(); // buffer
+ return KErrNotFound;
+ }
+ }
+ // Move search buffer
+ i += searchBuf.Length();
+
+ j = ptr.Mid(i).Find(KEndLine);
+ if( j < 0 )
+ {
+ CleanupStack::PopAndDestroy(); // buffer
+ return KErrNotFound;
+ }
+
+ aHeaderValue.Set( ptr.Mid(i, j) );
+
+ CleanupStack::PopAndDestroy(); // buffer
+ return KErrNone;
+ }
+
+// End of File