core/src/command_factory.cpp
changeset 87 63fd51b1ff80
parent 78 b3ffff030d5c
equal deleted inserted replaced
86:56b6ee983610 87:63fd51b1ff80
    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 			{
   541 				while (err == KErrNone)
   545 				while (err == KErrNone)
   542 					{
   546 					{
   543 					err = d.Read(entry);
   547 					err = d.Read(entry);
   544 					if (err == KErrNone)
   548 					if (err == KErrNone)
   545 						{
   549 						{
   546 						DoAppendExternalCommandsL(entry, aUidType, aExtension);
   550 						DoAppendExternalCommandL(entry, aUidType[1].iUid);
   547 						}
   551 						}
   548 					}
   552 					}
   549 				CleanupStack::PopAndDestroy(&d);
   553 				CleanupStack::PopAndDestroy(&d);
   550 				}
   554 				}
   551 			}
   555 			}
   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);