417 return r; |
417 return r; |
418 |
418 |
419 return(aRequest->Drive()->CheckMount()); |
419 return(aRequest->Drive()->CheckMount()); |
420 } |
420 } |
421 |
421 |
422 |
422 //----------------------------------------------------------------------------- |
423 LOCAL_C TInt DoMountFsInitialise(CFsRequest* aRequest,TDesC& aFsName,TBool aIsExtension,TBool aIsSync) |
423 /** |
424 // |
424 Read optional drive setting from estart.txt that may contain additional drive attributes, like KDRIVEATTLOGICALLYREMOVABLE, KDRIVEATTHIDDEN |
425 // |
425 and process them. |
426 // |
426 This may lead to addding/removing some attributes to the existing drive's ones. |
427 { |
427 N.B Implementation of this is quite strange, it knows only about 2 specific additional attributes.. |
428 if (!KCapFsMountFileSystem.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount File System"))) |
428 |
429 return KErrPermissionDenied; |
429 @param aDrvNum drive number |
430 |
430 @param aDrvAtt in: original drive attributes, out: altered drive attributes. |
431 TInt r=ValidateDrive(aRequest->Message().Int1(),aRequest); |
431 |
432 if(r!=KErrNone) |
432 |
433 return(r); |
433 */ |
434 |
434 static void DoProcessAdditionalDriveAttributes(TInt aDrvNum, TUint& aDrvAtt) |
435 TBool driveThreadExists = FsThreadManager::IsDriveAvailable(aRequest->DriveNumber(), ETrue); |
435 { |
436 if(driveThreadExists) |
436 TUint add_Att= 0; //-- additional drive attributes to be added |
437 { |
437 TUint remove_Att = 0; //-- additional drive attributes to be removed |
438 // A drive thread already exists for this drive.This could be because a filesystem |
438 |
439 // is already mounted, or a proxy drive is loaded. Check the mount to be sure... |
|
440 if(aRequest->Drive()->GetFSys()) |
|
441 { |
|
442 // Yes, a mount already exists so we can't mount another one! |
|
443 return(KErrAccessDenied); |
|
444 } |
|
445 |
|
446 __ASSERT_DEBUG(IsProxyDrive(aRequest->DriveNumber()), User::Panic(_L("Bad thread state - No Mount or Proxy Drive Exists!"), -999)); |
|
447 } |
|
448 |
|
449 // ...therefore no drive thread can be present |
|
450 __ASSERT_DEBUG(!&aRequest->Drive()->FSys(),Fault(EMountFileSystemFSys)); |
|
451 |
|
452 if(aRequest->Drive()->IsSubsted()) |
|
453 return(KErrAccessDenied); |
|
454 |
|
455 CFileSystem* pF = GetFileSystem(aFsName); |
|
456 |
|
457 if (pF == NULL) |
|
458 return(KErrNotFound); |
|
459 |
|
460 // Check that if the drive is a proxy drive (not using TBusLocalDrive) then the filesystem supports these... |
|
461 TInt driveNumber = aRequest->DriveNumber(); |
|
462 if(IsProxyDrive(driveNumber)) |
|
463 { |
|
464 if(!pF->IsProxyDriveSupported()) |
|
465 return KErrNotSupported; |
|
466 |
|
467 r = LocalDrives::SetupMediaChange(driveNumber); |
|
468 } |
|
469 |
|
470 TDriveInfo driveInfo; |
|
471 driveInfo.iDriveAtt=0; |
|
472 pF->DriveInfo(driveInfo, driveNumber); |
|
473 if(!driveInfo.iDriveAtt) |
|
474 r = KErrArgument; |
|
475 |
|
476 if(r == KErrNone && !driveThreadExists) |
|
477 { |
|
478 // determine whether file system synchronous or not not by flag passed in |
|
479 r=FsThreadManager::InitDrive(driveNumber, aIsSync); |
|
480 } |
|
481 |
|
482 if(r!=KErrNone) |
|
483 return(r); |
|
484 |
|
485 |
|
486 //-- let TDrive object know if the drive is synchronous |
|
487 aRequest->Drive()->SetSynchronous(aIsSync); |
|
488 |
|
489 if(aIsExtension && aRequest->Message().Ptr2()!=NULL) |
|
490 { |
|
491 TFullName extName; |
|
492 r = aRequest->Read(KMsgPtr2,extName); |
|
493 if (r!=KErrNone) |
|
494 return r; |
|
495 CProxyDriveFactory* pE=GetExtension(extName); |
|
496 if(pE==NULL) |
|
497 return(KErrNotFound); |
|
498 r=aRequest->Drive()->MountExtension(pE,ETrue); |
|
499 if(r!=KErrNone) |
|
500 return(r); |
|
501 } |
|
502 |
|
503 TInt32 newAtt = 0; |
|
504 TInt32 oldAtt = 0; |
|
505 _LIT8( KAddAtt, "AddDriveAttributes"); |
439 _LIT8( KAddAtt, "AddDriveAttributes"); |
506 _LIT8( KRemoveAtt, "RemoveDriveAttributes"); |
440 _LIT8( KRemoveAtt, "RemoveDriveAttributes"); |
507 _LIT8( KLogicallyRemovableAtt, "KDRIVEATTLOGICALLYREMOVABLE"); |
441 _LIT8( KLogicallyRemovableAtt, "KDRIVEATTLOGICALLYREMOVABLE"); |
508 _LIT8( KHiddenAtt, "KDRIVEATTHIDDEN"); |
442 _LIT8( KHiddenAtt, "KDRIVEATTHIDDEN"); |
509 _LIT8( KLogicallyRemovableAttHex, "0X200"); |
443 _LIT8( KLogicallyRemovableAttHex, "0X200"); |
510 _LIT8( KHiddenAttHex, "0X400"); |
444 _LIT8( KHiddenAttHex, "0X400"); |
511 TBuf8<0x1000> addbuf; |
445 |
512 addbuf.FillZ(); |
446 TBuf8<0x100> buf; |
513 TBuf8<0x1000> removebuf; |
|
514 removebuf.FillZ(); |
|
515 TInt drive = aRequest->Message().Int1(); |
|
516 _LIT8(KLitSectionNameDrive,"Drive%C"); |
|
517 TBuf8<8> sectionName; |
447 TBuf8<8> sectionName; |
518 sectionName.Format(KLitSectionNameDrive, 'A' + drive); |
448 F32Properties::GetDriveSection(aDrvNum, sectionName); |
519 F32Properties::GetString(sectionName, KAddAtt, addbuf); |
449 |
520 F32Properties::GetString(sectionName, KRemoveAtt, removebuf); //oldAtt now contains value of the attributes to be removed from iDriveAtt. |
450 //-- read and parse "AddDriveAttributes" string |
521 |
451 buf.Zero(); |
522 if(addbuf.Length() != 0) |
452 TBool bSectFound = F32Properties::GetString(sectionName, KAddAtt, buf); |
|
453 |
|
454 if(bSectFound && buf.Length() > 0) |
523 { |
455 { |
524 TInt pos = 0; |
456 TInt pos = 0; |
525 TInt length = 0; |
457 TInt length = 0; |
526 TPtrC8 ptr; |
458 TPtrC8 ptr; |
527 TBool endOfFlag=EFalse; |
459 TBool endOfFlag=EFalse; |
528 |
460 |
529 while(!endOfFlag) |
461 while(!endOfFlag) |
530 { |
462 { |
531 ptr.Set(addbuf.Mid(pos)); |
463 ptr.Set(buf.Mid(pos)); |
532 length = ptr.Locate(','); |
464 length = ptr.Locate(','); |
533 |
465 |
534 if(length == KErrNotFound) |
466 if(length == KErrNotFound) |
535 { |
467 { |
536 endOfFlag = ETrue; |
468 endOfFlag = ETrue; |
537 } |
469 } |
538 else{ |
470 else{ |
539 ptr.Set(ptr.Left(length)); |
471 ptr.Set(ptr.Left(length)); |
540 pos += (length +1); |
472 pos += (length +1); |
541 } |
473 } |
542 |
474 |
543 if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound)) |
475 if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound)) |
544 newAtt |= KDriveAttLogicallyRemovable; |
476 add_Att |= KDriveAttLogicallyRemovable; |
545 if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound)) |
477 |
546 newAtt |= KDriveAttHidden; |
478 if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound)) |
547 |
479 add_Att |= KDriveAttHidden; |
548 } |
480 |
549 } |
481 }//while(!endOfFlag) |
550 |
482 } |
551 if(removebuf.Length() != 0) |
483 |
|
484 //-- read and parse "RemoveDriveAttributes" string |
|
485 buf.Zero(); |
|
486 bSectFound = F32Properties::GetString(sectionName, KRemoveAtt, buf); //oldAtt now contains value of the attributes to be removed from iDriveAtt. |
|
487 |
|
488 if(bSectFound && buf.Length() > 0) |
552 { |
489 { |
553 TInt pos = 0; |
490 TInt pos = 0; |
554 TInt length = 0; |
491 TInt length = 0; |
555 TPtrC8 ptr; |
492 TPtrC8 ptr; |
556 TBool endOfFlag=EFalse; |
493 TBool endOfFlag=EFalse; |
557 |
494 |
558 while(!endOfFlag) |
495 while(!endOfFlag) |
559 { |
496 { |
560 ptr.Set(removebuf.Mid(pos)); |
497 ptr.Set(buf.Mid(pos)); |
561 length = ptr.Locate(','); |
498 length = ptr.Locate(','); |
562 |
499 |
563 if(length == KErrNotFound) |
500 if(length == KErrNotFound) |
564 { |
501 { |
565 endOfFlag = ETrue; |
502 endOfFlag = ETrue; |
566 } |
503 } |
567 else{ |
504 else |
568 ptr.Set(ptr.Left(length)); |
505 { |
569 pos += (length +1); |
506 ptr.Set(ptr.Left(length)); |
570 } |
507 pos += (length +1); |
|
508 } |
571 |
509 |
572 if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound)) |
510 if(((ptr.MatchF(KLogicallyRemovableAtt)) != KErrNotFound) || ((ptr.MatchF(KLogicallyRemovableAttHex)) != KErrNotFound)) |
573 oldAtt |= KDriveAttLogicallyRemovable; |
511 remove_Att |= KDriveAttLogicallyRemovable; |
574 if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound)) |
512 |
575 oldAtt |= KDriveAttHidden; |
513 if(((ptr.MatchF(KHiddenAtt)) != KErrNotFound) || ((ptr.MatchF(KHiddenAttHex)) != KErrNotFound)) |
|
514 remove_Att |= KDriveAttHidden; |
576 |
515 |
577 } |
516 }//while(!endOfFlag) |
578 } |
517 |
579 |
518 } |
580 if ((newAtt & KDriveAttLogicallyRemovable) && (!(driveInfo.iDriveAtt & KDriveAttRemovable)) && (!(newAtt & KDriveAttRemovable))) |
519 |
581 { |
520 if ((add_Att & KDriveAttLogicallyRemovable)) |
582 newAtt |= KDriveAttRemovable; //KDriveAttLogicallyRemovale should always set KDriveAttRemovale |
521 { |
583 } |
522 add_Att |= KDriveAttRemovable; //KDriveAttLogicallyRemovale should always set KDriveAttRemovale |
584 if ((oldAtt & KDriveAttRemovable) && (!(oldAtt & KDriveAttLogicallyRemovable))) |
523 } |
585 { |
524 |
586 oldAtt |= KDriveAttLogicallyRemovable; |
525 if ((remove_Att & KDriveAttRemovable)) |
587 } |
526 { |
588 if(newAtt) |
527 remove_Att |= KDriveAttLogicallyRemovable; |
589 { |
528 } |
590 driveInfo.iDriveAtt |= newAtt; |
529 |
591 } |
530 |
592 if(oldAtt) |
531 aDrvAtt |= add_Att; //-- add new attributes to drive's ones |
593 { |
532 aDrvAtt &= ~remove_Att; //-- remove drive attributes if there are soem indicated |
594 if(oldAtt & driveInfo.iDriveAtt) |
533 } |
595 { |
534 |
596 driveInfo.iDriveAtt ^= oldAtt; |
535 //----------------------------------------------------------------------------- |
597 } |
536 /** |
598 } |
537 Try to find and process "ForceRugged" key in the drive section. It looks like: |
599 aRequest->Drive()->SetAtt(driveInfo.iDriveAtt); |
538 [DriveX] |
600 aRequest->Drive()->GetFSys()=pF; |
539 ForceRugged N |
601 |
540 |
602 // empty the closed file queue |
541 where when N==0, the drive forced to be non-rugged, when N==1, the drive forced to be rugged, |
603 TClosedFileUtils::Remove(aRequest->DriveNumber()); |
542 otherwise the original value is not overridden. |
604 |
543 |
605 return(KErrNone); |
544 @param aDrvNum drive number |
606 } |
545 @param aRugged out: true/false if the setting is found, not changed if there is no such a key in the config file |
607 |
546 */ |
608 |
547 static void DoProcessForceRuggedSetting(TInt aDrvNum, TBool& aRugged) |
|
548 { |
|
549 _LIT8(KKeyname, "ForceRugged"); |
|
550 TBuf8<8> sectionName; |
|
551 F32Properties::GetDriveSection(aDrvNum, sectionName); |
|
552 |
|
553 TInt32 val=-1; |
|
554 if(F32Properties::GetInt(sectionName, KKeyname, val)) |
|
555 { |
|
556 if(val == 0) |
|
557 aRugged = EFalse; |
|
558 else if(val == 1) |
|
559 aRugged = ETrue; |
|
560 //else the value is considered to be invalid and nothing changed |
|
561 } |
|
562 } |
|
563 |
|
564 //----------------------------------------------------------------------------- |
|
565 /** |
|
566 A helper function that binds a file system to the drive along with the optional primary extension etc. |
|
567 |
|
568 @param aRequest FS request object |
|
569 @param aFsName file system name to be bound to the drive |
|
570 @param aIsExtension if true, this means that it's necessary to mount aprimary extension as well |
|
571 @param aIsSync specifies if this drive is synchronous one or not |
|
572 |
|
573 @return standard error code |
|
574 */ |
|
575 static TInt DoMountFsInitialise(CFsRequest* aRequest, TDesC& aFsName, TBool aIsExtension, TBool aIsSync) |
|
576 { |
|
577 if (!KCapFsMountFileSystem.CheckPolicy(aRequest->Message(), __PLATSEC_DIAGNOSTIC_STRING("Mount File System"))) |
|
578 return KErrPermissionDenied; |
|
579 |
|
580 TInt r=ValidateDrive(aRequest->Message().Int1(),aRequest); |
|
581 if(r!=KErrNone) |
|
582 return(r); |
|
583 |
|
584 const TBool driveThreadExists = FsThreadManager::IsDriveAvailable(aRequest->DriveNumber(), ETrue); |
|
585 TDrive& drive = *aRequest->Drive(); |
|
586 |
|
587 if(driveThreadExists) |
|
588 { |
|
589 // A drive thread already exists for this drive.This could be because a filesystem |
|
590 // is already mounted, or a proxy drive is loaded. Check the mount to be sure... |
|
591 if(drive.GetFSys()) |
|
592 { |
|
593 // Yes, a mount already exists so we can't mount another one! |
|
594 return(KErrAccessDenied); |
|
595 } |
|
596 |
|
597 __ASSERT_DEBUG(IsProxyDrive(aRequest->DriveNumber()), User::Panic(_L("Bad thread state - No Mount or Proxy Drive Exists!"), -999)); |
|
598 } |
|
599 |
|
600 // ...therefore no drive thread can be present |
|
601 __ASSERT_DEBUG(! &drive.FSys(),Fault(EMountFileSystemFSys)); |
|
602 |
|
603 if(drive.IsSubsted()) |
|
604 return(KErrAccessDenied); |
|
605 |
|
606 CFileSystem* pF = GetFileSystem(aFsName); |
|
607 if(!pF) |
|
608 return(KErrNotFound); |
|
609 |
|
610 |
|
611 // Check that if the drive is a proxy drive (not using TBusLocalDrive) then the filesystem supports these... |
|
612 const TInt driveNumber = aRequest->DriveNumber(); |
|
613 if(IsProxyDrive(driveNumber)) |
|
614 { |
|
615 if(!pF->IsProxyDriveSupported()) |
|
616 return KErrNotSupported; |
|
617 |
|
618 r = LocalDrives::SetupMediaChange(driveNumber); |
|
619 } |
|
620 |
|
621 |
|
622 //-- get drive information from the file system |
|
623 TDriveInfo driveInfo; |
|
624 driveInfo.iDriveAtt=0; |
|
625 pF->DriveInfo(driveInfo, driveNumber); //-- the file system can override some driveInfo properties |
|
626 if(!driveInfo.iDriveAtt) |
|
627 r = KErrArgument; |
|
628 |
|
629 if(r == KErrNone && !driveThreadExists) |
|
630 {// determine whether file system synchronous or not not by flag passed in |
|
631 r=FsThreadManager::InitDrive(driveNumber, aIsSync); |
|
632 } |
|
633 |
|
634 if(r!=KErrNone) |
|
635 return(r); |
|
636 |
|
637 |
|
638 //-- add a primary drive extension if it is specified |
|
639 if(aIsExtension && aRequest->Message().Ptr2()!=NULL) |
|
640 { |
|
641 //-- check extension name length. It should not exceed KMaxFSNameLength (32 characters) |
|
642 r = aRequest->GetDesLength(KMsgPtr2); |
|
643 if(r <=0 || r >KMaxFSNameLength) |
|
644 return KErrArgument; |
|
645 |
|
646 TFSName extName; |
|
647 |
|
648 r = aRequest->Read(KMsgPtr2,extName); |
|
649 if (r!=KErrNone) |
|
650 return r; |
|
651 |
|
652 CProxyDriveFactory* pE=GetExtension(extName); |
|
653 if(pE==NULL) |
|
654 return(KErrNotFound); |
|
655 |
|
656 r=drive.MountExtension(pE,ETrue); |
|
657 if(r!=KErrNone) |
|
658 return(r); |
|
659 } |
|
660 |
|
661 //-- process optional additional drive attributes that can be specified in estart.txt |
|
662 DoProcessAdditionalDriveAttributes(driveNumber, driveInfo.iDriveAtt); |
|
663 |
|
664 if(driveInfo.iDriveAtt & KDriveAttLogicallyRemovable) |
|
665 { |
|
666 ASSERT(driveInfo.iDriveAtt & KDriveAttRemovable); |
|
667 } |
|
668 |
|
669 |
|
670 //-- process 'rugged drive' property |
|
671 TBool bRuggedDrive = drive.IsRugged(); |
|
672 |
|
673 //-- reset 'Rugged drive' attribute if this drive is removable. Having 'rugged' file system on a removable drive |
|
674 //-- doesn't make any sense and leads only to the performance degradation |
|
675 if(bRuggedDrive && (driveInfo.iDriveAtt & KDriveAttRemovable)) |
|
676 { |
|
677 __PRINT1(_L("DoMountFsInitialise() drv:%d is removable. resetting 'Rugged' flag!"), driveNumber); |
|
678 bRuggedDrive = EFalse; |
|
679 } |
|
680 |
|
681 DoProcessForceRuggedSetting(driveNumber, bRuggedDrive); //-- setting in estart.txt can override this flag |
|
682 drive.SetRugged(bRuggedDrive); |
|
683 |
|
684 |
|
685 //-- let TDrive object know if the drive is synchronous |
|
686 drive.SetSynchronous(aIsSync); |
|
687 |
|
688 drive.SetAtt(driveInfo.iDriveAtt); //-- finally set drive attributes |
|
689 drive.GetFSys()=pF; //-- bind a file system to the drive |
|
690 |
|
691 |
|
692 TClosedFileUtils::Remove(driveNumber); // empty the closed file queue |
|
693 |
|
694 return KErrNone; |
|
695 } |
|
696 |
|
697 //----------------------------------------------------------------------------- |
609 TInt TFsMountFileSystem::DoRequestL(CFsRequest* aRequest) |
698 TInt TFsMountFileSystem::DoRequestL(CFsRequest* aRequest) |
610 // |
699 // |
611 // Mount a filesystem on a drive. |
700 // Mount a filesystem on a drive. |
612 // |
701 // |
613 { |
702 { |