349 void CDRMMessageParser::HandleContentDataL() |
349 void CDRMMessageParser::HandleContentDataL() |
350 { |
350 { |
351 TPtrC8 res( NULL, 0 ); |
351 TPtrC8 res( NULL, 0 ); |
352 TBool cont( ETrue ); |
352 TBool cont( ETrue ); |
353 TInt remainder( 0 ); |
353 TInt remainder( 0 ); |
354 |
354 |
355 // Loop until |
355 // Loop until |
356 // - PrepareContentDataL leaves |
356 // - PrepareContentDataL leaves |
357 // - boundary end marker is found |
357 // - boundary end marker is found |
358 // - iInputBuffer is not updated anymore. |
358 // - iInputBuffer is not updated anymore. |
359 for ( PrepareContentDataL(); |
359 for ( PrepareContentDataL(); |
360 iInputBuffer.Length() && |
360 iInputBuffer.Length() && |
361 ( remainder != iInputBuffer.Length() ) && |
361 ( remainder != iInputBuffer.Length() ) && |
362 cont; |
362 cont; |
363 PrepareContentDataL() ) |
363 PrepareContentDataL() ) |
364 { |
364 { |
365 TInt pos = iInputBuffer.Find( *iBoundary ); |
365 TInt pos = iInputBuffer.Find( *iBoundary ); |
366 |
366 |
367 if ( pos >= 0 ) |
367 if ( pos >= 0 ) |
368 { |
368 { |
369 if ( pos < KBoundaryMarkLength + 1 ) |
369 if ( pos < KBoundaryMarkLength + 1 ) |
370 { |
370 { |
371 SetBrokenStateL( KDRMMessageMalformed ); |
371 SetBrokenStateL( KDRMMessageMalformed ); |
372 } |
372 } |
373 |
373 |
374 res.Set( iInputBuffer.Left( pos - KBoundaryMarkLength ) ); |
374 res.Set( iInputBuffer.Left( pos - KBoundaryMarkLength ) ); |
375 |
375 |
376 StripEndLineL( res ); |
376 StripEndLineL( res ); |
377 |
377 |
378 cont = EFalse; |
378 cont = EFalse; |
379 } |
379 } |
380 else |
380 else |
381 { |
381 { |
382 // All the data cannot be processed immediately, because |
382 // All the data cannot be processed immediately, because |
383 // there may be only a part of boundary string in this buffer |
383 // there may be only a part of boundary string in this buffer |
384 // and the rest is got from the next input descriptor. |
384 // and the rest is got from the next input descriptor. |
385 remainder = iBoundary->Length() + KBoundaryMarkLength + 1; |
385 remainder = iBoundary->Length() + KBoundaryMarkLength + 1; |
386 |
386 |
387 if ( iInputBuffer.Length() <= remainder ) |
387 if ( iInputBuffer.Length() <= remainder ) |
388 { |
388 { |
389 return; |
389 return; |
390 } |
390 } |
391 |
391 |
392 res.Set( iInputBuffer.Left( iInputBuffer.Length() - |
392 res.Set( iInputBuffer.Left( iInputBuffer.Length() - |
393 remainder ) ); |
393 remainder ) ); |
394 } |
394 } |
395 |
395 |
396 if ( iState & EBase64 ) |
396 if ( iState & EBase64 ) |
397 { |
397 { |
398 iUsedFromInput = HandleBase64DataL( res ); |
398 iUsedFromInput = HandleBase64DataL( res ); |
399 } |
399 } |
400 |
400 |
401 else |
401 else |
402 { |
402 { |
403 iUsedFromInput = res.Length(); |
403 iUsedFromInput = res.Length(); |
404 } |
404 } |
405 |
405 |
406 ProcessContentDataL( res ); |
406 ProcessContentDataL( res ); |
407 |
407 |
408 CompressInputBuffer(); |
408 CompressInputBuffer(); |
409 |
409 |
410 remainder = iInputBuffer.Length(); |
410 remainder = iInputBuffer.Length(); |
411 } |
411 } |
412 |
412 |
413 if ( !cont ) |
413 if ( !cont ) |
414 { |
414 { |
415 // Discard all the remaining data. |
415 // Discard all the remaining data. |
416 ClearBit( EReadingContentPart ); |
416 ClearBit( EReadingContentPart ); |
417 SetBit( EAllDone ); |
417 SetBit( EAllDone ); |
512 // ----------------------------------------------------------------------------- |
512 // ----------------------------------------------------------------------------- |
513 // |
513 // |
514 void CDRMMessageParser::FindBoundaryL() |
514 void CDRMMessageParser::FindBoundaryL() |
515 { |
515 { |
516 TPtrC8 line( NULL, 0 ); |
516 TPtrC8 line( NULL, 0 ); |
517 |
517 |
518 FOREVER |
518 FOREVER |
519 { |
519 { |
520 line.Set( GetLineL() ); |
520 line.Set( GetLineL() ); |
521 |
521 |
522 if ( line.Length() > KBoundaryMarkLength ) |
522 if ( line.Length() > KBoundaryMarkLength ) |
523 { |
523 { |
524 TInt size = 0; |
524 TInt size = 0; |
525 |
525 |
526 if ( line.Left( KBoundaryMarkLength ) == KBoundaryMark ) |
526 if ( line.Left( KBoundaryMarkLength ) == KBoundaryMark ) |
527 { |
527 { |
528 size = line.Length() - KBoundaryMarkLength - 1; |
528 size = line.Length() - KBoundaryMarkLength - 1; |
529 |
529 |
530 if ( line[ line.Length() - 2 ] == '\r' ) |
530 if ( line[ line.Length() - 2 ] == '\r' ) |
531 { |
531 { |
532 --size; |
532 --size; |
533 } |
533 } |
534 |
534 |
535 iBoundary = line.Mid( KBoundaryMarkLength, size ).AllocL(); |
535 iBoundary = line.Mid( KBoundaryMarkLength, size ).AllocL(); |
536 |
536 |
537 SetBit( EGotBoundary ); |
537 SetBit( EGotBoundary ); |
538 SetBit( EReadingHeaderPart ); |
538 SetBit( EReadingHeaderPart ); |
539 |
539 |
540 CompressInputBuffer(); |
540 CompressInputBuffer(); |
541 |
541 |
542 return; |
542 return; |
543 } |
543 } |
544 } |
544 } |
545 else |
545 else |
546 { |
546 { |
547 if ( line.Length() == 0 ) |
547 if ( line.Length() == 0 ) |
548 { |
548 { |
549 return; |
549 return; |
550 } |
550 } |
551 } |
551 } |
552 |
552 |
553 // Something else, not interested. |
553 // Something else, not interested. |
554 CompressInputBuffer(); |
554 CompressInputBuffer(); |
555 } |
555 } |
556 } |
556 } |
557 |
557 |
558 // ---------------------------------------------------------------------------- |
558 // ---------------------------------------------------------------------------- |
559 // CDRMMessageParser::ReadHeaderL |
559 // CDRMMessageParser::ReadHeaderL |
560 // The boundary is read and the following part is (should be) either a RO part |
560 // The boundary is read and the following part is (should be) either a RO part |
561 // or content part. The data is kept in iInputBuffer until the whole header |
561 // or content part. The data is kept in iInputBuffer until the whole header |
562 // part of the MIME header part is received. After plain "\r\n" line is |
562 // part of the MIME header part is received. After plain "\r\n" line is |
563 // received and content-type is defined, iState is updated. |
563 // received and content-type is defined, iState is updated. |
564 // ---------------------------------------------------------------------------- |
564 // ---------------------------------------------------------------------------- |
565 // |
565 // |
566 void CDRMMessageParser::ReadHeaderL() |
566 void CDRMMessageParser::ReadHeaderL() |
567 { |
567 { |
568 TPtrC8 line( NULL, 0 ); |
568 TPtrC8 line( NULL, 0 ); |
569 TPtrC8 ptr( NULL, 0 ); |
569 TPtrC8 ptr( NULL, 0 ); |
570 |
570 |
571 FOREVER |
571 FOREVER |
572 { |
572 { |
573 /////////////////////////////////////////////////////////////////// |
573 /////////////////////////////////////////////////////////////////// |
574 // Process the MIME header line-by-line. Process the lines if they |
574 // Process the MIME header line-by-line. Process the lines if they |
575 // contain some information that is found useful. Update the |
575 // contain some information that is found useful. Update the |
576 // internal state according to findings. |
576 // internal state according to findings. |
577 /////////////////////////////////////////////////////////////////// |
577 /////////////////////////////////////////////////////////////////// |
578 line.Set( GetLineL() ); |
578 line.Set( GetLineL() ); |
579 |
579 |
580 if ( line.Length() ) |
580 if ( line.Length() ) |
581 { |
581 { |
582 if ( line == KEndLine || line == KNewLine ) |
582 if ( line == KEndLine || line == KNewLine ) |
583 { |
583 { |
584 /////////////////////////////////////////////// |
584 /////////////////////////////////////////////// |
585 // MIME header is read. Check what to do next. |
585 // MIME header is read. Check what to do next. |
586 /////////////////////////////////////////////// |
586 /////////////////////////////////////////////// |
587 if ( iState & EGotContentType ) |
587 if ( iState & EGotContentType ) |
588 { |
588 { |
589 // Sanity check: Either EReadingRightsPart or |
589 // Sanity check: Either EReadingRightsPart or |
590 // EReadingContentPart must defined. |
590 // EReadingContentPart must defined. |
591 __ASSERT_DEBUG( ( iState & EReadingRightsPart ) || |
591 __ASSERT_DEBUG( ( iState & EReadingRightsPart ) || |
592 ( iState & EReadingContentPart ), |
592 ( iState & EReadingContentPart ), |
593 User::Invariant() ); |
593 User::Invariant() ); |
594 |
594 |
595 ClearBit( EReadingHeaderPart ); |
595 ClearBit( EReadingHeaderPart ); |
596 |
596 |
597 CompressInputBuffer(); |
597 CompressInputBuffer(); |
598 |
598 |
599 // Check which part was read. |
599 // Check which part was read. |
600 // If content part is being processed, some checkings |
600 // If content part is being processed, some checkings |
601 // need to be made. |
601 // need to be made. |
602 if ( iState & EReadingContentPart ) |
602 if ( iState & EReadingContentPart ) |
603 { |
603 { |
604 if ( iContentType->CompareF( KDRMContentType ) == 0 ) |
604 if ( iContentType->CompareF( KDRMContentType ) == 0 ) |
605 { |
605 { |
606 if ( iState & EGotRightsPart ) |
606 if ( iState & EGotRightsPart ) |
607 { |
607 { |
608 // CD DCF. |
608 // CD DCF. |
609 SetBrokenStateL( KErrCANotSupported ); |
609 SetBrokenStateL( KErrCANotSupported ); |
610 } |
610 } |
611 |
611 |
612 InitDCFBufferL(); |
612 InitDCFBufferL(); |
613 |
613 |
614 SetBit( EDCFFile ); |
614 SetBit( EDCFFile ); |
615 } |
615 } |
616 else |
616 else |
617 { |
617 { |
618 // Non-DCF FL content or normal CD content. |
618 // Non-DCF FL content or normal CD content. |
619 // Create or modify the CID, save the RO. |
619 // Create or modify the CID, save the RO. |
620 HandleFlContentL(); |
620 HandleFlContentL(); |
621 |
621 |
622 iDcfCreator->EncryptInitializeL( |
622 iDcfCreator->EncryptInitializeL( |
623 iOutputStream, |
623 iOutputStream, |
624 *iContentType, |
624 *iContentType, |
625 iRightsObject ); |
625 iRightsObject ); |
626 SetBit( EEncryptStreamOk ); |
626 SetBit( EEncryptStreamOk ); |
627 |
627 |
628 // The RO handle iRightsObject is kept in order |
628 // The RO handle iRightsObject is kept in order |
629 // to delete the rights in case of content |
629 // to delete the rights in case of content |
630 // encryption error. In that case, this will |
630 // encryption error. In that case, this will |
631 // generate unnecessary "RO Added / RO Deleted" |
631 // generate unnecessary "RO Added / RO Deleted" |
632 // notifications, but so what. "More correct" |
632 // notifications, but so what. "More correct" |
633 // way of doing would be modifying |
633 // way of doing would be modifying |
634 // EncryptInitialize not to |
634 // EncryptInitialize not to |
635 // save the RO, but then the key would have to |
635 // save the RO, but then the key would have to |
636 // be given to it by other means. Since we are |
636 // be given to it by other means. Since we are |
637 // not their "friend" class, we cannot access |
637 // not their "friend" class, we cannot access |
638 // their members, and making them to ask our |
638 // their members, and making them to ask our |
639 // members when doing EncryptInitialize/Finalize |
639 // members when doing EncryptInitialize/Finalize |
640 // might cause some problems perhaps. |
640 // might cause some problems perhaps. |
641 } |
641 } |
642 |
642 |
643 delete iContentType; |
643 delete iContentType; |
644 iContentType = NULL; |
644 iContentType = NULL; |
645 } |
645 } |
646 |
646 |
647 return; |
647 return; |
648 } |
648 } |
649 |
649 |
650 // Empty MIME header. |
650 // Empty MIME header. |
651 SetBrokenStateL( KDRMMessageMalformed ); |
651 SetBrokenStateL( KDRMMessageMalformed ); |
652 } |
652 } |
653 |
653 |
654 /////////////////////////////////// |
654 /////////////////////////////////// |
655 // Check the line for content-type. |
655 // Check the line for content-type. |
656 /////////////////////////////////// |
656 /////////////////////////////////// |
657 if ( line.Length() > KContentType().Length() && |
657 if ( line.Length() > KContentType().Length() && |
658 !( line.Left( KContentType().Length() ).CompareF( KContentType ) ) ) |
658 !( line.Left( KContentType().Length() ).CompareF( KContentType ) ) ) |
659 { |
659 { |
660 if ( iState & EGotContentType ) |
660 if ( iState & EGotContentType ) |
661 { |
661 { |
662 // Content-type given twice. |
662 // Content-type given twice. |
663 SetBrokenStateL( KDRMMessageMalformed ); |
663 SetBrokenStateL( KDRMMessageMalformed ); |
664 } |
664 } |
665 |
665 |
666 ptr.Set( HeaderValueL( line ) ); |
666 ptr.Set( HeaderValueL( line ) ); |
667 |
667 |
668 SetBit( EGotContentType ); |
668 SetBit( EGotContentType ); |
669 |
669 |
670 // Which part this is: rights or the actual content? |
670 // Which part this is: rights or the actual content? |
671 if ( ( ptr.CompareF( KDRMXMLRightsType ) == 0 ) || |
671 if ( ( ptr.CompareF( KDRMXMLRightsType ) == 0 ) || |
672 ( ptr.CompareF( KDRMWBXMLRightsType ) == 0 ) ) |
672 ( ptr.CompareF( KDRMWBXMLRightsType ) == 0 ) ) |
673 { |
673 { |
674 if ( iState & EGotRightsPart ) |
674 if ( iState & EGotRightsPart ) |
675 { |
675 { |
676 // Rights are given twice. |
676 // Rights are given twice. |
677 SetBrokenStateL( KDRMMessageMalformed ); |
677 SetBrokenStateL( KDRMMessageMalformed ); |
678 } |
678 } |
679 |
679 |
680 SetBit( EReadingRightsPart ); |
680 SetBit( EReadingRightsPart ); |
681 } |
681 } |
682 else |
682 else |
683 { |
683 { |
684 if ( iState & EGotContentPart ) |
684 if ( iState & EGotContentPart ) |
685 { |
685 { |
686 SetBrokenStateL( KDRMMessageMalformed ); |
686 SetBrokenStateL( KDRMMessageMalformed ); |
687 } |
687 } |
688 |
688 |
689 SetBit( EReadingContentPart ); |
689 SetBit( EReadingContentPart ); |
690 |
690 |
691 // Content-type is saved for future use. |
691 // Content-type is saved for future use. |
692 iContentType = ptr.AllocL(); |
692 iContentType = ptr.AllocL(); |
693 } |
693 } |
694 } |
694 } |
695 else |
695 else |
704 if ( iState & EGotContentEncoding ) |
704 if ( iState & EGotContentEncoding ) |
705 { |
705 { |
706 // Double line. |
706 // Double line. |
707 SetBrokenStateL( KDRMMessageMalformed ); |
707 SetBrokenStateL( KDRMMessageMalformed ); |
708 } |
708 } |
709 |
709 |
710 ptr.Set( HeaderValueL( line ) ); |
710 ptr.Set( HeaderValueL( line ) ); |
711 |
711 |
712 SetBit( EGotContentEncoding ); |
712 SetBit( EGotContentEncoding ); |
713 |
713 |
714 // Throw an error if content-transfer-encoding |
714 // Throw an error if content-transfer-encoding |
715 // is something we don't support. |
715 // is something we don't support. |
716 if ( ptr.CompareF( KEncoding8bit ) && |
716 if ( ptr.CompareF( KEncoding8bit ) && |
717 ptr.CompareF( KEncoding7bit) && |
717 ptr.CompareF( KEncoding7bit) && |
718 ptr.CompareF( KEncodingBinary ) ) |
718 ptr.CompareF( KEncodingBinary ) ) |
719 { |
719 { |
720 if ( ptr.CompareF( KEncodingBase64 ) ) |
720 if ( ptr.CompareF( KEncodingBase64 ) ) |
721 { |
721 { |
722 SetBrokenStateL( KErrCANotSupported ); |
722 SetBrokenStateL( KErrCANotSupported ); |
723 } |
723 } |
724 |
724 |
725 // So it has to be Base64. |
725 // So it has to be Base64. |
726 SetBit( EBase64 ); |
726 SetBit( EBase64 ); |
727 } |
727 } |
728 } |
728 } |
729 else |
729 else |
730 { |
730 { |
731 ////////////////////////////////////////// |
731 ////////////////////////////////////////// |
732 // Check the line for end boundary marker. |
732 // Check the line for end boundary marker. |
733 ////////////////////////////////////////// |
733 ////////////////////////////////////////// |
734 TBool final( EFalse ); |
734 TBool final( EFalse ); |
735 |
735 |
736 if ( IsBoundary( line, final ) ) |
736 if ( IsBoundary( line, final ) ) |
737 { |
737 { |
738 SetBrokenStateL( KDRMMessageMalformed ); |
738 SetBrokenStateL( KDRMMessageMalformed ); |
739 } |
739 } |
740 |
740 |
741 // Else: some X-field, parameter or something else. |
741 // Else: some X-field, parameter or something else. |
742 // The line is ignored. |
742 // The line is ignored. |
743 } |
743 } |
744 } |
744 } |
745 |
745 |
746 CompressInputBuffer(); |
746 CompressInputBuffer(); |
747 } |
747 } |
748 |
748 |
749 else |
749 else |
750 { |
750 { |
751 // No line available yet. |
751 // No line available yet. |
752 return; |
752 return; |
753 } |
753 } |
761 // |
761 // |
762 TPtrC8 CDRMMessageParser::GetLineL() |
762 TPtrC8 CDRMMessageParser::GetLineL() |
763 { |
763 { |
764 TInt pos = 0; |
764 TInt pos = 0; |
765 TPtrC8 res( NULL, 0 ); |
765 TPtrC8 res( NULL, 0 ); |
766 |
766 |
767 if ( iInputBuffer.Length() > iUsedFromInput ) |
767 if ( iInputBuffer.Length() > iUsedFromInput ) |
768 { |
768 { |
769 pos = iInputBuffer.Mid( iUsedFromInput ).Find( KNewLine ); |
769 pos = iInputBuffer.Mid( iUsedFromInput ).Find( KNewLine ); |
770 |
770 |
771 if ( pos >= 0 ) |
771 if ( pos >= 0 ) |
772 { |
772 { |
773 res.Set( iInputBuffer.Mid( iUsedFromInput, pos - iUsedFromInput + 1 ) ); |
773 res.Set( iInputBuffer.Mid( iUsedFromInput, pos - iUsedFromInput + 1 ) ); |
774 iUsedFromInput = pos + 1; |
774 iUsedFromInput = pos + 1; |
775 } |
775 } |
776 } |
776 } |
777 |
777 |
778 if ( res.Length() == 0 ) |
778 if ( res.Length() == 0 ) |
779 { |
779 { |
780 if ( iInputData.Length() ) |
780 if ( iInputData.Length() ) |
781 { |
781 { |
782 pos = iInputData.Find( KNewLine ); |
782 pos = iInputData.Find( KNewLine ); |
783 |
783 |
784 if ( pos < 0 ) |
784 if ( pos < 0 ) |
785 { |
785 { |
786 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() < |
786 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() < |
787 iInputData.Length() ) |
787 iInputData.Length() ) |
788 { |
788 { |
789 SetBrokenStateL( KDRMMessageMalformed ); |
789 SetBrokenStateL( KDRMMessageMalformed ); |
790 } |
790 } |
791 |
791 |
792 iInputBuffer.Append( iInputData ); |
792 iInputBuffer.Append( iInputData ); |
793 iInputData.Set( NULL, 0 ); |
793 iInputData.Set( NULL, 0 ); |
794 } |
794 } |
795 else |
795 else |
796 { |
796 { |
797 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() < |
797 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() < |
798 pos + 1 ) |
798 pos + 1 ) |
799 { |
799 { |
800 SetBrokenStateL( KDRMMessageMalformed ); |
800 SetBrokenStateL( KDRMMessageMalformed ); |
801 } |
801 } |
802 |
802 |
803 iInputBuffer.Append( iInputData.Left( pos + 1 ) ); |
803 iInputBuffer.Append( iInputData.Left( pos + 1 ) ); |
804 res.Set( iInputBuffer.Mid( iUsedFromInput ) ); |
804 res.Set( iInputBuffer.Mid( iUsedFromInput ) ); |
805 iUsedFromInput = iInputBuffer.Length(); |
805 iUsedFromInput = iInputBuffer.Length(); |
806 |
806 |
807 iInputData.Set( iInputData.Mid( pos + 1 ) ); |
807 iInputData.Set( iInputData.Mid( pos + 1 ) ); |
808 } |
808 } |
809 } |
809 } |
810 } |
810 } |
811 |
811 |
812 return res; |
812 return res; |
813 } |
813 } |
814 |
814 |
815 // ----------------------------------------------------------------------------- |
815 // ----------------------------------------------------------------------------- |
816 // CDRMMessageParser::HeaderValueL |
816 // CDRMMessageParser::HeaderValueL |
819 // |
819 // |
820 TPtrC8 CDRMMessageParser::HeaderValueL( const TDesC8& aLine ) |
820 TPtrC8 CDRMMessageParser::HeaderValueL( const TDesC8& aLine ) |
821 { |
821 { |
822 TInt pos( 0 ); |
822 TInt pos( 0 ); |
823 TPtrC8 res( NULL, 0 ); |
823 TPtrC8 res( NULL, 0 ); |
824 |
824 |
825 pos = aLine.Find( KColon ); |
825 pos = aLine.Find( KColon ); |
826 |
826 |
827 if ( pos <= 0 ) |
827 if ( pos <= 0 ) |
828 { |
828 { |
829 SetBrokenStateL( KDRMMessageMalformed ); |
829 SetBrokenStateL( KDRMMessageMalformed ); |
830 } |
830 } |
831 |
831 |
832 pos += 1; |
832 pos += 1; |
833 |
833 |
834 while ( pos < aLine.Length() && |
834 while ( pos < aLine.Length() && |
835 TChar( aLine[ pos ] ).IsSpace() ) |
835 TChar( aLine[ pos ] ).IsSpace() ) |
836 { |
836 { |
837 ++pos; |
837 ++pos; |
838 } |
838 } |
839 |
839 |
840 // Don't overindex. |
840 // Don't overindex. |
841 if ( pos == aLine.Length() ) |
841 if ( pos == aLine.Length() ) |
842 { |
842 { |
843 // Full of whitespaces. |
843 // Full of whitespaces. |
844 SetBrokenStateL( KDRMMessageMalformed ); |
844 SetBrokenStateL( KDRMMessageMalformed ); |
845 } |
845 } |
846 |
846 |
847 // Drop possible parameters. |
847 // Drop possible parameters. |
848 res.Set( aLine.Mid( pos ) ); |
848 res.Set( aLine.Mid( pos ) ); |
849 pos = res.Find( KSemiColon ); |
849 pos = res.Find( KSemiColon ); |
850 |
850 |
851 if ( pos >= 0 ) |
851 if ( pos >= 0 ) |
852 { |
852 { |
853 res.Set( res.Left( pos ) ); |
853 res.Set( res.Left( pos ) ); |
854 } |
854 } |
855 |
855 |
856 pos = res.Length(); |
856 pos = res.Length(); |
857 |
857 |
858 if ( !pos ) |
858 if ( !pos ) |
859 { |
859 { |
860 // Just parameters, no actual value. |
860 // Just parameters, no actual value. |
861 SetBrokenStateL( KDRMMessageMalformed ); |
861 SetBrokenStateL( KDRMMessageMalformed ); |
862 } |
862 } |
863 |
863 |
864 // This can't underflow, since otherwise there would be only |
864 // This can't underflow, since otherwise there would be only |
865 // semicolon & parameters (checked earlier). |
865 // semicolon & parameters (checked earlier). |
866 while( TChar( res[ pos - 1 ] ).IsSpace() ) |
866 while( TChar( res[ pos - 1 ] ).IsSpace() ) |
867 { |
867 { |
868 --pos; |
868 --pos; |
869 } |
869 } |
870 |
870 |
871 return res.Left( pos ); |
871 return res.Left( pos ); |
872 } |
872 } |
873 |
873 |
874 // ----------------------------------------------------------------------------- |
874 // ----------------------------------------------------------------------------- |
875 // CDRMMessageParser::CompressInputBuffer |
875 // CDRMMessageParser::CompressInputBuffer |
993 // CDRMMessageParser::IsBoundary |
993 // CDRMMessageParser::IsBoundary |
994 // Check if the given line is a boundary line. Also check if the line is |
994 // Check if the given line is a boundary line. Also check if the line is |
995 // the end boundary. |
995 // the end boundary. |
996 // ----------------------------------------------------------------------------- |
996 // ----------------------------------------------------------------------------- |
997 // |
997 // |
998 TBool CDRMMessageParser::IsBoundary( const TDesC8& aLine, TBool& aLast ) const |
998 TBool CDRMMessageParser::IsBoundary( const TDesC8& aLine, TBool& aLast ) const |
999 { |
999 { |
1000 TBool res = EFalse; |
1000 TBool res = EFalse; |
1001 |
1001 |
1002 __ASSERT_DEBUG( iBoundary, User::Invariant() ); |
1002 __ASSERT_DEBUG( iBoundary, User::Invariant() ); |
1003 |
1003 |
1004 if ( iState & EGotBoundary ) |
1004 if ( iState & EGotBoundary ) |
1005 { |
1005 { |
1006 if ( aLine.Length() > KBoundaryMarkLength + iBoundary->Length() ) |
1006 if ( aLine.Length() > KBoundaryMarkLength + iBoundary->Length() ) |
1007 { |
1007 { |
1008 TPtrC8 tmp( NULL, 0 ); |
1008 TPtrC8 tmp( NULL, 0 ); |
1009 |
1009 |
1010 if ( ( aLine.Left( KBoundaryMarkLength ) == KBoundaryMark ) && |
1010 if ( ( aLine.Left( KBoundaryMarkLength ) == KBoundaryMark ) && |
1011 ( aLine.Mid( KBoundaryMarkLength, iBoundary->Length() ). |
1011 ( aLine.Mid( KBoundaryMarkLength, iBoundary->Length() ). |
1012 Compare( *iBoundary ) == 0 ) ) |
1012 Compare( *iBoundary ) == 0 ) ) |
1013 { |
1013 { |
1014 res = ETrue; |
1014 res = ETrue; |
1015 |
1015 |
1016 tmp.Set( aLine.Right( aLine.Length() - |
1016 tmp.Set( aLine.Right( aLine.Length() - |
1017 KBoundaryMarkLength - |
1017 KBoundaryMarkLength - |
1018 iBoundary->Length() ) ); |
1018 iBoundary->Length() ) ); |
1019 |
1019 |
1020 if ( ( tmp.Length() >= KBoundaryMarkLength ) && |
1020 if ( ( tmp.Length() >= KBoundaryMarkLength ) && |
1021 ( tmp.Left( KBoundaryMarkLength ) == KBoundaryMark ) ) |
1021 ( tmp.Left( KBoundaryMarkLength ) == KBoundaryMark ) ) |
1022 { |
1022 { |
1023 aLast = ETrue; |
1023 aLast = ETrue; |
1024 } |
1024 } |
1025 } |
1025 } |
1026 } |
1026 } |
1027 } |
1027 } |
1028 |
1028 |
1029 return res; |
1029 return res; |
1030 } |
1030 } |
1031 |
1031 |
1032 // ----------------------------------------------------------------------------- |
1032 // ----------------------------------------------------------------------------- |
1033 // CDRMMessageParser::HandleFlContentL |
1033 // CDRMMessageParser::HandleFlContentL |
1067 } |
1067 } |
1068 } |
1068 } |
1069 |
1069 |
1070 // ----------------------------------------------------------------------------- |
1070 // ----------------------------------------------------------------------------- |
1071 // CDRMMessageParser::ProcessRightsData |
1071 // CDRMMessageParser::ProcessRightsData |
1072 // Process DRM message -style rights object and fetch it to iRightsObject if |
1072 // Process DRM message -style rights object and fetch it to iRightsObject if |
1073 // necessary. |
1073 // necessary. |
1074 // ----------------------------------------------------------------------------- |
1074 // ----------------------------------------------------------------------------- |
1075 // |
1075 // |
1076 void CDRMMessageParser::ProcessRightsDataL( |
1076 void CDRMMessageParser::ProcessRightsDataL( |
1077 const TDesC8& aCID, |
1077 const TDesC8& aCID, |
1078 const TDesC8& aData ) |
1078 const TDesC8& aData ) |
1079 { |
1079 { |
1080 __ASSERT_DEBUG( !iRightsObject, User::Invariant() ); |
1080 __ASSERT_DEBUG( !iRightsObject, User::Invariant() ); |
1081 |
1081 |
1082 TInt start = aData.Find(KRightsStartTag); |
1082 TInt start = aData.Find(KRightsStartTag); |
1083 TInt end = aData.LocateReverse('>'); |
1083 TInt end = aData.LocateReverse('>'); |
1084 |
1084 |
1085 if ( start >= 0 && end > start ) |
1085 if ( start >= 0 && end > start ) |
1086 { |
1086 { |
1087 TDRMUniqueID localID( 0 ); |
1087 TDRMUniqueID localID( 0 ); |
1088 CDrmRightsParser* parser( NULL ); |
1088 CDrmRightsParser* parser( NULL ); |
1089 CDRMAsset* asset( NULL ); |
1089 CDRMAsset* asset( NULL ); |
1090 RDRMRightsClient client; |
1090 RDRMRightsClient client; |
1091 TPtrC8 ptr( &aData[start], end - start + 1 ); |
1091 TPtrC8 ptr( &aData[start], end - start + 1 ); |
1092 TBuf8< KDCFKeySize > key; |
1092 TBuf8< KDCFKeySize > key; |
1093 key.SetLength(KDCFKeySize); |
1093 key.SetLength(KDCFKeySize); |
1094 RPointerArray< CDRMRights > rights; |
1094 RPointerArray< CDRMRights > rights; |
1095 |
1095 |
1096 TCleanupItem cleanup( DoResetAndDestroy, &rights ); |
1096 TCleanupItem cleanup( DoResetAndDestroy, &rights ); |
1097 CleanupStack::PushL( cleanup ); |
1097 CleanupStack::PushL( cleanup ); |
1098 |
1098 |
1099 User::LeaveIfError( client.Connect() ); |
1099 User::LeaveIfError( client.Connect() ); |
1100 CleanupClosePushL( client ); |
1100 CleanupClosePushL( client ); |
1101 |
1101 |
1102 parser = CDrmRightsParser::NewL(); |
1102 parser = CDrmRightsParser::NewL(); |
1103 CleanupStack::PushL( parser ); |
1103 CleanupStack::PushL( parser ); |
1104 |
1104 |
1105 parser->ParseL( ptr, rights ); |
1105 parser->ParseL( ptr, rights ); |
1106 |
1106 |
1107 if (rights.Count()==0) |
1107 if (rights.Count()==0) |
1108 { |
1108 { |
1109 User::Leave(KErrCorrupt); |
1109 User::Leave(KErrCorrupt); |
1110 } |
1110 } |
1111 |
1111 |
1112 client.GetRandomDataL(key); |
1112 client.GetRandomDataL(key); |
1113 |
1113 |
1114 User::LeaveIfError( client.AddRecord( |
1114 User::LeaveIfError( client.AddRecord( |
1115 key, |
1115 key, |
1116 rights[0]->GetPermission(), |
1116 rights[0]->GetPermission(), |
1117 aCID, |
1117 aCID, |
1118 localID) ); |
1118 localID) ); |
1119 |
1119 |
1120 iRightsObject = CDRMRights::NewL(); |
1120 iRightsObject = CDRMRights::NewL(); |
1121 |
1121 |
1122 asset = CDRMAsset::NewLC(); |
1122 asset = CDRMAsset::NewLC(); |
1123 asset->iUid = aCID.AllocL(); |
1123 asset->iUid = aCID.AllocL(); |
1124 |
1124 |
1125 iRightsObject->SetAssetL(*asset); |
1125 iRightsObject->SetAssetL(*asset); |
1126 iRightsObject->SetPermissionL(rights[0]->GetPermission()); |
1126 iRightsObject->SetPermissionL(rights[0]->GetPermission()); |
1127 |
1127 |
1128 CleanupStack::PopAndDestroy( 4 ); // asset, parser, client, rights |
1128 CleanupStack::PopAndDestroy( 4 ); // asset, parser, client, rights |
1129 } |
1129 } |
1130 else |
1130 else |
1131 { |
1131 { |
1132 SetBrokenStateL( KErrArgument ); |
1132 SetBrokenStateL( KErrArgument ); |
1133 } |
1133 } |
1134 } |
1134 } |
1135 |
1135 |
1136 // ----------------------------------------------------------------------------- |
1136 // ----------------------------------------------------------------------------- |
1137 // CDRMMessageParser::ProcessContentDataL |
1137 // CDRMMessageParser::ProcessContentDataL |
1138 // Handle DCF file's CID manipulation in "DCF in DRM message" case. |
1138 // Handle DCF file's CID manipulation in "DCF in DRM message" case. |
1139 // Send the data to EncryptUpdateL if encryption is needed. |
1139 // Send the data to EncryptUpdateL if encryption is needed. |
1140 // ----------------------------------------------------------------------------- |
1140 // ----------------------------------------------------------------------------- |
1141 // |
1141 // |
1142 void CDRMMessageParser::ProcessContentDataL( TPtrC8& aData ) |
1142 void CDRMMessageParser::ProcessContentDataL( TPtrC8& aData ) |
1143 { |
1143 { |
1163 // ----------------------------------------------------------------------------- |
1163 // ----------------------------------------------------------------------------- |
1164 // |
1164 // |
1165 TBool CDRMMessageParser::ValidB64CharL( const TUint8 aChar ) |
1165 TBool CDRMMessageParser::ValidB64CharL( const TUint8 aChar ) |
1166 { |
1166 { |
1167 // Allowed characters are '0'...'9', 'A'...'Z', 'a'...'z', '+', '/', '=' |
1167 // Allowed characters are '0'...'9', 'A'...'Z', 'a'...'z', '+', '/', '=' |
1168 if ( ( aChar >= 48 && aChar <= 57 ) || |
1168 if ( ( aChar >= 48 && aChar <= 57 ) || |
1169 ( aChar >= 65 && aChar <= 90 ) || |
1169 ( aChar >= 65 && aChar <= 90 ) || |
1170 ( aChar >= 97 && aChar <= 122 ) || |
1170 ( aChar >= 97 && aChar <= 122 ) || |
1171 ( aChar == 43 ) || |
1171 ( aChar == 43 ) || |
1172 ( aChar == 47 ) || |
1172 ( aChar == 47 ) || |
1173 ( aChar == 61 ) ) |
1173 ( aChar == 61 ) ) |
1174 { |
1174 { |
1175 return ETrue; |
1175 return ETrue; |
1176 } |
1176 } |
1177 |
1177 |
1178 if ( ( aChar != 0x0D ) && ( aChar != 0x0A ) ) |
1178 if ( ( aChar != 0x0D ) && ( aChar != 0x0A ) ) |
1179 { |
1179 { |
1180 SetBrokenStateL( KDRMMessageMalformed ); |
1180 SetBrokenStateL( KDRMMessageMalformed ); |
1181 } |
1181 } |
1182 |
1182 |
1183 return EFalse; |
1183 return EFalse; |
1184 } |
1184 } |
1185 |
1185 |
1186 // ----------------------------------------------------------------------------- |
1186 // ----------------------------------------------------------------------------- |
1187 // DRMCommon::ProcessMessage |
1187 // DRMCommon::ProcessMessage |
1188 // |
1188 // |
1189 // ----------------------------------------------------------------------------- |
1189 // ----------------------------------------------------------------------------- |
1190 EXPORT_C TInt CDRMMessageParser::ProcessMessage( |
1190 EXPORT_C TInt CDRMMessageParser::ProcessMessage( |
1191 HBufC8*& aDRMMessage) |
1191 HBufC8*& aDRMMessage) |
1192 { |
1192 { |
1193 TInt error( KErrNone ); |
1193 TInt error( KErrNone ); |
1194 TRAP( error, DoProcessMessageL( aDRMMessage ) ); |
1194 TRAP( error, DoProcessMessageL( aDRMMessage ) ); |
1195 |
1195 |
1196 return error; |
1196 return error; |
1197 } |
1197 } |
1198 |
1198 |
1199 // ----------------------------------------------------------------------------- |
1199 // ----------------------------------------------------------------------------- |
1200 // DRMCommon::ProcessRightsObject |
1200 // DRMCommon::ProcessRightsObject |
1201 // Processes a rights objects and saves it in the rights database. |
1201 // Processes a rights objects and saves it in the rights database. |
1202 // ----------------------------------------------------------------------------- |
1202 // ----------------------------------------------------------------------------- |
1203 EXPORT_C TInt CDRMMessageParser::ProcessRightsObject( |
1203 EXPORT_C TInt CDRMMessageParser::ProcessRightsObject( |
1204 const TDesC8& aRightsObject, |
1204 const TDesC8& aRightsObject, |
1205 RPointerArray<CDRMRights>& aRightsDetail) |
1205 RPointerArray<CDRMRights>& aRightsDetail) |
1206 { |
1206 { |
1207 TInt error( KErrNone ); |
1207 TInt error( KErrNone ); |
1208 TRAP( error, DoProcessRightsObjectL( aRightsObject, |
1208 TRAP( error, DoProcessRightsObjectL( aRightsObject, |
1209 aRightsDetail ) ); |
1209 aRightsDetail ) ); |
1210 |
1210 |
1211 return error; |
1211 return error; |
1212 } |
1212 } |
1213 |
1213 |
1214 void CDRMMessageParser::SetBit( TUint32 aBit ) |
1214 void CDRMMessageParser::SetBit( TUint32 aBit ) |
1215 { |
1215 { |
1216 iState |= aBit; |
1216 iState |= aBit; |
1217 } |
1217 } |
1218 |
1218 |
1219 void CDRMMessageParser::ClearBit( TUint32 aBit ) |
1219 void CDRMMessageParser::ClearBit( TUint32 aBit ) |
1220 { |
1220 { |
1221 iState &= ~aBit; |
1221 iState &= ~aBit; |
1222 } |
1222 } |
1223 |
1223 |
1224 void CDRMMessageParser::Reset() |
1224 void CDRMMessageParser::Reset() |
1225 { |
1225 { |
1226 delete iDCFBuffer; |
1226 delete iDCFBuffer; |
1227 iDCFBuffer = NULL; |
1227 iDCFBuffer = NULL; |
1228 |
1228 |
1229 delete iDcfCreator; |
1229 delete iDcfCreator; |
1230 iDcfCreator = NULL; |
1230 iDcfCreator = NULL; |
1231 |
1231 |
1232 delete iRightsData; |
1232 delete iRightsData; |
1233 iRightsData = NULL; |
1233 iRightsData = NULL; |
1234 |
1234 |
1235 delete iRightsObject; |
1235 delete iRightsObject; |
1236 iRightsObject = NULL; |
1236 iRightsObject = NULL; |
1237 |
1237 |
1238 delete iBoundary; |
1238 delete iBoundary; |
1239 iBoundary = NULL; |
1239 iBoundary = NULL; |
1240 |
1240 |
1241 delete iContentType; |
1241 delete iContentType; |
1242 iContentType = NULL; |
1242 iContentType = NULL; |
1243 |
1243 |
1244 iInputBuffer.SetLength( 0 ); |
1244 iInputBuffer.SetLength( 0 ); |
1245 |
1245 |
1246 iState = ESearchingBoundary; |
1246 iState = ESearchingBoundary; |
1247 iDCFHeaderSize[ 0 ] = KMaxTUint32; |
1247 iDCFHeaderSize[ 0 ] = KMaxTUint32; |
1248 iDCFHeaderSize[ 1 ] = KMaxTUint32; |
1248 iDCFHeaderSize[ 1 ] = KMaxTUint32; |
1249 } |
1249 } |
1250 |
1250 |
1252 { |
1252 { |
1253 TDeleteFileData fileData; |
1253 TDeleteFileData fileData; |
1254 RFileWriteStream output; |
1254 RFileWriteStream output; |
1255 RFile file; |
1255 RFile file; |
1256 TInt size( 0 ); |
1256 TInt size( 0 ); |
1257 |
1257 |
1258 User::LeaveIfError( fileData.aFs.Connect() ); |
1258 User::LeaveIfError( fileData.aFs.Connect() ); |
1259 CleanupClosePushL( fileData.aFs ); |
1259 CleanupClosePushL( fileData.aFs ); |
1260 |
1260 |
1261 TCleanupItem cleanup( DoDeleteFile, &fileData ); |
1261 TCleanupItem cleanup( DoDeleteFile, &fileData ); |
1262 CleanupStack::PushL( cleanup ); |
1262 CleanupStack::PushL( cleanup ); |
1263 |
1263 |
1264 #ifndef RD_MULTIPLE_DRIVE |
1264 #ifndef RD_MULTIPLE_DRIVE |
1265 |
1265 |
1266 User::LeaveIfError( output.Temp( fileData.aFs, |
1266 User::LeaveIfError( output.Temp( fileData.aFs, |
1267 KTempPath, |
1267 KTempPath, |
1268 fileData.aName, |
1268 fileData.aName, |
1269 EFileWrite ) ); |
1269 EFileWrite ) ); |
1270 |
1270 |
1271 #else //RD_MULTIPLE_DRIVE |
1271 #else //RD_MULTIPLE_DRIVE |
1272 |
1272 |
1273 TInt driveNumber( -1 ); |
1273 TInt driveNumber( -1 ); |
1274 TChar driveLetter; |
1274 TChar driveLetter; |
1275 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
1275 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
1276 fileData.aFs.DriveToChar( driveNumber, driveLetter ); |
1276 fileData.aFs.DriveToChar( driveNumber, driveLetter ); |
1277 |
1277 |
1278 TFileName tempPath; |
1278 TFileName tempPath; |
1279 tempPath.Format( KTempPath, (TUint)driveLetter ); |
1279 tempPath.Format( KTempPath, (TUint)driveLetter ); |
1280 |
1280 |
1281 User::LeaveIfError( output.Temp( fileData.aFs, |
1281 User::LeaveIfError( output.Temp( fileData.aFs, |
1282 tempPath, |
1282 tempPath, |
1283 fileData.aName, |
1283 fileData.aName, |
1284 EFileWrite ) ); |
1284 EFileWrite ) ); |
1285 |
1285 |
1286 #endif |
1286 #endif |
1287 |
1287 |
1288 CleanupClosePushL( output ); |
1288 CleanupClosePushL( output ); |
1289 |
1289 |
1290 InitializeMessageParserL( output ); |
1290 InitializeMessageParserL( output ); |
1291 ProcessMessageDataL( *aDRMMessage ); |
1291 ProcessMessageDataL( *aDRMMessage ); |
1292 FinalizeMessageParserL(); |
1292 FinalizeMessageParserL(); |
1293 |
1293 |
1294 CleanupStack::PopAndDestroy(); // output |
1294 CleanupStack::PopAndDestroy(); // output |
1295 |
1295 |
1296 User::LeaveIfError( file.Open( fileData.aFs, fileData.aName, EFileRead ) ); |
1296 User::LeaveIfError( file.Open( fileData.aFs, fileData.aName, EFileRead ) ); |
1297 CleanupClosePushL( file ); |
1297 CleanupClosePushL( file ); |
1298 |
1298 |
1299 User::LeaveIfError( file.Size( size ) ); |
1299 User::LeaveIfError( file.Size( size ) ); |
1300 |
1300 |
1301 if ( size > aDRMMessage->Des().MaxSize() ) |
1301 if ( size > aDRMMessage->Des().MaxSize() ) |
1302 { |
1302 { |
1303 HBufC8* tmp( NULL ); |
1303 HBufC8* tmp( NULL ); |
1304 |
1304 |
1305 delete aDRMMessage; |
1305 delete aDRMMessage; |
1306 aDRMMessage = NULL; |
1306 aDRMMessage = NULL; |
1307 |
1307 |
1308 tmp = HBufC8::NewLC( size ); |
1308 tmp = HBufC8::NewLC( size ); |
1309 TPtr8 data( tmp->Des() ); |
1309 TPtr8 data( tmp->Des() ); |
1310 |
1310 |
1311 User::LeaveIfError( file.Read( data ) ); |
1311 User::LeaveIfError( file.Read( data ) ); |
1312 CleanupStack::Pop(); // tmp |
1312 CleanupStack::Pop(); // tmp |
1313 |
1313 |
1314 aDRMMessage = tmp; |
1314 aDRMMessage = tmp; |
1315 } |
1315 } |
1316 else |
1316 else |
1317 { |
1317 { |
1318 TPtr8 data( aDRMMessage->Des() ); |
1318 TPtr8 data( aDRMMessage->Des() ); |
1319 User::LeaveIfError( file.Read( data ) ); |
1319 User::LeaveIfError( file.Read( data ) ); |
1320 } |
1320 } |
1321 |
1321 |
1322 CleanupStack::PopAndDestroy( 3 ); // file, cleanup, fileData.aFs |
1322 CleanupStack::PopAndDestroy( 3 ); // file, cleanup, fileData.aFs |
1323 } |
1323 } |
1324 |
1324 |
1325 void CDRMMessageParser::DoProcessRightsObjectL( |
1325 void CDRMMessageParser::DoProcessRightsObjectL( |
1326 const TDesC8& aRightsObject, |
1326 const TDesC8& aRightsObject, |
1327 RPointerArray<CDRMRights>& aRightsDetail ) |
1327 RPointerArray<CDRMRights>& aRightsDetail ) |
1328 { |
1328 { |
1329 CDrmRightsParser* parser = NULL; |
1329 CDrmRightsParser* parser = NULL; |
1330 TInt start; |
1330 TInt start; |
1331 TInt end; |
1331 TInt end; |
1332 TPtrC8 ptr(0, 0); |
1332 TPtrC8 ptr(0, 0); |
1333 |
1333 |
1334 start = aRightsObject.Find(KRightsStartTag); |
1334 start = aRightsObject.Find(KRightsStartTag); |
1335 end = aRightsObject.LocateReverse('>'); |
1335 end = aRightsObject.LocateReverse('>'); |
1336 |
1336 |
1337 TCleanupItem cleanup( DoResetAndDestroy, &aRightsDetail ); |
1337 TCleanupItem cleanup( DoResetAndDestroy, &aRightsDetail ); |
1338 CleanupStack::PushL( cleanup ); |
1338 CleanupStack::PushL( cleanup ); |
1339 |
1339 |
1340 if ( start != KErrNotFound && end != KErrNotFound ) |
1340 if ( start != KErrNotFound && end != KErrNotFound ) |
1341 { |
1341 { |
1342 // xml |
1342 // xml |
1343 parser = CDrmRightsParser::NewL(); |
1343 parser = CDrmRightsParser::NewL(); |
1344 CleanupStack::PushL(parser); |
1344 CleanupStack::PushL(parser); |
1345 |
1345 |
1346 ptr.Set(&aRightsObject[start], end - start + 1); |
1346 ptr.Set(&aRightsObject[start], end - start + 1); |
1347 |
1347 |
1348 parser->ParseAndStoreL(ptr, aRightsDetail); |
1348 parser->ParseAndStoreL(ptr, aRightsDetail); |
1349 |
1349 |
1350 if (aRightsDetail.Count() == 0) |
1350 if (aRightsDetail.Count() == 0) |
1351 { |
1351 { |
1352 User::Leave( KErrArgument ); |
1352 User::Leave( KErrArgument ); |
1353 } |
1353 } |
1354 |
1354 |
1355 CleanupStack::PopAndDestroy(); // parser |
1355 CleanupStack::PopAndDestroy(); // parser |
1356 } |
1356 } |
1357 else if (start == KErrNotFound ) |
1357 else if (start == KErrNotFound ) |
1358 { |
1358 { |
1359 // wbxml |
1359 // wbxml |
1360 parser = CDrmRightsParser::NewL(CDrmRightsParser::EWbxmlParser); |
1360 parser = CDrmRightsParser::NewL(CDrmRightsParser::EWbxmlParser); |
1361 CleanupStack::PushL(parser); |
1361 CleanupStack::PushL(parser); |
1362 |
1362 |
1363 parser->ParseAndStoreL(aRightsObject, aRightsDetail); |
1363 parser->ParseAndStoreL(aRightsObject, aRightsDetail); |
1364 if (aRightsDetail.Count() == 0) |
1364 if (aRightsDetail.Count() == 0) |
1365 { |
1365 { |
1366 User::Leave( KErrArgument ); |
1366 User::Leave( KErrArgument ); |
1367 } |
1367 } |
1368 |
1368 |
1369 CleanupStack::PopAndDestroy(); // parser |
1369 CleanupStack::PopAndDestroy(); // parser |
1370 } |
1370 } |
1371 else |
1371 else |
1372 { |
1372 { |
1373 User::Leave( KErrArgument ); |
1373 User::Leave( KErrArgument ); |
1374 } |
1374 } |
1375 |
1375 |
1376 CleanupStack::Pop(); // cleanup |
1376 CleanupStack::Pop(); // cleanup |
1377 } |
1377 } |
1378 |
1378 |
1379 void CDRMMessageParser::DeletePermission() |
1379 void CDRMMessageParser::DeletePermission() |
1380 { |
1380 { |
1381 if ( iRightsObject ) |
1381 if ( iRightsObject ) |
1382 { |
1382 { |
1383 if ( !( iState & EFLContent ) ) |
1383 if ( !( iState & EFLContent ) ) |
1384 { |
1384 { |
1385 HBufC8* URI = NULL; |
1385 HBufC8* URI = NULL; |
1386 |
1386 |
1387 if ( !( iRightsObject->GetContentURI( URI ) ) ) |
1387 if ( !( iRightsObject->GetContentURI( URI ) ) ) |
1388 { |
1388 { |
1389 __ASSERT_DEBUG( URI, User::Invariant() ); |
1389 __ASSERT_DEBUG( URI, User::Invariant() ); |
1390 |
1390 |
1391 RDRMRightsClient client; |
1391 RDRMRightsClient client; |
1392 |
1392 |
1393 TInt error = client.Connect(); |
1393 TInt error = client.Connect(); |
1394 |
1394 |
1395 if ( !error ) |
1395 if ( !error ) |
1396 { |
1396 { |
1397 // Don't care if it fails. |
1397 // Don't care if it fails. |
1398 client.DeleteDbEntry( *URI, iRightsObject->GetLocalID() ); |
1398 client.DeleteDbEntry( *URI, iRightsObject->GetLocalID() ); |
1399 |
1399 |
1400 client.Close(); |
1400 client.Close(); |
1401 } |
1401 } |
1402 |
1402 |
1403 delete URI; |
1403 delete URI; |
1404 URI = NULL; |
1404 URI = NULL; |
1405 } |
1405 } |
1406 } |
1406 } |
1407 |
1407 |
1408 delete iRightsObject; |
1408 delete iRightsObject; |
1409 iRightsObject = NULL; |
1409 iRightsObject = NULL; |
1410 } |
1410 } |
1411 } |
1411 } |
1412 |
1412 |
1413 void CDRMMessageParser::SetBrokenStateL( const TInt aError ) |
1413 void CDRMMessageParser::SetBrokenStateL( const TInt aError ) |
1414 { |
1414 { |
1415 SetBit( EBroken ); |
1415 SetBit( EBroken ); |
1416 DeletePermission(); |
1416 DeletePermission(); |
1417 |
1417 |
1418 User::Leave( aError ); |
1418 User::Leave( aError ); |
1419 } |
1419 } |
1420 |
1420 |
1421 void CDRMMessageParser::InitDCFBufferL() |
1421 void CDRMMessageParser::InitDCFBufferL() |
1422 { |
1422 { |
1483 { |
1483 { |
1484 ////////////////////////////////////////////////////////////////// |
1484 ////////////////////////////////////////////////////////////////// |
1485 // Modify ContentURI. |
1485 // Modify ContentURI. |
1486 ////////////////////////////////////////////////////////////////// |
1486 ////////////////////////////////////////////////////////////////// |
1487 FillDCFBufferL( aDCFData ); |
1487 FillDCFBufferL( aDCFData ); |
1488 |
1488 |
1489 if ( iDCFBuffer->Length() > 3 ) |
1489 if ( iDCFBuffer->Length() > 3 ) |
1490 { |
1490 { |
1491 TInt pos = 0; |
1491 TInt pos = 0; |
1492 TUint8* data = const_cast< TUint8* > ( iDCFBuffer->Ptr() ); |
1492 TUint8* data = const_cast< TUint8* > ( iDCFBuffer->Ptr() ); |
1493 |
1493 |
1494 if ( data[ 0 ] != 1 ) |
1494 if ( data[ 0 ] != 1 ) |
1495 { |
1495 { |
1496 SetBrokenStateL( KDRMMessageMalformed ); |
1496 SetBrokenStateL( KDRMMessageMalformed ); |
1497 } |
1497 } |
1498 |
1498 |
1499 // Cache the data until |
1499 // Cache the data until |
1500 // - version, |
1500 // - version, |
1501 // - ContentTypeLen, |
1501 // - ContentTypeLen, |
1502 // - ContentURILen, |
1502 // - ContentURILen, |
1503 // - ContentType and |
1503 // - ContentType and |
1504 // - ContentURI |
1504 // - ContentURI |
1505 // have been received. |
1505 // have been received. |
1506 pos = data[ 1 ] + 3; |
1506 pos = data[ 1 ] + 3; |
1507 if ( iDCFBuffer->Length() < pos + data[ 2 ] ) |
1507 if ( iDCFBuffer->Length() < pos + data[ 2 ] ) |
1508 { |
1508 { |
1509 return; |
1509 return; |
1510 } |
1510 } |
1511 |
1511 |
1512 // Sanity check. URI has to be more than four ("cid:") octets. |
1512 // Sanity check. URI has to be more than four ("cid:") octets. |
1513 if ( data[ 2 ] < 5 ) |
1513 if ( data[ 2 ] < 5 ) |
1514 { |
1514 { |
1515 SetBrokenStateL( KDRMMessageMalformed ); |
1515 SetBrokenStateL( KDRMMessageMalformed ); |
1516 } |
1516 } |
1517 |
1517 |
1518 if ( Mem::CompareF( &data[ pos ], |
1518 if ( Mem::CompareF( &data[ pos ], |
1519 KCIDStringLength, |
1519 KCIDStringLength, |
1520 KCIDString().Ptr(), |
1520 KCIDString().Ptr(), |
1521 KCIDStringLength ) == 0 ) |
1521 KCIDStringLength ) == 0 ) |
1522 { |
1522 { |
1523 // The data length doesn't change, so Mem::Copy() is safe. |
1523 // The data length doesn't change, so Mem::Copy() is safe. |
1524 Mem::Copy( &data[ pos ], |
1524 Mem::Copy( &data[ pos ], |
1525 KFLPrefix().Ptr(), |
1525 KFLPrefix().Ptr(), |
1526 KFLKPrefixLength ); |
1526 KFLKPrefixLength ); |
1527 |
1527 |
1528 iOutputStream.WriteL( iDCFBuffer->Left( pos + data[ 2 ] ) ); |
1528 iOutputStream.WriteL( iDCFBuffer->Left( pos + data[ 2 ] ) ); |
1529 |
1529 |
1530 doCommit = ETrue; |
1530 doCommit = ETrue; |
1531 |
1531 |
1532 CompressDCFBuffer( pos + data[ 2 ] ); |
1532 CompressDCFBuffer( pos + data[ 2 ] ); |
1533 |
1533 |
1534 SetBit( EDCFURIModified ); |
1534 SetBit( EDCFURIModified ); |
1535 } |
1535 } |
1536 else |
1536 else |
1537 { |
1537 { |
1538 // Discard the broken DCF |
1538 // Discard the broken DCF |
1551 // URI is now modified. Modify DCF headers if necessary. |
1551 // URI is now modified. Modify DCF headers if necessary. |
1552 ////////////////////////////////////////////////////////////////// |
1552 ////////////////////////////////////////////////////////////////// |
1553 if ( !( iState & EDCFHeadersModified ) ) |
1553 if ( !( iState & EDCFHeadersModified ) ) |
1554 { |
1554 { |
1555 FillDCFBufferL( aDCFData ); |
1555 FillDCFBufferL( aDCFData ); |
1556 |
1556 |
1557 // Figure out how much data there is in the header part and/or |
1557 // Figure out how much data there is in the header part and/or |
1558 // in the data part. |
1558 // in the data part. |
1559 if ( ( iDCFHeaderSize[ 0 ] == KMaxTUint32 ) && |
1559 if ( ( iDCFHeaderSize[ 0 ] == KMaxTUint32 ) && |
1560 ( iDCFHeaderSize[ 1 ] == KMaxTUint32 ) ) |
1560 ( iDCFHeaderSize[ 1 ] == KMaxTUint32 ) ) |
1561 { |
1561 { |
1562 TUint8 used( 0 ); |
1562 TUint8 used( 0 ); |
1563 |
1563 |
1564 // uintvar has 1...5 octets and we need two uintvars before |
1564 // uintvar has 1...5 octets and we need two uintvars before |
1565 // anything can be done. Still, there has to be at least |
1565 // anything can be done. Still, there has to be at least |
1566 // 12 octets of data in total to make the DCF legal. But here |
1566 // 12 octets of data in total to make the DCF legal. But here |
1567 // we just check the two uintvars. |
1567 // we just check the two uintvars. |
1568 if ( iDCFBuffer->Length() < 10 ) |
1568 if ( iDCFBuffer->Length() < 10 ) |
1569 { |
1569 { |
1570 // Not enough data yet. |
1570 // Not enough data yet. |
1571 // No need to flush aDCFData at this point, since it |
1571 // No need to flush aDCFData at this point, since it |
1572 // simply cannot contain anything at this point. |
1572 // simply cannot contain anything at this point. |
1573 __ASSERT_DEBUG( !aDCFData.Length(), User::Invariant() ); |
1573 __ASSERT_DEBUG( !aDCFData.Length(), User::Invariant() ); |
1574 break; |
1574 break; |
1575 } |
1575 } |
1576 |
1576 |
1577 // Read header field length & data length. |
1577 // Read header field length & data length. |
1578 for ( TUint8 count = 0; count < 2; ++count ) |
1578 for ( TUint8 count = 0; count < 2; ++count ) |
1579 { |
1579 { |
1580 TInt size( 0 ); |
1580 TInt size( 0 ); |
1581 |
1581 |
1582 TWspPrimitiveDecoder decoder( |
1582 TWspPrimitiveDecoder decoder( |
1583 iDCFBuffer->Mid( used ) ); |
1583 iDCFBuffer->Mid( used ) ); |
1584 size = decoder.UintVar( iDCFHeaderSize[ count ] ); |
1584 size = decoder.UintVar( iDCFHeaderSize[ count ] ); |
1585 |
1585 |
1586 // Sanity check. |
1586 // Sanity check. |
1587 if ( size < 1 || iDCFHeaderSize[ count ] >= KMaxTInt ) |
1587 if ( size < 1 || iDCFHeaderSize[ count ] >= KMaxTInt ) |
1588 { |
1588 { |
1589 SetBrokenStateL( KDRMMessageMalformed ); |
1589 SetBrokenStateL( KDRMMessageMalformed ); |
1590 } |
1590 } |
1591 |
1591 |
1592 used += size; |
1592 used += size; |
1593 } |
1593 } |
1594 |
1594 |
1595 CompressDCFBuffer( used ); |
1595 CompressDCFBuffer( used ); |
1596 } |
1596 } |
1597 else |
1597 else |
1598 { |
1598 { |
1599 // We know the original header size now. |
1599 // We know the original header size now. |
1600 // Wait until the whole header is read. |
1600 // Wait until the whole header is read. |
1601 if ( static_cast< TUint32 >( iDCFBuffer->Length() ) < |
1601 if ( static_cast< TUint32 >( iDCFBuffer->Length() ) < |
1602 iDCFHeaderSize[ 0 ] ) |
1602 iDCFHeaderSize[ 0 ] ) |
1603 { |
1603 { |
1604 if ( !aDCFData.Length() ) |
1604 if ( !aDCFData.Length() ) |
1605 { |
1605 { |
1606 // All available data is now processed. |
1606 // All available data is now processed. |
1611 { |
1611 { |
1612 TUint offset( 0 ); |
1612 TUint offset( 0 ); |
1613 TUint length( 0 ); |
1613 TUint length( 0 ); |
1614 HBufC8* newHeader = NULL; |
1614 HBufC8* newHeader = NULL; |
1615 |
1615 |
1616 if ( FindDCFHeader( KRightsIssuer, |
1616 if ( FindDCFHeader( KRightsIssuer, |
1617 offset, |
1617 offset, |
1618 length ) ) |
1618 length ) ) |
1619 { |
1619 { |
1620 // The header field exists. |
1620 // The header field exists. |
1621 TInt pos( 0 ); |
1621 TInt pos( 0 ); |
1622 TPtr8 trim( const_cast< TUint8* >( |
1622 TPtr8 trim( const_cast< TUint8* >( |
1623 iDCFBuffer->Ptr() ) + offset, |
1623 iDCFBuffer->Ptr() ) + offset, |
1624 length, |
1624 length, |
1625 length ); |
1625 length ); |
1626 |
1626 |
1627 iDCFHeaderSize[ 0 ] -= length; // remove old data. |
1627 iDCFHeaderSize[ 0 ] -= length; // remove old data. |
1628 |
1628 |
1629 // No colon, no header value. |
1629 // No colon, no header value. |
1630 pos = trim.Find( KColon ); |
1630 pos = trim.Find( KColon ); |
1631 if ( pos > 0 ) |
1631 if ( pos > 0 ) |
1632 { |
1632 { |
1633 trim.Set( const_cast< TUint8* >( trim.Ptr() ) + pos + 1, |
1633 trim.Set( const_cast< TUint8* >( trim.Ptr() ) + pos + 1, |
1634 trim.Length() - pos - 1, |
1634 trim.Length() - pos - 1, |
1635 trim.Length() - pos - 1 ); |
1635 trim.Length() - pos - 1 ); |
1636 |
1636 |
1637 // Skip whitespaces |
1637 // Skip whitespaces |
1638 trim.TrimLeft(); |
1638 trim.TrimLeft(); |
1639 trim.TrimRight(); |
1639 trim.TrimRight(); |
1640 |
1640 |
1641 if ( trim.Length() ) |
1641 if ( trim.Length() ) |
1642 { |
1642 { |
1643 // Something to process |
1643 // Something to process |
1644 newHeader = EncryptDCFFieldLC( trim ); |
1644 newHeader = EncryptDCFFieldLC( trim ); |
1645 |
1645 |
1646 iDCFHeaderSize[ 0 ] += KRightsIssuer().Length(); |
1646 iDCFHeaderSize[ 0 ] += KRightsIssuer().Length(); |
1647 iDCFHeaderSize[ 0 ] += newHeader->Length(); |
1647 iDCFHeaderSize[ 0 ] += newHeader->Length(); |
1648 iDCFHeaderSize[ 0 ] += 3; // ":" and CRLF |
1648 iDCFHeaderSize[ 0 ] += 3; // ":" and CRLF |
1649 } |
1649 } |
1650 } |
1650 } |
1651 } |
1651 } |
1652 |
1652 |
1653 // Write the uintvars to output. |
1653 // Write the uintvars to output. |
1654 for ( TUint8 loop = 0; loop < 2; ++loop ) |
1654 for ( TUint8 loop = 0; loop < 2; ++loop ) |
1655 { |
1655 { |
1656 TWspPrimitiveEncoder encoder; |
1656 TWspPrimitiveEncoder encoder; |
1657 HBufC8* var( encoder.UintVarL( iDCFHeaderSize[ loop ] ) ); |
1657 HBufC8* var( encoder.UintVarL( iDCFHeaderSize[ loop ] ) ); |
1658 |
1658 |
1659 CleanupStack::PushL( var ); |
1659 CleanupStack::PushL( var ); |
1660 |
1660 |
1661 iOutputStream.WriteL( *var ); |
1661 iOutputStream.WriteL( *var ); |
1662 |
1662 |
1663 CleanupStack::PopAndDestroy(); // var |
1663 CleanupStack::PopAndDestroy(); // var |
1664 } |
1664 } |
1665 |
1665 |
1666 // Dump the header data to output stream. |
1666 // Dump the header data to output stream. |
1667 iOutputStream.WriteL( iDCFBuffer->Left( offset ) ); |
1667 iOutputStream.WriteL( iDCFBuffer->Left( offset ) ); |
1668 |
1668 |
1669 if ( newHeader ) |
1669 if ( newHeader ) |
1670 { |
1670 { |
1671 iOutputStream.WriteL( KRightsIssuer ); |
1671 iOutputStream.WriteL( KRightsIssuer ); |
1672 iOutputStream.WriteL( KColon ); |
1672 iOutputStream.WriteL( KColon ); |
1673 iOutputStream.WriteL( *newHeader ); |
1673 iOutputStream.WriteL( *newHeader ); |
1674 |
1674 |
1675 CleanupStack::PopAndDestroy(); // newHeader |
1675 CleanupStack::PopAndDestroy(); // newHeader |
1676 newHeader = NULL; |
1676 newHeader = NULL; |
1677 |
1677 |
1678 iOutputStream.WriteL( KEndLine ); |
1678 iOutputStream.WriteL( KEndLine ); |
1679 } |
1679 } |
1680 |
1680 |
1681 iOutputStream.WriteL( |
1681 iOutputStream.WriteL( |
1682 iDCFBuffer->Right( iDCFBuffer->Length() - |
1682 iDCFBuffer->Right( iDCFBuffer->Length() - |
1683 offset - |
1683 offset - |
1684 length ) ); |
1684 length ) ); |
1685 |
1685 |
1686 doCommit = ETrue; |
1686 doCommit = ETrue; |
1687 |
1687 |
1688 CompressDCFBuffer( iDCFBuffer->Length() ); |
1688 CompressDCFBuffer( iDCFBuffer->Length() ); |
1689 SetBit( EDCFHeadersModified ); |
1689 SetBit( EDCFHeadersModified ); |
1690 } |
1690 } |
1691 } |
1691 } |
1692 } |
1692 } |
1768 } |
1768 } |
1769 else |
1769 else |
1770 { |
1770 { |
1771 pos += KEndLineLength; |
1771 pos += KEndLineLength; |
1772 } |
1772 } |
1773 |
1773 |
1774 if ( ( pos < aString.Length() ) || |
1774 if ( ( pos < aString.Length() ) || |
1775 ( des.Left( aString.Length() ).CompareF( aString ) != 0 ) ) |
1775 ( des.Left( aString.Length() ).CompareF( aString ) != 0 ) ) |
1776 { |
1776 { |
1777 // Skip the line, since this can't be the one we're looking for. |
1777 // Skip the line, since this can't be the one we're looking for. |
1778 des.Set( des.Right( des.Length() - |
1778 des.Set( des.Right( des.Length() - |
1779 pos ) ); |
1779 pos ) ); |
1780 } |
1780 } |
1781 else |
1781 else |
1782 { |
1782 { |
1783 aOffset = des.Ptr() - iDCFBuffer->Ptr(); |
1783 aOffset = des.Ptr() - iDCFBuffer->Ptr(); |
1784 aLength = pos; |
1784 aLength = pos; |
1785 |
1785 |
1786 return ETrue; |
1786 return ETrue; |
1787 } |
1787 } |
1788 } |
1788 } |
1789 |
1789 |
1790 // Never reached. |
1790 // Never reached. |
1791 return EFalse; |
1791 return EFalse; |
1792 } |
1792 } |
1793 |
1793 |
1794 void CDRMMessageParser::EnsureFLRightsExistL( |
1794 void CDRMMessageParser::EnsureFLRightsExistL( |
1795 RDRMRightsClient& aClient, |
1795 RDRMRightsClient& aClient, |
1796 CDRMRights** aOutput ) |
1796 CDRMRights** aOutput ) |
1797 { |
1797 { |
1798 HBufC8* cid( NULL ); |
1798 HBufC8* cid( NULL ); |
1799 CDRMRights* perm( NULL ); |
1799 CDRMRights* perm( NULL ); |
1800 RPointerArray< CDRMPermission > rights( 1 ); |
1800 RPointerArray< CDRMPermission > rights( 1 ); |
1801 |
1801 |
1802 TCleanupItem cleanup( DoResetAndDestroy2, &rights ); |
1802 TCleanupItem cleanup( DoResetAndDestroy2, &rights ); |
1803 CleanupStack::PushL( cleanup ); |
1803 CleanupStack::PushL( cleanup ); |
1804 |
1804 |
1805 User::LeaveIfError( aClient.ForwardLockURI( cid ) ); |
1805 User::LeaveIfError( aClient.ForwardLockURI( cid ) ); |
1806 CleanupStack::PushL( cid ); |
1806 CleanupStack::PushL( cid ); |
1807 |
1807 |
1808 TRAPD( error, aClient.GetDBEntriesL( *cid, rights ) ); |
1808 TRAPD( error, aClient.GetDBEntriesL( *cid, rights ) ); |
1809 |
1809 |
1810 if ( !error ) |
1810 if ( !error ) |
1811 { |
1811 { |
1812 ConvertPermissionL( perm, *( rights[ 0 ] ), *cid ); |
1812 ConvertPermissionL( perm, *( rights[ 0 ] ), *cid ); |
1813 // No need to pushl 'perm' into cleanup stack. |
1813 // No need to pushl 'perm' into cleanup stack. |
1814 } |
1814 } |
1815 else if ( error == KErrCANoRights ) |
1815 else if ( error == KErrCANoRights ) |
1816 { |
1816 { |
1817 HBufC8* fl( NULL ); |
1817 HBufC8* fl( NULL ); |
1818 RPointerArray< CDRMRights > rightslist( 1 ); |
1818 RPointerArray< CDRMRights > rightslist( 1 ); |
1819 |
1819 |
1820 TCleanupItem cleanup2( DoResetAndDestroy, &rightslist ); |
1820 TCleanupItem cleanup2( DoResetAndDestroy, &rightslist ); |
1821 CleanupStack::PushL( cleanup2 ); |
1821 CleanupStack::PushL( cleanup2 ); |
1822 |
1822 |
1823 fl = HBufC8::NewLC( KFLROSize + cid->Length() ); |
1823 fl = HBufC8::NewLC( KFLROSize + cid->Length() ); |
1824 |
1824 |
1825 *fl = KROPart1; |
1825 *fl = KROPart1; |
1826 fl->Des().Append( *cid ); |
1826 fl->Des().Append( *cid ); |
1827 fl->Des().Append( KROPart2 ); |
1827 fl->Des().Append( KROPart2 ); |
1828 |
1828 |
1829 User::LeaveIfError( ProcessRightsObject( *fl, rightslist ) ); |
1829 User::LeaveIfError( ProcessRightsObject( *fl, rightslist ) ); |
1830 |
1830 |
1831 CleanupStack::PopAndDestroy(); // fl |
1831 CleanupStack::PopAndDestroy(); // fl |
1832 |
1832 |
1833 perm = rightslist[ 0 ]; |
1833 perm = rightslist[ 0 ]; |
1834 rightslist.Remove( 0 ); |
1834 rightslist.Remove( 0 ); |
1835 |
1835 |
1836 CleanupStack::PopAndDestroy(); // cleanup2 |
1836 CleanupStack::PopAndDestroy(); // cleanup2 |
1837 |
1837 |
1838 error = KErrNone; |
1838 error = KErrNone; |
1839 } |
1839 } |
1840 |
1840 |
1841 CleanupStack::PopAndDestroy(); // cid |
1841 CleanupStack::PopAndDestroy(); // cid |
1842 |
1842 |
1843 if ( !error ) |
1843 if ( !error ) |
1844 { |
1844 { |
1845 // There is something. |
1845 // There is something. |