diff -r 50c53e893c3f -r 1221b68b8a5f commondrm/drmqtencryptor/drmencyptor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commondrm/drmqtencryptor/drmencyptor.cpp Tue Aug 31 15:29:38 2010 +0300 @@ -0,0 +1,795 @@ +/* +* Copyright (c) 2003-2009 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: DRM Encryption tool. +* +*/ + +#include "drmencryptor.h" +//#include "ui_dialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +//#include + +#include "drmserviceapi.h" +#include "DRMTypes.h" + +const TInt KBufferSize = 20000; + +DRMEncryptor::DRMEncryptor() +{ + QWidget *widget = new QWidget(); + setCentralWidget(widget); + + setBackgroundRole( QPalette::Window ); + + QVBoxLayout *layout = new QVBoxLayout; + layout->setAlignment(Qt::AlignCenter); + + QLabel *mainWindowLabel = new QLabel("DRM Encryptor"); + layout->addWidget(mainWindowLabel); + + //layout->addStretch(); + + //ui->setupUi(this); + //iOptionsMenu = menuBar()->addMenu(tr("&Options")); + + // Create menu options + iSetDRMClockAct = new QAction(tr("&Set DRM Clock"), this); + iSetDRMClockAct->setStatusTip(tr("Set DRM secure clock time.")); + + iGetDRMClockAct = new QAction(tr("&Get DRM Clock Time"), this); + iGetDRMClockAct->setStatusTip(tr("Get DRM secure clock time.")); + + iEncryptAct = new QAction(tr("&Encrypt"), this); + iEncryptAct->setStatusTip(tr("Encrypt")); + + iLaunchBrowserAct = new QAction(tr("&Launch Browser"), this); + iLaunchBrowserAct->setStatusTip(tr("Launch Browser")); + + iDeleteWMDRMDBAct = new QAction(tr("&Delete WMDRM DB"), this); + iDeleteWMDRMDBAct->setStatusTip(tr("Delete WMDRM Database rights.")); + + iDeleteOMADRMDBAct = new QAction(tr("&Delete OMADRM DB"), this); + iDeleteOMADRMDBAct->setStatusTip(tr("Delete OMADRM Database rights.")); + + menuBar()->addAction(iSetDRMClockAct); + menuBar()->addAction(iGetDRMClockAct); + menuBar()->addAction(iEncryptAct); + menuBar()->addAction(iDeleteWMDRMDBAct); + menuBar()->addAction(iDeleteOMADRMDBAct); + menuBar()->addAction(iLaunchBrowserAct); + + connect(iSetDRMClockAct, SIGNAL(triggered()), this, SLOT(setDRMClock())); + connect(iGetDRMClockAct, SIGNAL(triggered()), this, SLOT(getDRMClock())); + connect(iEncryptAct, SIGNAL(triggered()), this, SLOT(startEncrypt())); + connect(iDeleteWMDRMDBAct, SIGNAL(triggered()), this, SLOT(deleteWmDrmDB())); + connect(iDeleteOMADRMDBAct, SIGNAL(triggered()), this, SLOT(deleteOmaDrmDB())); + connect(iLaunchBrowserAct, SIGNAL(triggered()), this, SLOT(launchBrowser())); + + //setDRMClockButton = new QPushButton("Set DRM Clock", this); + //connect(setDRMClockButton, SIGNAL(clicked()), this, SLOT(setDRMClock())); + //setDRMClockButton->show(); + +/* ui->pushButton->setEnabled(false); + + ui->lineEdit->setValidator(new QDoubleValidator(this)); + ui->lineEdit_2->setValidator(new QDoubleValidator(this)); +*/ + //connect(ui->mainMenu,SIGNAL(onChanged()),this,SLOT(onLaske())); + //connect(ui->lineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(onTextChanged(const QString &))); + //connect(ui->mainMenu,SIGNAL(textChanged(const QString &)),this,SLOT(onTextChanged(const QString &))); + + widget->setLayout(layout); +} + +DRMEncryptor::~DRMEncryptor() +{ + //delete ui; +} + +void DRMEncryptor::setDRMClock() +{ + DateTimeDialog *dateTimeDialog = new DateTimeDialog(); + dateTimeDialog->show(); +} + +void DRMEncryptor::getDRMClock() +{ + TTime time; + TInt timeZone; + TDateTime date; + DRMClock::ESecurityLevel level; + TInt error( KErrNone ); + TBuf< 80 > buf; + + DRM::CDrmServiceApi* service = NULL; + + TRAPD(err, service = DRM::CDrmServiceApi::NewL()); + if(err!=KErrNone) + { + QMessageBox::information(this, tr("DRM Clock"),tr("Error creating CDrmServiceApi.")); + buf.AppendNum(error); + QString string((QChar*)buf.Ptr(),buf.Length()); + QMessageBox::information(this, tr("DRM Clock"),string); + delete service; // service + return; + } + + error = service->GetSecureTime( time, timeZone, level ); + if(!error==KErrNone) + { + QMessageBox::information(this, tr("DRM Clock"),tr("Error getting secure time.")); + + buf.AppendNum(error); + QString string((QChar*)buf.Ptr(),buf.Length()); + QMessageBox::information(this, tr("DRM Clock"),string); + delete service; + return; + } + + date = time.DateTime(); + + if(level == DRMClock::KSecure) + { + _LIT(KFormatTxt,"DRMClock Time:\n%d/%d/%d\n%d:%d:%d\nNitz available"); + buf.Format( KFormatTxt, + date.Day()+1, + TInt(date.Month()+1), + date.Year(), + date.Hour(), + date.Minute(), + date.Second()); + } + else + { + _LIT(KFormatTxt,"DRMClock Time:\n%d/%d/%d\n%d:%d:%d\nNitz unavailable"); + buf.Format( KFormatTxt, + date.Day()+1, + TInt(date.Month()+1), + date.Year(), + date.Hour(), + date.Minute(), + date.Second()); + } + + QGridLayout *layout = new QGridLayout; + layout->setAlignment(Qt::AlignCenter); + setLayout(layout); + + + QString datetimeString((QChar*)buf.Ptr(),buf.Length()); + + QMessageBox *drmClockTime = new QMessageBox(this); + drmClockTime->setWindowTitle(tr("DRM Clock")); + drmClockTime->setText(datetimeString); + + layout->addWidget(drmClockTime); + drmClockTime->show(); + +} + +LOCAL_C void ReadFileL(HBufC8*& aContent, const TDesC& aName, RFs& aFs) + { + TInt size = 0; + RFile file; + User::LeaveIfError(file.Open(aFs, aName, EFileRead)); + User::LeaveIfError(file.Size(size)); + aContent = HBufC8::NewLC(size); + TPtr8 ptr(aContent->Des()); + User::LeaveIfError(file.Read(ptr, size)); + CleanupStack::Pop(); //aContent + } + +// --------------------------------------------------------- +// UpdateDCFRepositoryL() +// Update saved file to DCFRepository +// --------------------------------------------------------- +// +LOCAL_C void UpdateDCFRepositoryL( const TDesC& aFileName) + { + CDcfEntry* dcf( NULL ); + CDcfRep* dcfRep( NULL ); + + dcf = CDcfEntry::NewL(); + CleanupStack::PushL( dcf ); + + dcfRep = CDcfRep::NewL(); + CleanupStack::PushL( dcfRep ); + + dcf->SetLocationL( aFileName, 0 ); + dcfRep->UpdateL( dcf ); + + CleanupStack::PopAndDestroy(2); // dcf, dcfRep + } + +void ProcessRightsL(const TDesC& aFile) + { + CDRMMessageParser* c = NULL; + HBufC8* d = NULL; + RFs fs; + RPointerArray rights; + + User::LeaveIfError(fs.Connect()); + c = CDRMMessageParser::NewL(); + ReadFileL(d, aFile, fs); + c->ProcessRightsObject(*d, rights); + rights.ResetAndDestroy(); + delete d; + delete c; + fs.Close(); + } + +void DRMEncryptor::ProcessMessageL(const TDesC& aFile, const TDesC& aOutput) + { + CDRMMessageParser* c = NULL; + HBufC8* d = NULL; + RFs fs; + TPtr8 inRead(NULL, 0); + TInt error = 1; + __UHEAP_MARK; + + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + c = CDRMMessageParser::NewL(); + CleanupStack::PushL(c); + + d = HBufC8::NewLC( KBufferSize ); + + RFile input; + User::LeaveIfError(input.Open( fs, aFile, EFileRead )); + CleanupClosePushL( input ); + + RFileWriteStream output; + output.Replace( fs, aOutput, EFileWrite ); + CleanupClosePushL( output ); + + c->InitializeMessageParserL( output ); + + while( error ) + { + inRead.Set( const_cast(d->Ptr()),0,KBufferSize); + error = input.Read( inRead ); + + if( error ) + { + c->FinalizeMessageParserL(); + + User::Leave( error ); + } + else + { + error = inRead.Length(); + } + + if( error ) + { + c->ProcessMessageDataL(inRead); + } + } + + c->FinalizeMessageParserL(); + + + CleanupStack::PopAndDestroy( 5 ); // fs, c, d, input, output + UpdateDCFRepositoryL( aOutput ); + __UHEAP_MARKEND; + } + +void EncryptFileL(const TDesC& aFile, TDesC& aOutput, TInt aMultiplier) + { + COma1DcfCreator* c = NULL; + CDRMRights* rights = NULL; + TBuf8<64> mime; + RFs fs; + TFileName aDcfFile; + TInt aOriginalFileNameLength(aOutput.Length() - 4); + + User::LeaveIfError(fs.Connect()); + if (aFile.Right(3).CompareF(_L("amr")) == 0) //AMR + { + mime.Copy(_L8("audio/amr")); + } + else if (aFile.Right(3).CompareF(_L("awb")) == 0) //AMR-AWB + { + mime.Copy(_L8("audio/amr-wb")); + } + else if (aFile.Right(3).CompareF(_L("mp3")) == 0) //MP3 + { + mime.Copy(_L8("audio/mpeg")); + } + else if (aFile.Right(3).CompareF(_L("mp4")) == 0) //MP4 + { + mime.Copy(_L8("audio/mp4")); + } + else if (aFile.Right(3).CompareF(_L("m4a")) == 0) //M4A + { + mime.Copy(_L8("audio/mp4")); + } + else if (aFile.Right(3).CompareF(_L("3gp")) == 0) //3GPP + { + mime.Copy(_L8("audio/3gpp")); + } + else if (aFile.Right(3).CompareF(_L("3g2")) == 0) //3GPP2 + { + mime.Copy(_L8("audio/3gpp2")); + } + else if (aFile.Right(3).CompareF(_L("aac")) == 0) //AAC + { + mime.Copy(_L8("audio/aac")); + } + else if (aFile.Right(3).CompareF(_L("mid")) == 0) //MIDI + { + mime.Copy(_L8("audio/midi")); + } + else if (aFile.Right(5).CompareF(_L(".spmid")) == 0) //SP-MIDI + { + mime.Copy(_L8("audio/sp-midi")); + } + else if (aFile.Right(3).CompareF(_L("rmf")) == 0) //RMF + { + mime.Copy(_L8("audio/rmf")); + } + else if (aFile.Right(4).CompareF(_L("mxmf")) == 0) //Mobile-XMF + { + mime.Copy(_L8("audio/mobile-xmf")); + } + else if (aFile.Right(3).CompareF(_L("wav")) == 0) //WAV + { + mime.Copy(_L8("audio/x-wav")); + } + else if (aFile.Right(3).CompareF(_L("gif")) == 0) // GIF + { + mime.Copy(_L8("image/gif")); + } + else if (aFile.Right(3).CompareF(_L("jpg")) == 0) // JPEG + { + mime.Copy(_L8("image/jpeg")); + } + else if (aFile.Right(3).CompareF(_L("txt")) == 0) // text + { + mime.Copy(_L8("text/plain")); + } + else if (aFile.Right(3).CompareF(_L("pip")) == 0) // PIP + { + mime.Copy(_L8("application/x-pip")); + } + + aDcfFile.Append(aOutput); + + for(TInt i = 0; i < aMultiplier ; ++i) + { + aDcfFile.Delete(aOriginalFileNameLength, aDcfFile.Length()); + aDcfFile.Append(_L("-")); + aDcfFile.AppendNum(i); + aDcfFile.Append(_L(".dcf")); + c = COma1DcfCreator::NewL(); + CleanupStack::PushL(c); + fs.Delete(aOutput); + c->EncryptFileL(aFile, aDcfFile, mime, rights); + UpdateDCFRepositoryL( aDcfFile ); + delete rights; + CleanupStack::PopAndDestroy(); // c + } + fs.Close(); + + } + +void DRMEncryptor::startEncrypt() + { + TUint result = 0; + TUint aEncryptedCount = 0; + TUint aRightsCount = 0; + TUint aMessagesProcessed = 0; + TBuf<128> buffer; + + result = EncryptL(aEncryptedCount, aRightsCount, aMessagesProcessed); + + buffer.Append(_L("Encryption done\n")); + if(result < 1) + { + buffer.Append(_L("No files found")); + } + if(aMessagesProcessed != 0) + { + buffer.AppendNum(aMessagesProcessed); + buffer.Append(_L(" messages processed\n")); + } + if(aRightsCount != 0) + { + buffer.AppendNum(aRightsCount); + buffer.Append(_L(" rights objects processed\n")); + } + if(aMessagesProcessed != 0) + { + buffer.AppendNum(aEncryptedCount); + buffer.Append(_L(" files encrypted\n")); + } + + QGridLayout *layout = new QGridLayout; + layout->setAlignment(Qt::AlignCenter); + setLayout(layout); + + QString encryptString((QChar*)buffer.Ptr(),buffer.Length()); + QMessageBox *encrpytMessage = new QMessageBox(this); + encrpytMessage->setWindowTitle(tr("Encrypt")); + encrpytMessage->setText(encryptString); + + layout->addWidget(encrpytMessage); + encrpytMessage->show(); + + } + +TUint DRMEncryptor::EncryptL(TUint& aEncryptedCount, TUint& aRightsCount, TUint& aMessagesProcessed) + { + TInt i; + CDir* files; + TFileName input; + TFileName output; + TUint inputNameSize = 0; + TUint outputNameSize = 0; + RFs fs; + User::LeaveIfError(fs.Connect()); + TInt aMultiplier(1); + + +#ifdef __WINS__ + input.Append(_L("c:\\data\\DRM\\")); + output.Append(_L("c:\\data\\Others\\")); +#else +#ifndef RD_MULTIPLE_DRIVE + + input.Append(_L("e:\\DRM\\")); + output.Append(_L("e:\\Others\\")); + +#else //RD_MULTIPLE_DRIVE + + TInt driveNumber( -1 ); + TChar driveLetter; + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, driveNumber ); + fs.DriveToChar( driveNumber, driveLetter ); + + _LIT( KdrmDir, "%c:\\DRM\\" ); + input.Format( KdrmDir, (TUint)driveLetter ); + + _LIT( KothersDir, "%c:\\Others\\" ); + output.Format( KothersDir, (TUint)driveLetter ); + +#endif +#endif + + inputNameSize = input.Length(); + outputNameSize = output.Length(); + + + fs.MkDir(input); + fs.MkDir(output); + + fs.GetDir(input, KEntryAttNormal, ESortNone, files); + for (i = 0; i < files->Count(); i++) + { + input.Append((*files)[i].iName); + + output.Append((*files)[i].iName); + + if (input.Right(2).CompareF(_L("dm")) == 0) + { + + for(TInt ii = 0; ii < aMultiplier ; ++ii) + { + output.Delete(outputNameSize +(*files)[i].iName.Length() , output.Length()-1); + output.Append(_L("-")); + output.AppendNum(ii); + output.Append(_L(".dcf")); + ProcessMessageL(input, output); + ++aMessagesProcessed; + } + } + else if (input.Right(3).CompareF(_L("oro")) == 0 || + input.Right(3).CompareF(_L("drc")) == 0 || + input.Right(2).CompareF(_L("ro")) == 0 || + input.Right(2).CompareF(_L("dr")) == 0 ) + { + for (TInt iii = 0; iii < aMultiplier; ++iii) + { + ProcessRightsL(input); + ++aRightsCount; + } + } + else if (input.Right(3).CompareF(_L("dcf")) != 0) + { + output.Append(_L(".dcf")); + EncryptFileL(input, output, aMultiplier); + ++aEncryptedCount; + } + + //restore paths + input.Delete(inputNameSize, input.Length()-1); + output.Delete(outputNameSize, output.Length()-1); + } + + fs.Close(); + + TRequestStatus status; + CDcfRep* rep = CDcfRep::NewL(); + CleanupStack::PushL(rep); + rep->RefreshDcf(status); + User::WaitForRequest( status ); + CleanupStack::PopAndDestroy( rep ); + + delete files; + + return (aEncryptedCount*aMultiplier + aRightsCount + aMessagesProcessed); + + } + +ContentAccess::CManager* GetCafDataL( TAgent& aAgent ) + { + TPtr8 ptr(NULL, 0, 0); + RArray agents; + TRequestStatus status; + TInt i; + + CleanupClosePushL( agents ); + CManager* manager = CManager::NewLC(); + + manager->ListAgentsL( agents ); + + for (i = 0; i < agents.Count(); i++) + { + if (agents[i].Name().Compare(KWmDrmAgentName) == 0) + { + aAgent = agents[i]; + break; + } + } + CleanupStack::Pop( manager ); + CleanupStack::PopAndDestroy(); // agents + return manager; + } + +void DRMEncryptor::DeleteWmDrmRdbL() + { + // get the data part + ContentAccess::CManager* manager = NULL; + ContentAccess::TAgent agent; + TPtr8 ptr(NULL, 0, 0); + TPtrC8 ptr2; + + // Find the caf agent and create manager + manager = GetCafDataL( agent ); + CleanupStack::PushL( manager ); + + User::LeaveIfError( + manager->AgentSpecificCommand( agent, + (TInt)DRM::EWmDrmDeleteRights, + ptr2, + ptr) ); + CleanupStack::PopAndDestroy( manager ); + } + +void DRMEncryptor::deleteWmDrmDB() + { + TRAPD(err, DeleteWmDrmRdbL()); + if(!err) + { + QMessageBox::information(this, tr("WMDRM DB"),tr("DRM rights deleted.")); + } + else + { + QMessageBox::information(this, tr("WMDRM DB"),tr("Error deleting WMDRM rights.")); + } + } + +void DRMEncryptor::deleteOmaDrmDB() + { + RDRMRightsClient client; + User::LeaveIfError(client.Connect()); + client.DeleteAll(); + client.Close(); + } + + + +void DRMEncryptor::launchBrowser() + { + /*_LIT( KTestDrmFile, "c:\\data\\others\\sd_water003.dcf" ); + TInt urlLength = 256; + TFileName fileName(KTestDrmFile); + RFile file; + RFs fs; + + User::LeaveIfError(fs.Connect()); + TInt result = 0; + + result = file.Open(fs, fileName, EFileRead | EFileShareReadersOrWriters); + + CData* content = CData::NewLC( file, KDefaultContentObject, EPeek ); + + HBufC* rightsIssuerBuf = HBufC::NewLC( urlLength ); // Content issuer max URL length + TPtr rightsIssuer(const_cast(rightsIssuerBuf->Ptr()), 0, urlLength); + + // Get value of rights-issuer header field + TInt error = content->GetStringAttribute( ERightsIssuerUrl, rightsIssuer ); + rightsIssuer.TrimAll(); + + rightsIssuer.Insert(0, _L("http://")); + + HBufC* finalUrl = rightsIssuer.AllocLC(); + + DRM::CDrmBrowserLauncher::LaunchUrlL(*finalUrl); + + CleanupStack::PopAndDestroy(3); // finalUrl, rightsIssuerBuf, content;*/ + } + +/* +void DRMEncryptorsetDRMClock() +{ + + double value1 = ui->lineEdit->text().toDouble(&bOK1); + double value2 = ui->lineEdit_2->text().toDouble(&bOK2); + + ui->lineEdit_3->setText(""); + + if(bOK1 && bOK2) + { + if(value2 != 0) + { + double result = value1 / value2; + ui->lineEdit_3->setText(QString::number(result)); + } + else + { + box.setText("Et voi jakaa nollalla"); + box.exec(); + } + } + else + { + box.setText("Virheellinen syöte"); + box.exec(); + } +} + + void DRMEncryptoronDateTimeChanged(const QDateTime & datetime ) + { + + } +*/ + +void DRMEncryptor::onTextChanged(const QString &) +{ + //ui->pushButton->setEnabled(ui->lineEdit->text() != "" && ui->lineEdit_2->text() != ""); +} + +DateTimeDialog::DateTimeDialog() + { + //iLayout = new QHBoxLayout; + QGridLayout *layout = new QGridLayout; + layout->setAlignment(Qt::AlignCenter); + setLayout(layout); + + iDateEdit = new QDateTimeEdit(QDate::currentDate()); + iDateEdit->setAlignment(Qt::AlignHCenter); + iDateEdit->setDisplayFormat("yyyy.mm.dd hh.mm.ss"); + iDateEdit->setWindowTitle("Set DRM Clock yyyy.MM.dd hh.mm.ss"); + QPushButton *okButton = new QPushButton("OK", this); + QPushButton *cancelButton = new QPushButton("Cancel", this); + + layout->addWidget(iDateEdit); + layout->addWidget(okButton); + layout->addWidget(cancelButton); + + connect(okButton, SIGNAL(clicked()), this, SLOT(setDRMClock())); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); + + //this->setLayout(iLayout); + okButton->show(); + cancelButton->show(); + this->show(); + } + +DateTimeDialog::~DateTimeDialog() + { + + } + +void DateTimeDialog::setDRMClock() + { + DRM::CDrmServiceApi* service = NULL; + TBuf<5> buf; + TRAPD(err, service = DRM::CDrmServiceApi::NewL()); + if(err!=KErrNone) + { + QMessageBox::information(this, tr("DRM Clock"),tr("Error creating CDrmServiceApi.")); + buf.AppendNum(err); + QString string((QChar*)buf.Ptr(),buf.Length()); + QMessageBox::information(this, tr("DRM Clock"),string); + delete service; // service + return; + } + + QString datetimeString = iDateEdit->dateTime().toString("yyyy.mm.dd hh.mm.ss"); + + // datetime in format YYYYMMDD:HHMMSS for TTime + datetimeString.remove(QChar('.')); + datetimeString.replace(" ", ":"); + datetimeString.append(".000000"); + + TPtrC datetimePtr(reinterpret_cast(datetimeString.constData())); + HBufC *datetimeBuf = NULL; + TBuf<5> errorBuf; + TRAPD(errorCode, datetimeBuf = datetimePtr.AllocL()); + if(errorCode!=KErrNone) + { + QMessageBox::information(this, tr("DRM Clock"),tr("Error in datetimePtr.AllocL.")); + errorBuf.AppendNum(errorCode); + QString string((QChar*)buf.Ptr(),buf.Length()); + QMessageBox::information(this, tr("DRM Clock"),string); + delete service; + delete datetimeBuf; + return; + } + + + TTime inputTime(*datetimeBuf); + TInt timezone = 0; + delete datetimeBuf; + + // Get secure time from service api to get timezone + DRMClock::ESecurityLevel level; + TInt error( KErrNone ); + + TTime currentTime; + error = service->GetSecureTime(currentTime, timezone, level); + + if(error != KErrNone) + { + return; + } + + error = service->UpdateSecureTime(inputTime, timezone); + + if(error != KErrNone) + { + return; + } + + delete service; + + QMessageBox::information(this, tr("DRM Clock"),tr("DRM Clock Set")); + } +