branch | RCL_3 |
changeset 294 | 039a3e647356 |
parent 268 | 345b1ca54e88 |
268:345b1ca54e88 | 294:039a3e647356 |
---|---|
537 if(ReadOnly() && aOperation == RFs::EFinal_RW) |
537 if(ReadOnly() && aOperation == RFs::EFinal_RW) |
538 { |
538 { |
539 User::Leave(KErrAccessDenied); //-- can't override RO flag |
539 User::Leave(KErrAccessDenied); //-- can't override RO flag |
540 } |
540 } |
541 |
541 |
542 (void)LocalDrive()->Finalise(ETrue); |
542 (void)LocalDrive()->Finalise(ETrue); |
543 |
543 |
544 if(aOperation == RFs::EFinal_RO) |
544 if(aOperation == RFs::EFinal_RO) |
545 { |
545 { |
546 SetReadOnly(ETrue); |
546 SetReadOnly(ETrue); |
547 return; |
547 return; |
548 } |
548 } |
549 |
549 |
550 return; |
550 return; |
551 } |
551 } |
552 |
552 |
553 if(Locked()) |
553 if(LockStatus() != 0) |
554 {//-- can't finalise the volume if it has opened disk access objects, like Format or RawAccess |
554 {//-- can't finalise the volume if it has opened objects and not in the consistent state. |
555 //-- Theoretically, we can finalise the mount if we have files opened only for read, but at present, |
|
556 //-- it's impossible to detect such situation. |
|
555 User::Leave(KErrInUse); |
557 User::Leave(KErrInUse); |
556 } |
558 } |
557 |
559 |
558 if(State() != EInit_R && State() != EInit_W) |
560 if(State() != EInit_R && State() != EInit_W) |
559 {//-- can't finalise the mount because it can be in an inconsistent state; e.g. corrupt. |
561 {//-- can't finalise the mount because it can be in an inconsistent state; e.g. corrupt. |
597 |
599 |
598 //-- finally, put the volume into RO mode if required |
600 //-- finally, put the volume into RO mode if required |
599 if(aOperation == RFs::EFinal_RO) |
601 if(aOperation == RFs::EFinal_RO) |
600 SetReadOnly(ETrue); |
602 SetReadOnly(ETrue); |
601 |
603 |
602 (void)LocalDrive()->Finalise(ETrue); |
|
603 |
|
604 SetState(EFinalised); |
604 SetState(EFinalised); |
605 } |
605 } |
606 |
606 |
607 |
607 |
608 //------------------------------------------------------------------------------------------------------------------- |
608 //------------------------------------------------------------------------------------------------------------------- |
1608 //----------------------------------------------------------------------------------------- |
1608 //----------------------------------------------------------------------------------------- |
1609 |
1609 |
1610 /** |
1610 /** |
1611 Overwrite as many contiguous file clusters as possible. |
1611 Overwrite as many contiguous file clusters as possible. |
1612 */ |
1612 */ |
1613 void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster, TUint aFlag) |
1613 void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster) |
1614 { |
1614 { |
1615 |
1615 |
1616 __PRINT(_L("CFatMountCB::DoWriteToClusterListL")); |
1616 __PRINT(_L("CFatMountCB::DoWriteToClusterListL")); |
1617 __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt)); |
1617 __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt)); |
1618 |
1618 |
1620 |
1620 |
1621 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1621 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1622 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1622 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1623 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1623 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1624 const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1624 const TInt writeLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1625 TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos; |
1625 TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos; |
1626 |
1626 |
1627 TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset, aFlag)); |
1627 TRAPD(r, iRawDisk->WriteL(dataStart,writeLength,aSrc,aMessage,anOffset)); |
1628 |
1628 |
1629 if(r == KErrNone) // Write succeded |
1629 if(r == KErrNone) // Write succeded |
1630 { |
1630 { |
1631 aPos.iPos+=writeLength; |
1631 aPos.iPos+=writeLength; |
1632 aPos.iCluster=endCluster; |
1632 aPos.iCluster=endCluster; |
1651 cluster--; |
1651 cluster--; |
1652 |
1652 |
1653 if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster)) |
1653 if((aPos.iPos != 0) && (badcluster == aPos.iCluster) && (aLastcluster == 0) && (aPos.iCluster == cluster)) |
1654 { //Copy the contents already present in this cluster to new cluster allocated. |
1654 { //Copy the contents already present in this cluster to new cluster allocated. |
1655 const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2()); |
1655 const TInt sizeToRead = aPos.iPos - ((aPos.iPos >> ClusterSizeLog2()) << ClusterSizeLog2()); |
1656 dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead)); |
1656 dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos((aPos.iPos - sizeToRead)); |
1657 |
1657 |
1658 |
1658 |
1659 //-- Allocate the buffer required to copy the contents from bad cluster |
1659 //-- Allocate the buffer required to copy the contents from bad cluster |
1660 RBuf8 clustBuf; |
1660 RBuf8 clustBuf; |
1661 CleanupClosePushL(clustBuf); |
1661 CleanupClosePushL(clustBuf); |
1680 |
1680 |
1681 FOREVER |
1681 FOREVER |
1682 { |
1682 { |
1683 //Calculate and copy the contents to new cluster. |
1683 //Calculate and copy the contents to new cluster. |
1684 aPos.iCluster = goodcluster; |
1684 aPos.iCluster = goodcluster; |
1685 dataStart = FAT().DataPositionInBytesL(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead); |
1685 dataStart = FAT().DataPositionInBytes(aPos.iCluster) + ClusterRelativePos(aPos.iPos - sizeToRead); |
1686 |
1686 |
1687 r = LocalDrive()->Write(dataStart, clustBuf); |
1687 r = LocalDrive()->Write(dataStart, clustBuf); |
1688 if(r == KErrNone) |
1688 if(r == KErrNone) |
1689 { // Copied contents to new cluster so fix up the chain and mark the cluster as bad. |
1689 { // Copied contents to new cluster so fix up the chain and mark the cluster as bad. |
1690 FAT().WriteL(goodcluster, FAT().ReadL(badcluster)); |
1690 FAT().WriteL(goodcluster, FAT().ReadL(badcluster)); |
1737 User::Leave(KErrCorrupt); |
1737 User::Leave(KErrCorrupt); |
1738 } |
1738 } |
1739 |
1739 |
1740 //----------------------------------------------------------------------------------------- |
1740 //----------------------------------------------------------------------------------------- |
1741 |
1741 |
1742 void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster, TUint aFlag) |
1742 void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster) |
1743 // |
1743 // |
1744 // Overwrite cluster list. |
1744 // Overwrite cluster list. |
1745 // |
1745 // |
1746 { |
1746 { |
1747 |
1747 |
1759 |
1759 |
1760 TUint offset=0; |
1760 TUint offset=0; |
1761 TInt previouscluster=0; |
1761 TInt previouscluster=0; |
1762 FOREVER |
1762 FOREVER |
1763 { |
1763 { |
1764 DoWriteToClusterListL(aPos,length-offset,aSrc,aMessage,anOffset+offset, previouscluster, aBadcluster, aGoodcluster, aFlag); |
1764 DoWriteToClusterListL(aPos,length-offset,aSrc,aMessage,anOffset+offset, previouscluster, aBadcluster, aGoodcluster); |
1765 if (offset == (aPos.iPos-startPos)) |
1765 if (offset == (aPos.iPos-startPos)) |
1766 continue; |
1766 continue; |
1767 offset=aPos.iPos-startPos; |
1767 offset=aPos.iPos-startPos; |
1768 __ASSERT_ALWAYS(aPos.iPos>startPos,User::Leave(KErrCorrupt)); |
1768 __ASSERT_ALWAYS(aPos.iPos>startPos,User::Leave(KErrCorrupt)); |
1769 previouscluster=aPos.iCluster; |
1769 previouscluster=aPos.iCluster; |
1774 } |
1774 } |
1775 } |
1775 } |
1776 |
1776 |
1777 //----------------------------------------------------------------------------------------- |
1777 //----------------------------------------------------------------------------------------- |
1778 |
1778 |
1779 void CFatMountCB::DoReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset, TUint aFlag) const |
1779 void CFatMountCB::DoReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset) const |
1780 // |
1780 // |
1781 // Read from as many contiguous file clusters as possible |
1781 // Read from as many contiguous file clusters as possible |
1782 // |
1782 // |
1783 { |
1783 { |
1784 |
1784 |
1788 |
1788 |
1789 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1789 const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos); |
1790 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1790 const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1; |
1791 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1791 const TInt clusterListLen=FAT().CountContiguousClustersL(aPos.iCluster,endCluster,maxClusters); |
1792 const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1792 const TInt readLength=Min(aLength,(clusterListLen<<ClusterSizeLog2())-clusterRelativePos); |
1793 const TInt64 dataStart=FAT().DataPositionInBytesL(aPos.iCluster)+clusterRelativePos; |
1793 const TInt64 dataStart=FAT().DataPositionInBytes(aPos.iCluster)+clusterRelativePos; |
1794 |
1794 |
1795 TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset, aFlag)); |
1795 TRAPD(r, iRawDisk->ReadL(dataStart,readLength,aTrg,aMessage,anOffset)); |
1796 |
1796 |
1797 if(r == KErrNone) // Read succeded |
1797 if(r == KErrNone) // Read succeded |
1798 { |
1798 { |
1799 aPos.iPos+=readLength; |
1799 aPos.iPos+=readLength; |
1800 aPos.iCluster=endCluster; |
1800 aPos.iCluster=endCluster; |
1815 User::Leave(KErrCorrupt); |
1815 User::Leave(KErrCorrupt); |
1816 } |
1816 } |
1817 |
1817 |
1818 //----------------------------------------------------------------------------------------- |
1818 //----------------------------------------------------------------------------------------- |
1819 |
1819 |
1820 void CFatMountCB::ReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset, TUint aFlag) const |
1820 void CFatMountCB::ReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset) const |
1821 // |
1821 // |
1822 // Read from cluster list |
1822 // Read from cluster list |
1823 // |
1823 // |
1824 { |
1824 { |
1825 |
1825 |
1835 } |
1835 } |
1836 |
1836 |
1837 TInt offset=0; |
1837 TInt offset=0; |
1838 FOREVER |
1838 FOREVER |
1839 { |
1839 { |
1840 DoReadFromClusterListL(aPos,aLength-offset,aTrg,aMessage,anOffset+offset, aFlag); |
1840 DoReadFromClusterListL(aPos,aLength-offset,aTrg,aMessage,anOffset+offset); |
1841 offset=aPos.iPos-startPos; |
1841 offset=aPos.iPos-startPos; |
1842 if ((offset<aLength)) |
1842 if ((offset<aLength)) |
1843 { |
1843 { |
1844 __ASSERT_ALWAYS(FAT().GetNextClusterL(aPos.iCluster),User::Leave(KErrCorrupt)); |
1844 __ASSERT_ALWAYS(FAT().GetNextClusterL(aPos.iCluster),User::Leave(KErrCorrupt)); |
1845 } |
1845 } |
3152 |
3152 |
3153 if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster) |
3153 if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster) |
3154 User::Leave(KErrCorrupt); |
3154 User::Leave(KErrCorrupt); |
3155 |
3155 |
3156 TBuf8<sizeof(TCheckedUid)> uidBuf; |
3156 TBuf8<sizeof(TCheckedUid)> uidBuf; |
3157 iRawDisk->ReadCachedL(FAT().DataPositionInBytesL(aCluster),sizeof(TCheckedUid),uidBuf); |
3157 iRawDisk->ReadCachedL(FAT().DataPositionInBytes(aCluster),sizeof(TCheckedUid),uidBuf); |
3158 __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed)); |
3158 __ASSERT_DEBUG(uidBuf.Length()==sizeof(TCheckedUid),Fault(EFatReadUidFailed)); |
3159 TCheckedUid uid(uidBuf); |
3159 TCheckedUid uid(uidBuf); |
3160 anEntry.iType=uid.UidType(); |
3160 anEntry.iType=uid.UidType(); |
3161 } |
3161 } |
3162 |
3162 |
3228 if (pos<(clusterListLen<<ClusterSizeLog2())) |
3228 if (pos<(clusterListLen<<ClusterSizeLog2())) |
3229 { |
3229 { |
3230 // Read the remaining length or the entire cluster block whichever is smaller |
3230 // Read the remaining length or the entire cluster block whichever is smaller |
3231 TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos); |
3231 TInt readLength = Min(aLength-readTotal,(clusterListLen<<ClusterSizeLog2())-pos); |
3232 __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed)); |
3232 __ASSERT_DEBUG(readLength>0,Fault(EReadFileSectionFailed)); |
3233 TInt64 dataAddress=(FAT().DataPositionInBytesL(cluster))+pos; |
3233 TInt64 dataAddress=(FAT().DataPositionInBytes(cluster))+pos; |
3234 iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal, 0); |
3234 iRawDisk->ReadL(dataAddress,readLength,aTrg,aMessage,readTotal); |
3235 readTotal += readLength; |
3235 readTotal += readLength; |
3236 |
3236 |
3237 if (readTotal == aLength) |
3237 if (readTotal == aLength) |
3238 return; |
3238 return; |
3239 |
3239 |
3257 void CFatMountCB::RawReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt anOffset,const RMessagePtr2& aMessage) const |
3257 void CFatMountCB::RawReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,TInt anOffset,const RMessagePtr2& aMessage) const |
3258 // |
3258 // |
3259 // Read aLength of data from disk directly to thread relative descriptor |
3259 // Read aLength of data from disk directly to thread relative descriptor |
3260 // |
3260 // |
3261 { |
3261 { |
3262 iRawDisk->ReadL(aPos,aLength,aTrg,aMessage,anOffset, 0); |
3262 iRawDisk->ReadL(aPos,aLength,aTrg,aMessage,anOffset); |
3263 } |
3263 } |
3264 |
3264 |
3265 //----------------------------------------------------------------------------------------- |
3265 //----------------------------------------------------------------------------------------- |
3266 |
3266 |
3267 void CFatMountCB::RawWriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt anOffset,const RMessagePtr2& aMessage) |
3267 void CFatMountCB::RawWriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,TInt anOffset,const RMessagePtr2& aMessage) |
3272 CheckWritableL(); |
3272 CheckWritableL(); |
3273 |
3273 |
3274 //-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case. |
3274 //-- check if we are trying to write to the FAT directly and wait until FAT scan thread finishes in this case. |
3275 FAT().RequestRawWriteAccess(aPos, aLength); |
3275 FAT().RequestRawWriteAccess(aPos, aLength); |
3276 |
3276 |
3277 iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset, 0); |
3277 iRawDisk->WriteL(aPos,aLength,aSrc,aMessage,anOffset); |
3278 //-- Note: FAT directory cache will be invalidated in MountL() |
3278 //-- Note: FAT directory cache will be invalidated in MountL() |
3279 } |
3279 } |
3280 |
3280 |
3281 //----------------------------------------------------------------------------------------- |
3281 //----------------------------------------------------------------------------------------- |
3282 /** |
3282 /** |
3432 |
3432 |
3433 //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos); |
3433 //__PRINT2(_L("CFatMountCB::MakeLinAddrL, cl:%d, pos:%d"), aPos.iCluster, aPos.iPos); |
3434 if (!IsRootDir(aPos)) |
3434 if (!IsRootDir(aPos)) |
3435 { |
3435 { |
3436 TInt relPos=ClusterRelativePos(aPos.iPos); |
3436 TInt relPos=ClusterRelativePos(aPos.iPos); |
3437 return FAT().DataPositionInBytesL(aPos.iCluster)+relPos; |
3437 return FAT().DataPositionInBytes(aPos.iCluster)+relPos; |
3438 } |
3438 } |
3439 if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()) |
3439 if (aPos.iPos+StartOfRootDirInBytes()>=RootDirEnd()) |
3440 User::Leave(KErrDirFull); // Past last root dir entry |
3440 User::Leave(KErrDirFull); // Past last root dir entry |
3441 return StartOfRootDirInBytes()+aPos.iPos; |
3441 return StartOfRootDirInBytes()+aPos.iPos; |
3442 } |
3442 } |
4068 r = LocalDrive()->Caps(caps); |
4068 r = LocalDrive()->Caps(caps); |
4069 if ( r != KErrNone ) |
4069 if ( r != KErrNone ) |
4070 User::LeaveIfError(r); |
4070 User::LeaveIfError(r); |
4071 if ( caps().iType&EMediaRam ) |
4071 if ( caps().iType&EMediaRam ) |
4072 { |
4072 { |
4073 realPosition = FAT().DataPositionInBytesL( aPos.iCluster ); |
4073 realPosition = FAT().DataPositionInBytes( aPos.iCluster ); |
4074 aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2()); |
4074 aPos.iCluster = I64LOW((realPosition - aInfo.iStartBlockAddress)>>ClusterSizeLog2()); |
4075 blockMapEntry.SetStartBlock( aPos.iCluster ); |
4075 blockMapEntry.SetStartBlock( aPos.iCluster ); |
4076 } |
4076 } |
4077 else |
4077 else |
4078 blockMapEntry.SetStartBlock( aPos.iCluster - 2); |
4078 blockMapEntry.SetStartBlock( aPos.iCluster - 2); |