omadrm/drmengine/server/src/DRMObsoleteFinder.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/server/src/DRMObsoleteFinder.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,466 @@
+/*
+* Copyright (c) 2003 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 the DRM Rights Database
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32std.h>		// RPointerArray
+#include <e32def.h>		// Type definitions
+
+#include <caf/caf.h>
+#include <dcfrep.h>
+#include "DRMCommon.h"	// DRM Error messages
+#include "DRMObsoleteFinder.h"
+#include "DRMRightsDB.h"
+#include "drmlog.h"
+#include <dcfrep.h>
+
+#include <SysUtil.h>    // Disk space checking
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <DriveInfo.h>
+#endif
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES  
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+const TInt KScanFileSystem = 1;
+const TInt KScanContents = 2;
+const TInt KRemoveUsedParents = 3;
+const TInt KWriteTempFile = 4;
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+LOCAL_C TInt CompareHBufC8( const HBufC8& aFirst, const HBufC8& aSecond );
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+LOCAL_C TInt CompareHBufC8( const HBufC8& aFirst, const HBufC8& aSecond )
+    {
+	return aFirst.Compare( aSecond );
+    };
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+        
+// -----------------------------------------------------------------------------
+// CDRMObsoleteFinder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CDRMObsoleteFinder* CDRMObsoleteFinder::NewL( RFs& aFs,
+                                            CDRMRightsDB* aDatabase,
+                                            TRequestStatus& aStatus,
+                                            RWriteStream& aStream,
+                                            TBool aPerformScan )
+    {
+    CDRMObsoleteFinder* self = new( ELeave ) CDRMObsoleteFinder( aFs, 
+                                                        aDatabase, aStatus, 
+                                                        aStream );
+    CleanupStack::PushL( self );
+    self->ConstructL( aPerformScan );
+    CleanupStack::Pop();
+    
+    return self;
+    }
+  
+        
+// -----------------------------------------------------------------------------
+// Destructor        
+// -----------------------------------------------------------------------------
+//
+CDRMObsoleteFinder::~CDRMObsoleteFinder()
+    {
+    // just in case
+    Cancel();
+    
+    if( iDcfClient )
+        {
+        delete iDcfClient;
+        iDcfClient = NULL;    
+        }
+    
+    if( iContents )
+        {
+        delete iContents;
+        iContents = NULL;   
+        }
+
+    if( iParents )
+        {
+        delete iParents;
+        iParents = NULL;            
+        }
+     
+    if( iNoContents )
+        {
+        delete iNoContents;
+        iNoContents = NULL;            
+        }            
+    };
+
+// -----------------------------------------------------------------------------
+// CDRMObsoleteFinder::ExecuteCleanupLD        
+// -----------------------------------------------------------------------------
+//    
+void CDRMObsoleteFinder::ExecuteFinderLD()
+    {
+    TRequestStatus* status = 0;
+    
+    if( !IsAdded() ) 
+        {
+        CActiveScheduler::Add(this);        
+        }
+    if ( !IsActive() ) 
+        {
+        SetActive();        
+        }
+    
+    iOperationStatus = KRequestPending;
+    status = &iStatus;
+    User::RequestComplete(status,KErrNone);        
+    };
+
+// -----------------------------------------------------------------------------                        
+// Default Constructor - First phase.
+// -----------------------------------------------------------------------------
+//
+CDRMObsoleteFinder::CDRMObsoleteFinder( RFs& aFs,
+                                        CDRMRightsDB* aDatabase,
+                                        TRequestStatus& aStatus,
+                                        RWriteStream& aStream ) :
+    CActive( EPriorityLow ),
+    iContents( NULL ),
+    iParents( NULL ),
+    iNoContents( NULL ),
+    iIndex( -1 ),
+    iFileServer( aFs ),
+    iStream( aStream ),
+    iRightsDb( aDatabase ),
+    iOperationStatus( aStatus ),
+    iState( KScanFileSystem )                         
+    {
+        
+    }; 
+        
+
+// -----------------------------------------------------------------------------                        
+// CDRMObsoleteFinder::ConstructL
+// -----------------------------------------------------------------------------
+// 
+void CDRMObsoleteFinder::ConstructL( const TBool aPerformScan )
+    {
+    // if the scan needs to be done, the initial state is different:
+    if( aPerformScan )
+        {
+        iState = KScanFileSystem;    
+        }
+    else
+        {
+        iState = KScanContents;    
+        } 
+       
+    // connect to dcf repository
+    iDcfClient = CDcfRep::NewL();
+    
+    // Create a new list
+    iContents = CDRMPointerArray<HBufC8>::NewL();    
+    
+    // Create a new list
+    iParents = CDRMPointerArray<HBufC8>::NewL();  
+
+    // Create a new list
+    iNoContents = CDRMPointerArray<HBufC8>::NewL();  
+        
+    };  
+
+// -----------------------------------------------------------------------------                        
+// CDRMObsoleteFinder::RunError
+// -----------------------------------------------------------------------------
+//  
+TInt CDRMObsoleteFinder::RunError(TInt aError)
+    {
+    TRequestStatus* status = 0;
+    
+    if( aError != KErrNone )
+        {
+        status = &iOperationStatus;
+        User::RequestComplete( status, aError );                
+        delete this;            
+        }
+    return KErrNone;
+    };
+
+// -----------------------------------------------------------------------------                        
+// CDRMObsoleteFinder::RunL
+// -----------------------------------------------------------------------------
+//      
+void CDRMObsoleteFinder::RunL()
+    {
+    TRequestStatus* status = 0;    
+    TInt error = KErrNone;
+    HBufC8* buffer = NULL;
+
+    // If the status of the cleaning is other than KErrNone
+    User::LeaveIfError( iStatus.Int() );
+
+    switch( iState )
+        {
+        case KScanFileSystem:
+            iState = KScanContents;
+            iDcfClient->RefreshDcf( iStatus );            
+            SetActive();    
+            break;
+        case KScanContents:
+            if( iIndex == -1 )
+                {
+                // Get the contents
+                iRightsDb->GetContentIDListL( *iContents );
+                // Reset the index
+                iIndex = 0;  
+                }
+            else 
+                {
+                iIndex++;                     
+                }  
+                
+            if( iIndex >= iContents->Count() )
+                {
+                iState = KRemoveUsedParents;
+                iIndex = -1;   
+                }
+            else 
+                {
+                // Check if there is content
+                TRAP( error, iDcfClient->OrderListL( *(*iContents)[iIndex] ));
+        
+                // If an error occurs, leave if it's ok, continue
+                if( error != KErrNotFound )
+                    {
+                    User::LeaveIfError( error ); 
+                    
+                    // Get all the parents
+                    if( !error ) 
+                        {
+                        GetParentsL( *(*iContents)[iIndex], *iParents );   
+                        }                      
+                    }
+                // If the error is not found, add to the no content list    
+                else
+                    {
+                    buffer = (*iContents)[iIndex]->AllocLC();
+                    iNoContents->AppendL( buffer );
+                    CleanupStack::Pop();    
+                    }                       
+                }
+            SetActive();
+            status = &iStatus;
+            User::RequestComplete(status,KErrNone);              
+            break;
+        case KRemoveUsedParents:
+            if( iIndex == -1 )
+                {
+                iIndex = 0;  
+                }
+            else 
+                {
+                iIndex++;                     
+                }
+                  
+            if( iIndex >= iParents->Count() )
+                {
+                iState = KWriteTempFile;
+                iIndex = -1; 
+                }
+            else
+                {
+                // Find the parent
+                error = iNoContents->FindInOrder( (*iParents)[iIndex], 
+                                       TLinearOrder<HBufC8>(CompareHBufC8));
+                                      
+                if( error != KErrNotFound )
+                    {
+                    buffer = (*iNoContents)[error];
+                    iNoContents->Remove( error );
+                    delete buffer;
+                    buffer = 0;    
+                    }                                                           
+                }
+            SetActive();
+            status = &iStatus;
+            User::RequestComplete(status,KErrNone);                 
+            break;
+        case KWriteTempFile:
+            ObsoleteToStreamL();
+            // we are complete:
+            status = &iOperationStatus;
+            User::RequestComplete( status, KErrNone );                
+            delete this; 
+            return;                          
+        default:
+            // illegal status, return error and delete object
+            status = &iOperationStatus;
+            User::RequestComplete( status, KErrGeneral );
+            delete this; 
+            return;                       
+        }
+    };    
+
+
+// ----------------------------------------------------------------------------
+// CDRMObsoleteFinder::GetParentsL
+// ----------------------------------------------------------------------------
+//
+void CDRMObsoleteFinder::GetParentsL( const TDesC8& aContentId,
+                                      RPointerArray<HBufC8>& aParents )
+    {
+    HBufC8* parentId = NULL;
+    TInt error = KErrNone;
+    CDRMPointerArray<CDRMPermission>* permissions = 
+      CDRMPointerArray<CDRMPermission>::NewLC();
+    permissions->SetAutoCleanup( ETrue );
+    CDRMPointerArray<CDRMPermission>& perm = *permissions;  
+
+    TRAP( error, iRightsDb->GetDBEntryByContentIDL( aContentId, *permissions ) );
+    
+    // If there are no keys it means that there is encryption key and such, but
+    // no available permissions
+    if( error == KErrCANoRights )
+        {
+        CleanupStack::PopAndDestroy(); // permissions
+        return;    
+        }
+    else 
+        {
+        User::LeaveIfError(error);    
+        }
+        
+    for( TInt i = 0; i < permissions->Count(); i++, error = KErrNone )
+        {
+        // Check if the permission has a parent
+        if( perm[i]->iParentUID ) 
+            {
+            // if it does, insert it to the aParents array
+            error = aParents.FindInOrder( perm[i]->iParentUID, 
+                                          TLinearOrder<HBufC8>(CompareHBufC8));
+            if( error == KErrNotFound )
+                {
+                parentId = perm[i]->iParentUID->AllocLC();
+                User::LeaveIfError( aParents.InsertInOrder(parentId, 
+                                    TLinearOrder<HBufC8>(CompareHBufC8)) );
+                CleanupStack::Pop();       
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // permissions     
+    }; 
+
+
+// -----------------------------------------------------------------------------
+// CDRMObsoleteFinder::ObsoleteToStreamL
+// -----------------------------------------------------------------------------
+//
+void CDRMObsoleteFinder::ObsoleteToStreamL()
+    {
+    TInt count( 0 );
+
+
+    TInt size( 4 ); // size of the count
+    for( count = 0; count < iNoContents->Count(); count++ )
+        {
+        size += (*iNoContents)[ count ]->Size();
+        size += sizeof(TUint16);
+        }
+
+    // Reset count variable:
+    count = 0;
+
+#ifndef RD_MULTIPLE_DRIVE
+
+    if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFileServer, 
+                                                size, 
+                                                EDriveC ) )
+    
+#else //RD_MULTIPLE_DRIVE
+    
+    TInt driveNumber( -1 );
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+
+    if ( SysUtil::DiskSpaceBelowCriticalLevelL( &iFileServer, 
+                                                size, 
+                                                driveNumber ) )
+    
+#endif
+
+        {
+        DRMLOG( _L( "CDRMDbSession::UriListToFileL: KErrDiskFull" ) );
+        User::Leave( KErrDiskFull );
+        }     
+    // Write the whole stuff into the file.
+    while( count < iNoContents->Count() )
+        {
+        iStream.WriteUint16L( (*iNoContents)[count]->Length() );
+        iStream.WriteL( *(*iNoContents)[count] );
+        ++count;
+        }
+    // Finish with a 0    
+    iStream.WriteUint16L( 0 );    
+    
+    iStream.CommitL();
+    }
+
+// -----------------------------------------------------------------------------                        
+// CDRMObsoleteFinder::DoCancel
+// -----------------------------------------------------------------------------
+//      
+void CDRMObsoleteFinder::DoCancel()
+    {  
+    }; 
+
+// -----------------------------------------------------------------------------                        
+// CDRMObsoleteFinder::DoCleanup
+// -----------------------------------------------------------------------------
+//      
+void CDRMObsoleteFinder::DoCleanup()
+    {
+    TRequestStatus* status = 0;      
+    if( iCancel <= 0 )
+        {
+        iCancel = 1;
+        status = &iStatus;
+        User::RequestComplete(status, KErrCancel);
+        }       
+    }; 
+
+
+
+
+
+
+
+