33 |
33 |
34 //const TUid KFshellDllUid = {FSHELL_UID2_FSHELL_DLL}; |
34 //const TUid KFshellDllUid = {FSHELL_UID2_FSHELL_DLL}; |
35 const TUid KFshellExeUid = {FSHELL_UID2_FSHELL_EXE}; |
35 const TUid KFshellExeUid = {FSHELL_UID2_FSHELL_EXE}; |
36 const TUint KPipsExeUidValue = 0x20004c45; |
36 const TUint KPipsExeUidValue = 0x20004c45; |
37 const TUid KPipsExeUid = { KPipsExeUidValue }; |
37 const TUid KPipsExeUid = { KPipsExeUidValue }; |
38 _LIT(KExecutableDir, "\\sys\\bin\\"); |
|
39 _LIT(KFshellPrefix, "fshell_"); // This MUST be in lower case. |
38 _LIT(KFshellPrefix, "fshell_"); // This MUST be in lower case. |
40 |
39 |
41 |
40 |
42 // |
41 // |
43 // CDummyCommandConstructor. |
42 // CDummyCommandConstructor. |
141 MCommand* CCommandFactory::DoCreateCommandL(const TDesC& aCommandName, const TDesC& aArguments, RProcess& aProcess) |
140 MCommand* CCommandFactory::DoCreateCommandL(const TDesC& aCommandName, const TDesC& aArguments, RProcess& aProcess) |
142 { |
141 { |
143 RProcess& process(aProcess); |
142 RProcess& process(aProcess); |
144 |
143 |
145 TInt ret = FindCommandL(aCommandName); |
144 TInt ret = FindCommandL(aCommandName); |
146 if (ret >= 0) |
145 if (ret >= 0 && (iCommands[ret]->Type() != CCommandConstructorBase::ETypeExe || static_cast<CExeCommandConstructor*>(iCommands[ret])->ExeName().Length())) |
147 { |
146 { |
148 // (1) we explicitly know about it |
147 // (1) we explicitly know about it |
149 return iCommands[ret]->ConstructCommandL(); |
148 return iCommands[ret]->ConstructCommandL(); |
150 } |
149 } |
151 |
150 |
|
151 /* The comment on (2) below is no longer correct because we now scan \resource\cif rather than \sys\bin so we don't automatically know about fshell_ prefixed exes |
152 if (iFileSystemScanned) |
152 if (iFileSystemScanned) |
153 { |
153 { |
154 // (2) We successfully scanned the file system (which means we had enough PlatSec capabilities to do so), |
154 // (2) We successfully scanned the file system (which means we had enough PlatSec capabilities to do so), |
155 // so any command that we don't know about must be a process command. |
155 // so any command that we don't know about must be a process command. |
156 User::LeaveIfError(process.Create(aCommandName, aArguments)); |
156 User::LeaveIfError(process.Create(aCommandName, aArguments)); |
157 return CProcessCommand::NewL(aCommandName, process); |
157 return CProcessCommand::NewL(aCommandName, process); |
158 } |
158 } |
|
159 */ |
159 |
160 |
160 // We didn't manage to scan the file system, so this command could be any kind of external command. |
161 // We didn't manage to scan the file system, so this command could be any kind of external command. |
161 |
162 |
162 // See if a .exe extension was explicitly specified. |
163 // See if a .exe extension was explicitly specified. |
163 _LIT(KExeSuffix, ".exe"); |
164 _LIT(KExeSuffix, ".exe"); |
239 return count; |
240 return count; |
240 } |
241 } |
241 |
242 |
242 CCommandFactory::CCommandFactory(RFs& aFs) |
243 CCommandFactory::CCommandFactory(RFs& aFs) |
243 : CActive(CActive::EPriorityStandard), iFs(aFs), iFactoryThreadId(RThread().Id()), iFactoryAllocator(&User::Allocator()) |
244 : CActive(CActive::EPriorityStandard), iFs(aFs), iFactoryThreadId(RThread().Id()), iFactoryAllocator(&User::Allocator()) |
244 #ifdef __WINS__ |
|
245 , iFailedToScanFileSystem(ETrue) |
|
246 #endif |
|
247 { |
245 { |
248 CActiveScheduler::Add(this); |
246 CActiveScheduler::Add(this); |
249 } |
247 } |
250 |
248 |
251 void CCommandFactory::ConstructL() |
249 void CCommandFactory::ConstructL() |
421 delete existingCommand; |
419 delete existingCommand; |
422 existingCommand = NULL; |
420 existingCommand = NULL; |
423 iCommands.Remove(pos); |
421 iCommands.Remove(pos); |
424 iCommands.Insert(aCommandConstructor, pos); |
422 iCommands.Insert(aCommandConstructor, pos); |
425 } |
423 } |
|
424 else |
|
425 { |
|
426 delete aCommandConstructor; |
|
427 } |
426 } |
428 } |
427 else |
429 else |
428 { |
430 { |
429 User::LeaveIfError(err); |
431 User::LeaveIfError(err); |
430 } |
432 } |
486 { |
488 { |
487 iCommands.Remove(i); |
489 iCommands.Remove(i); |
488 } |
490 } |
489 } |
491 } |
490 |
492 |
491 _LIT(KExeExtension, ".exe"); |
493 /*_LIT(KExeExtension, ".exe"); |
492 TUidType exeUids(KNullUid, KFshellExeUid, KNullUid); |
494 TUidType exeUids(KNullUid, KFshellExeUid, KNullUid); |
493 AppendExternalCommandsL(exeUids, KExeExtension); |
495 AppendExternalCommandsL(exeUids, KExeExtension); |
494 |
496 |
495 TUidType pipsUids(KNullUid, KPipsExeUid, KNullUid); |
497 TUidType pipsUids(KNullUid, KPipsExeUid, KNullUid); |
496 AppendExternalCommandsL(pipsUids, KExeExtension); |
498 AppendExternalCommandsL(pipsUids, KExeExtension); |
|
499 */ |
|
500 AppendExternalCifCommandsL(); |
497 |
501 |
498 iFileSystemScanned = ETrue; |
502 iFileSystemScanned = ETrue; |
499 |
503 |
500 CleanupStack::PopAndDestroy(); // WaitLC. |
504 CleanupStack::PopAndDestroy(); // WaitLC. |
501 } |
505 } |
502 |
506 |
503 void CCommandFactory::AppendExternalCommandsL(const TUidType& aUidType, const TDesC& aExtension) |
507 /* |
504 { |
508 void CCommandFactory::AppendExternalCommandsL(const TUidType& aUidType, const TDesC& / *aExtension* /) |
505 //const TInt numDrives = iDriveList.Length(); |
509 { |
506 for (TInt drive = EDriveY; ; --drive) |
510 for (TInt drive = EDriveY; ; --drive) |
507 { |
511 { |
508 if (drive == -1) |
512 if (drive == -1) |
509 { |
513 { |
510 drive = EDriveZ; |
514 drive = EDriveZ; |
523 { |
527 { |
524 CleanupStack::PushL(dir); |
528 CleanupStack::PushL(dir); |
525 const TInt count = dir->Count(); |
529 const TInt count = dir->Count(); |
526 for (TInt i = 0; i < count; ++i) |
530 for (TInt i = 0; i < count; ++i) |
527 { |
531 { |
528 DoAppendExternalCommandsL((*dir)[i], aUidType, aExtension); |
532 DoAppendExternalCommandL((*dir)[i], aUidType[1].iUid); |
529 } |
533 } |
530 CleanupStack::PopAndDestroy(dir); |
534 CleanupStack::PopAndDestroy(dir); |
531 } |
535 } |
532 else if (err == KErrNoMemory) |
536 else if (err == KErrNoMemory) |
533 { |
537 { |
559 { |
563 { |
560 break; |
564 break; |
561 } |
565 } |
562 } |
566 } |
563 } |
567 } |
564 |
568 */ |
565 void CCommandFactory::DoAppendExternalCommandsL(const TEntry& aEntry, const TUidType& aUidType, const TDesC& aExtension) |
569 |
566 { |
570 void CCommandFactory::AppendExternalCifCommandsL() |
567 TInt pos = aEntry.iName.FindF(aExtension); |
571 { |
568 TPtrC name; |
572 for (TInt drive = EDriveY; ; --drive) |
569 if (pos >= 0) |
573 { |
570 { |
574 if (drive == -1) |
571 name.Set(aEntry.iName.Left(pos)); |
575 { |
572 } |
576 drive = EDriveZ; |
573 else |
577 } |
574 { |
578 |
575 name.Set(aEntry.iName); |
579 TChar driveLetter; |
576 } |
580 User::LeaveIfError(RFs::DriveToChar(drive, driveLetter)); |
577 |
581 CDir* dir = NULL; |
578 HBufC* nameBuf = name.AllocLC(); |
582 TFileName dirName; |
|
583 dirName.Append(driveLetter); |
|
584 dirName.Append(':'); |
|
585 dirName.Append(KFshellCifPath); |
|
586 // Try getting the directory contents in one go |
|
587 TInt err = iFs.GetDir(dirName, KEntryAttNormal, ESortByName, dir); |
|
588 if (err == KErrNone) |
|
589 { |
|
590 CleanupStack::PushL(dir); |
|
591 const TInt count = dir->Count(); |
|
592 for (TInt i = 0; i < count; ++i) |
|
593 { |
|
594 DoAppendExternalCommandL((*dir)[i], 0); |
|
595 } |
|
596 CleanupStack::PopAndDestroy(dir); |
|
597 } |
|
598 else if (err == KErrNoMemory) |
|
599 { |
|
600 // If not enough memory to read dir in one go, iterate the RDir (slower but uses less memory) |
|
601 RDir d; |
|
602 TInt err = d.Open(iFs, dirName, KEntryAttNormal); |
|
603 if (err == KErrNone) |
|
604 { |
|
605 CleanupClosePushL(d); |
|
606 TEntry entry; |
|
607 while (err == KErrNone) |
|
608 { |
|
609 err = d.Read(entry); |
|
610 if (err == KErrNone) |
|
611 { |
|
612 DoAppendExternalCommandL(entry, 0); |
|
613 } |
|
614 } |
|
615 CleanupStack::PopAndDestroy(&d); |
|
616 } |
|
617 } |
|
618 else if (err == KErrPermissionDenied) |
|
619 { |
|
620 // Abort in this case because all drives will doubtless fail with the same error if we don't have enough capabilities. |
|
621 User::Leave(err); |
|
622 } |
|
623 |
|
624 if (drive == EDriveZ) |
|
625 { |
|
626 break; |
|
627 } |
|
628 } |
|
629 } |
|
630 |
|
631 |
|
632 void CCommandFactory::DoAppendExternalCommandL(const TEntry& aEntry, TInt aUid) |
|
633 { |
|
634 HBufC* nameBuf = TParsePtrC(aEntry.iName).Name().AllocLC(); // Removes any extension |
579 nameBuf->Des().Fold(); |
635 nameBuf->Des().Fold(); |
580 CCommandConstructorBase* commandConstructor = NULL; |
636 CCommandConstructorBase* commandConstructor = NULL; |
581 |
637 |
582 switch (aUidType[1].iUid) |
638 switch (aUid) |
583 { |
639 { |
584 case FSHELL_UID2_FSHELL_EXE: |
640 case FSHELL_UID2_FSHELL_EXE: |
585 { |
641 { |
586 if (nameBuf->Left(KFshellPrefix().Length()).Compare(KFshellPrefix) == 0) |
642 if (nameBuf->Left(KFshellPrefix().Length()).Compare(KFshellPrefix) == 0) |
587 { |
643 { |
596 { |
652 { |
597 commandConstructor = CPipsCommandConstructor::NewLC(*nameBuf); |
653 commandConstructor = CPipsCommandConstructor::NewLC(*nameBuf); |
598 commandConstructor->SetAttributes(CCommandConstructorBase::EAttExternal | CCommandConstructorBase::EAttNotInHelp); |
654 commandConstructor->SetAttributes(CCommandConstructorBase::EAttExternal | CCommandConstructorBase::EAttNotInHelp); |
599 break; |
655 break; |
600 } |
656 } |
|
657 case 0: |
|
658 { |
|
659 commandConstructor = CExeCommandConstructor::NewLC(*nameBuf, KNullDesC); |
|
660 commandConstructor->SetAttributes(CCommandConstructorBase::EAttExternal); |
|
661 break; |
|
662 } |
601 } |
663 } |
602 |
664 |
603 AddCommandL(commandConstructor); |
665 AddCommandL(commandConstructor); |
604 CleanupStack::Pop(commandConstructor); |
666 CleanupStack::Pop(commandConstructor); |
605 CleanupStack::PopAndDestroy(nameBuf); |
667 CleanupStack::PopAndDestroy(nameBuf); |