Changed the CCommandFactory logic that searches for commands. Release_002
authorTom Sutcliffe <thomas.sutcliffe@accenture.com>
Sat, 06 Nov 2010 20:15:03 +0000
changeset 87 63fd51b1ff80
parent 86 56b6ee983610
child 88 b44958a4977b
Changed the CCommandFactory logic that searches for commands. * Changed the CCommandFactory logic that searches for commands; it now scans \resource\cif\fshell rather than \sys\bin. This means that the 'help' command now works on the emulator and on installs without all capabilities. * Fixed wslog ciftest
build/common/common.mmh
commands/chkdeps/chkdeps.mmp
commands/group/bld.inf
commands/group/fshell_commands.iby
commands/load/load.cif
commands/load/load.cpp
commands/patchdata/patchdata.cif
commands/wslog/wslog.cpp
core/src/command_factory.cpp
core/src/command_factory.h
documentation/change_history.pod
libraries/iosrv/client/command_info_file.cpp
libraries/iosrv/inc/ioutils.h
--- a/build/common/common.mmh	Sat Nov 06 16:46:13 2010 +0000
+++ b/build/common/common.mmh	Sat Nov 06 20:15:03 2010 +0000
@@ -397,6 +397,7 @@
 
 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT
 #define FSHELL_QR3_SUPPORT_SANDBOX
+#define FSHELL_QR3_SUPPORT_KERNINFO
 #endif
 
 
--- a/commands/chkdeps/chkdeps.mmp	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/chkdeps/chkdeps.mmp	Sat Nov 06 20:15:03 2010 +0000
@@ -16,7 +16,7 @@
 targettype		exe
 uid				FSHELL_UID2_FSHELL_EXE FSHELL_UID_CHKDEPS
 
-capability		all
+capability		FSHELL_CAP_MMP_MAX
 
 userinclude		.
 #include <fshell/fsh_system_include.mmh>
--- a/commands/group/bld.inf	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/group/bld.inf	Sat Nov 06 20:15:03 2010 +0000
@@ -424,15 +424,20 @@
 
 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT
 PRJ_EXPORTS
-..\kerninfo\kerninfo.cif		z:\resource\cif\fshell\kerninfo.cif
 ..\setpriority\setpriority.cif		z:\resource\cif\fshell\setpriority.cif
 ..\setcritical\setcritical.cif		z:\resource\cif\fshell\setcritical.cif
 PRJ_MMPFILES
-..\kerninfo\kerninfo.mmp
 ..\setpriority\setpriority.mmp
 ..\setcritical\setcritical.mmp
 #endif // FSHELL_MEMORY_ACCESS_SUPPORT
 
+#ifdef FSHELL_QR3_SUPPORT_KERNINFO
+PRJ_EXPORTS
+..\kerninfo\kerninfo.cif		z:\resource\cif\fshell\kerninfo.cif
+PRJ_MMPFILES
+..\kerninfo\kerninfo.mmp
+#endif // FSHELL_QR3_SUPPORT_KERNINFO
+
 #ifdef FSHELL_CORE_SUPPORT_TOP
 PRJ_EXPORTS
 ..\top\top.cif				z:\resource\cif\fshell\top.cif
--- a/commands/group/fshell_commands.iby	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/group/fshell_commands.iby	Sat Nov 06 20:15:03 2010 +0000
@@ -356,14 +356,17 @@
 FSHELL_COMMAND_INFO_FILE(fshell,fed.cif)
 
 #ifdef FSHELL_MEMORY_ACCESS_SUPPORT
-FSHELL_EXECUTABLE_FILE(kerninfo.exe)
-FSHELL_COMMAND_INFO_FILE(fshell,kerninfo.cif)
 FSHELL_EXECUTABLE_FILE(setpriority.exe)
 FSHELL_COMMAND_INFO_FILE(fshell,setpriority.cif)
 FSHELL_EXECUTABLE_FILE(setcritical.exe)
 FSHELL_COMMAND_INFO_FILE(fshell,setcritical.cif)
 #endif
 
+#ifdef FSHELL_QR3_SUPPORT_KERNINFO
+FSHELL_EXECUTABLE_FILE(kerninfo.exe)
+FSHELL_COMMAND_INFO_FILE(fshell,kerninfo.cif)
+#endif
+
 #ifdef FSHELL_CORE_SUPPORT_TOP
 FSHELL_DEVICE_DRIVER(topsampler.ldd)
 FSHELL_EXECUTABLE_FILE(top.exe)
--- a/commands/load/load.cif	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/load/load.cif	Sat Nov 06 20:15:03 2010 +0000
@@ -34,6 +34,10 @@
 
 The version of the DLL to be loaded. The top 16 bits of the version are the major version, the bottom 16 the minor. Unless otherwise specified DLLs are given the version 10.0, ie 0x000A0000. Note versions are not checked on the WINSCW platform because it uses the windows DLL loader.
 
+==option bool n nowait
+
+Don't wait before exiting.
+
 ==argument string dll_name
 
 The name of the DLL to load.
@@ -42,3 +46,6 @@
 
 Copyright (c) 2008-2010 Accenture. All rights reserved.
 
+==smoke-test
+
+load --nowait euser.dll $Quiet
--- a/commands/load/load.cpp	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/load/load.cpp	Sat Nov 06 20:15:03 2010 +0000
@@ -32,6 +32,7 @@
 	RArray<TUint> iUids;
 	TUint iModuleVersion;
 	RLibrary iLibrary;
+	TBool iNoWait;
 	};
 
 
@@ -91,6 +92,8 @@
 	TUidType uids = iLibrary.Type();
 	Printf(_L("Loaded %S\r\n"), &file);
 	Printf(_L("Uids: 0x%x, 0x%x, 0x%x\r\n"), uids[0].iUid, uids[1].iUid, uids[2].iUid);
+
+	if (iNoWait) Complete(KErrNone);
 	}
 
 void CCmdLoad::OptionsL(RCommandOptionList& aOptions)
@@ -100,6 +103,9 @@
 
 	_LIT(KCmdOptVersion, "version");
 	aOptions.AppendUintL(iModuleVersion, KCmdOptVersion);
+
+	_LIT(KCmdOptNoWait, "nowait");
+	aOptions.AppendBoolL(iNoWait, KCmdOptNoWait);
 	}
 
 void CCmdLoad::ArgumentsL(RCommandArgumentList& aArguments)
--- a/commands/patchdata/patchdata.cif	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/patchdata/patchdata.cif	Sat Nov 06 20:15:03 2010 +0000
@@ -42,3 +42,6 @@
 
 Copyright (c) 2008-2010 Accenture. All rights reserved.
 
+==smoke-test
+
+patchdata $Quiet
--- a/commands/wslog/wslog.cpp	Sat Nov 06 16:46:13 2010 +0000
+++ b/commands/wslog/wslog.cpp	Sat Nov 06 20:15:03 2010 +0000
@@ -127,8 +127,12 @@
 			Printf(_L("Z drive wsini log lines:\r\n"));
 			CmdL(_L("fshell.exe"), _L("-e 'cat z:\\system\\data\\wsini.ini | match LOG*'"));
 
+#ifdef FSHELL_QR3_SUPPORT_KERNINFO
 			Printf(_L("Possible logging DLLs (none means logging probably not enabled):\r\n"));
 			CmdL(_L("kerninfo.exe"), _L("codeseg -m DLOG*"));
+#else
+			Printf(_L("(Not listing logging DLLs as kerninfo is not available)\r\n"));
+#endif
 			}
 			break;
 		case EDump:
--- a/core/src/command_factory.cpp	Sat Nov 06 16:46:13 2010 +0000
+++ b/core/src/command_factory.cpp	Sat Nov 06 20:15:03 2010 +0000
@@ -35,7 +35,6 @@
 const TUid KFshellExeUid = {FSHELL_UID2_FSHELL_EXE};
 const TUint KPipsExeUidValue = 0x20004c45;
 const TUid KPipsExeUid = { KPipsExeUidValue };
-_LIT(KExecutableDir, "\\sys\\bin\\");
 _LIT(KFshellPrefix, "fshell_"); // This	MUST be in lower case.
 
 
@@ -143,12 +142,13 @@
 	RProcess& process(aProcess);
 
 	TInt ret = FindCommandL(aCommandName);
-	if (ret >= 0)
+	if (ret >= 0 && (iCommands[ret]->Type() != CCommandConstructorBase::ETypeExe || static_cast<CExeCommandConstructor*>(iCommands[ret])->ExeName().Length()))
 		{
 		// (1) we explicitly know about it
 		return iCommands[ret]->ConstructCommandL();
 		}
 
+	/* 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
 	if (iFileSystemScanned)
 		{
 		// (2) We successfully scanned the file system (which means we had enough PlatSec capabilities to do so),
@@ -156,6 +156,7 @@
 		User::LeaveIfError(process.Create(aCommandName, aArguments));
 		return CProcessCommand::NewL(aCommandName, process);
 		}
+	*/
 
 	// We didn't manage to scan the file system, so this command could be any kind of external command.
 
@@ -241,9 +242,6 @@
 
 CCommandFactory::CCommandFactory(RFs& aFs)
 	: CActive(CActive::EPriorityStandard), iFs(aFs), iFactoryThreadId(RThread().Id()), iFactoryAllocator(&User::Allocator())
-#ifdef __WINS__
-	, iFailedToScanFileSystem(ETrue)
-#endif
 	{
 	CActiveScheduler::Add(this);
 	}
@@ -423,6 +421,10 @@
 			iCommands.Remove(pos);
 			iCommands.Insert(aCommandConstructor, pos);
 			}
+		else
+			{
+			delete aCommandConstructor;
+			}
 		}
 	else
 		{
@@ -488,21 +490,23 @@
 			}
 		}
 
-	_LIT(KExeExtension, ".exe");
+	/*_LIT(KExeExtension, ".exe");
 	TUidType exeUids(KNullUid, KFshellExeUid, KNullUid);
 	AppendExternalCommandsL(exeUids, KExeExtension);
 
 	TUidType pipsUids(KNullUid, KPipsExeUid, KNullUid);
 	AppendExternalCommandsL(pipsUids, KExeExtension);
+	*/
+	AppendExternalCifCommandsL();
 
 	iFileSystemScanned = ETrue;
 
 	CleanupStack::PopAndDestroy(); // WaitLC.
 	}
 
-void CCommandFactory::AppendExternalCommandsL(const TUidType& aUidType, const TDesC& aExtension)
+/*
+void CCommandFactory::AppendExternalCommandsL(const TUidType& aUidType, const TDesC& / *aExtension* /)
 	{
-	//const TInt numDrives = iDriveList.Length();
 	for (TInt drive = EDriveY; ; --drive)
 		{
 		if (drive == -1)
@@ -525,7 +529,7 @@
 			const TInt count = dir->Count();
 			for (TInt i = 0; i < count; ++i)
 				{
-				DoAppendExternalCommandsL((*dir)[i], aUidType, aExtension);
+				DoAppendExternalCommandL((*dir)[i], aUidType[1].iUid);
 				}
 			CleanupStack::PopAndDestroy(dir);
 			}
@@ -543,7 +547,69 @@
 					err = d.Read(entry);
 					if (err == KErrNone)
 						{
-						DoAppendExternalCommandsL(entry, aUidType, aExtension);
+						DoAppendExternalCommandL(entry, aUidType[1].iUid);
+						}
+					}
+				CleanupStack::PopAndDestroy(&d);
+				}
+			}
+		else if (err == KErrPermissionDenied)
+			{
+			// Abort in this case because all drives will doubtless fail with the same error if we don't have enough capabilities.
+			User::Leave(err);
+			}
+
+		if (drive == EDriveZ)
+			{
+			break;
+			}
+		}
+	}
+*/
+
+void CCommandFactory::AppendExternalCifCommandsL()
+	{
+	for (TInt drive = EDriveY; ; --drive)
+		{
+		if (drive == -1)
+			{
+			drive = EDriveZ;
+			}
+
+		TChar driveLetter;
+		User::LeaveIfError(RFs::DriveToChar(drive, driveLetter));
+		CDir* dir = NULL;
+		TFileName dirName;
+		dirName.Append(driveLetter);
+		dirName.Append(':');
+		dirName.Append(KFshellCifPath);
+		// Try getting the directory contents in one go
+		TInt err = iFs.GetDir(dirName, KEntryAttNormal, ESortByName, dir);
+		if (err == KErrNone)
+			{
+			CleanupStack::PushL(dir);
+			const TInt count = dir->Count();
+			for (TInt i = 0; i < count; ++i)
+				{
+				DoAppendExternalCommandL((*dir)[i], 0);
+				}
+			CleanupStack::PopAndDestroy(dir);
+			}
+		else if (err == KErrNoMemory)
+			{
+			// If not enough memory to read dir in one go, iterate the RDir (slower but uses less memory)
+			RDir d;
+			TInt err = d.Open(iFs, dirName, KEntryAttNormal);
+			if (err == KErrNone)
+				{
+				CleanupClosePushL(d);
+				TEntry entry;
+				while (err == KErrNone)
+					{
+					err = d.Read(entry);
+					if (err == KErrNone)
+						{
+						DoAppendExternalCommandL(entry, 0);
 						}
 					}
 				CleanupStack::PopAndDestroy(&d);
@@ -562,24 +628,14 @@
 		}
 	}
 
-void CCommandFactory::DoAppendExternalCommandsL(const TEntry& aEntry, const TUidType& aUidType, const TDesC& aExtension)
+
+void CCommandFactory::DoAppendExternalCommandL(const TEntry& aEntry, TInt aUid)
 	{
-	TInt pos = aEntry.iName.FindF(aExtension);
-	TPtrC name;
-	if (pos >= 0)
-		{
-		name.Set(aEntry.iName.Left(pos));
-		}
-	else
-		{
-		name.Set(aEntry.iName);
-		}
-
-	HBufC* nameBuf = name.AllocLC();
+	HBufC* nameBuf = TParsePtrC(aEntry.iName).Name().AllocLC(); // Removes any extension
 	nameBuf->Des().Fold();
 	CCommandConstructorBase* commandConstructor = NULL;
 
-	switch (aUidType[1].iUid)
+	switch (aUid)
 		{
 		case FSHELL_UID2_FSHELL_EXE:
 			{
@@ -598,6 +654,12 @@
 			commandConstructor->SetAttributes(CCommandConstructorBase::EAttExternal | CCommandConstructorBase::EAttNotInHelp);
 			break;
 			}
+		case 0:
+			{
+			commandConstructor = CExeCommandConstructor::NewLC(*nameBuf, KNullDesC);
+			commandConstructor->SetAttributes(CCommandConstructorBase::EAttExternal);
+			break;
+			}
 		}
 
 	AddCommandL(commandConstructor);
--- a/core/src/command_factory.h	Sat Nov 06 16:46:13 2010 +0000
+++ b/core/src/command_factory.h	Sat Nov 06 20:15:03 2010 +0000
@@ -44,7 +44,8 @@
 	void CheckExternalCommands();
 	void FindExternalCommandsL();
 	void AppendExternalCommandsL(const TUidType& aUidType, const TDesC& aExtension);
-	void DoAppendExternalCommandsL(const TEntry& aEntry, const TUidType& aUidType, const TDesC& aExtension);
+	void AppendExternalCifCommandsL();
+	void DoAppendExternalCommandL(const TEntry& aEntry, TInt aUid);
 	void WaitLC() const;
 	TInt FindCommandL(const TDesC& aCommandName);
 	MCommand* DoCreateCommandL(const TDesC& aCommandName, const TDesC& aArguments, RProcess& aProcess);
--- a/documentation/change_history.pod	Sat Nov 06 16:46:13 2010 +0000
+++ b/documentation/change_history.pod	Sat Nov 06 20:15:03 2010 +0000
@@ -14,13 +14,13 @@
 
 =head1 FShell Change History
 
-=head2 Release 002 [Not yet released]
+=head2 Release 002
 
 =over 5
 
 =item *
 
-Open signing of fshell SIS files is now supported for production S60 handsets. Build fshell with the C<FSHELL_OPEN_SIGNED> macro defined (and without defining C<FSHELL_CAP_ALL> or C<FSHELL_PROTECTED_UIDS>) in your platform.mmh and submit \epoc32\fshell\fshell.unsigned.sis to https://www.symbiansigned.com/app/page/public/openSignedOnline.do . The following commands are not available when using Open Signing due to Platform Security restrictions: fdb; kerninfo; chunkinfo; svrinfo; objinfo; sudo; fsck; localdrive; ramdefrag; readmem; reboot; setcritical; setpriority. Others such as chkdeps, e32header, ps, and fshell itself will run but in a restricted capacity (for example, fshell will no longer allow you to modify files in the \sys\bin directory).
+Open signing of fshell SIS files is now supported for production S60 handsets. Build fshell with the C<FSHELL_OPEN_SIGNED> macro defined (and without defining C<FSHELL_CAP_ALL> or C<FSHELL_PROTECTED_UIDS>) in your platform.mmh and submit \epoc32\fshell\fshell.unsigned.sis to https://www.symbiansigned.com/app/page/public/openSignedOnline.do . The following commands are not available when using Open Signing due to Platform Security restrictions: fdb; kerninfo; chunkinfo; svrinfo; objinfo; sudo; fsck; localdrive; ramdefrag; readmem; reboot; setcritical; setpriority; showdebug. Others such as chkdeps, e32header, ps, and fshell itself will run but in a restricted capacity (for example, fshell will no longer allow you to modify files in the \sys\bin directory).
 
 =item *
 
@@ -86,6 +86,9 @@
 
 Removed iosrv.ini's console_size_detect setting. It is now calculated on a per-console basis whether the console requires size detection, based on whether the console implements the C<ConsoleSize::ReportedCorrectly()> extension. All the fshell-supplied consoles have been updated to implement this extension as appropriate, meaning that size detection will no longer be run unnecessarily on (for eg) win32cons when you run fshell.bat. As part of this work, the laziness of defcons (CDefaultConsole) has been removed as it overlapped unnecessarily with CLazyConsole. Defcons's sole responsibility now is to pick an appropriate console; lazycons is responsible for making sure it isn't instantiated prematurely.
 
+=item *
+
+Changed the CCommandFactory logic that searches for commands; it now scans \resource\cif\fshell rather than \sys\bin. This means that the 'help' command now works on the emulator and on installs without all capabilities.
 
 =back
 
--- a/libraries/iosrv/client/command_info_file.cpp	Sat Nov 06 16:46:13 2010 +0000
+++ b/libraries/iosrv/client/command_info_file.cpp	Sat Nov 06 20:15:03 2010 +0000
@@ -16,7 +16,6 @@
 
 _LIT(KCifExt, ".cif");
 _LIT(KCifPathVar, "CIF_PATH");
-_LIT(KCifPath, "\\resource\\cif\\fshell");
 _LIT(KEnumSeparator, ",");
 _LIT(KEnumQuote, "\"");
 _LIT(KNewLine, "\r\n");
@@ -227,7 +226,7 @@
 	{
 	TFileName2 fileName;
 	TRAPD(err, fileName.Copy(aEnvironment.GetAsDesL(KCifPathVar)));
-	if (err) fileName.Copy(KCifPath);
+	if (err) fileName.Copy(KFshellCifPath);
 
 	// Search the drive the command is running from first (rather than what the session path happens to be, which was the previous behaviour)
 	if (!fileName.HasDriveLetter()) fileName.Insert(0, _L("?:"));
--- a/libraries/iosrv/inc/ioutils.h	Sat Nov 06 16:46:13 2010 +0000
+++ b/libraries/iosrv/inc/ioutils.h	Sat Nov 06 20:15:03 2010 +0000
@@ -572,6 +572,7 @@
 	RArray<TCommandArgument> iArguments;
 	};
 
+_LIT(KFshellCifPath, "\\resource\\cif\\fshell\\");
 
 class CCommandInfoFile : public CBase
 	{