Catchup.
authorJoe Branton <joe.branton@accenture.com>
Thu, 29 Jul 2010 12:03:43 +1000
changeset 15 6bb86f60191e
parent 14 4ab8c027df23 (current diff)
parent 10 ba0a96c1cc51 (diff)
child 16 18a55d594fba
Catchup.
core/group/fshell.bat
plugins/consoles/defcons/bmarm/defconsu.def
plugins/consoles/defcons/bwins/defconsu.def
plugins/consoles/defcons/eabi/defconsu.def
plugins/consoles/nullcons/BMARM/nullconsU.DEF
plugins/consoles/nullcons/bwins/nullconsu.def
plugins/consoles/nullcons/eabi/nullconsu.def
--- a/build/common/bld.inf	Thu Jul 29 12:02:58 2010 +1000
+++ b/build/common/bld.inf	Thu Jul 29 12:03:43 2010 +1000
@@ -33,6 +33,9 @@
 #include "..\..\plugins\consoles\rcons\group\bld.inf"
 #include "..\..\plugins\consoles\vt100cons\group\bld.inf"
 #include "..\..\plugins\consoles\win32cons\group\bld.inf"
+#ifdef FSHELL_TESTEXECUTE_SUPPORT
+#include "..\..\plugins\consoles\tefcons\bld.inf"
+#endif
 #include "..\..\plugins\networking\nullnif\group\bld.inf"
 #include "..\..\plugins\networking\tcpcsy\group\bld.inf"
 #include "..\..\plugins\networking\winsockprt\group\bld.inf"
--- a/build/common/common.mmh	Thu Jul 29 12:02:58 2010 +1000
+++ b/build/common/common.mmh	Thu Jul 29 12:03:43 2010 +1000
@@ -88,6 +88,9 @@
 #ifndef FSHELL_NO_MD4_SUPPORT
 #define FSHELL_MD4_SUPPORT
 #endif
+#ifndef FSHELL_NO_SPCRE_SUPPORT
+#define FSHELL_SPCRE_SUPPORT
+#endif
 
 //
 // PlatSec.
@@ -515,9 +518,10 @@
 #define FSHELL_UID_LOCALDRIVE                 0x10286F6D
 #define FSHELL_UID_PIPSRUN                    0x102866DB
 #define FSHELL_UID_USB                        0x10286F6E
-#define FSHELL_UID_EXTRABTRACE                0x10286F6B
-#define FSHELL_UID_MEMSPY                     0x10286F6C
-#define FSHELL_UID_EXTRABTRACEK               0x10286F6D
+#define FSHELL_UID_EXTRABTRACE                0x10286F6F
+#define FSHELL_UID_MEMSPY                     0x10286F70
+#define FSHELL_UID_EXTRABTRACEK               0x10286F71
+#define FSHELL_UID_TESTEXECUTE                0x10286F72
 
 #else // Not FSHELL_PROTECTED_UIDS
 
@@ -645,9 +649,10 @@
 #define FSHELL_UID_LOCALDRIVE                 0xE0286F6D
 #define FSHELL_UID_PIPSRUN                    0xE02866DB
 #define FSHELL_UID_USB                        0xE0286F6E
-#define FSHELL_UID_EXTRABTRACE                0xE0286F6B
-#define FSHELL_UID_MEMSPY                     0xE0286F6C
-#define FSHELL_UID_EXTRABTRACEK               0xE0286F6D
+#define FSHELL_UID_EXTRABTRACE                0xE0286F6F
+#define FSHELL_UID_MEMSPY                     0xE0286F70
+#define FSHELL_UID_EXTRABTRACEK               0xE0286F71
+#define FSHELL_UID_TESTEXECUTE                0xE0286F72
 
 #endif // FSHELL_PROTECTED_UIDS
 
--- a/build/common/fsh_buildsis.mk	Thu Jul 29 12:02:58 2010 +1000
+++ b/build/common/fsh_buildsis.mk	Thu Jul 29 12:03:43 2010 +1000
@@ -1,4 +1,4 @@
-# bldsis.mk
+# fsh_buildsis.mk
 # 
 # Copyright (c) 2010 Accenture. All rights reserved.
 # This component and the accompanying materials are made available
--- a/build/s60/platform_generic.mmh	Thu Jul 29 12:02:58 2010 +1000
+++ b/build/s60/platform_generic.mmh	Thu Jul 29 12:03:43 2010 +1000
@@ -31,6 +31,6 @@
 #define SYMBIAN_JAVA_NOT_INCLUDED
 #endif
 
-#define FSHELL_SPCRE_SUPPORT
+#define FSHELL_TESTEXECUTE_SUPPORT
 
 #endif // FSHELL_PLATFORM_GENERIC_MMH
--- a/commands/group/bld.inf	Thu Jul 29 12:02:58 2010 +1000
+++ b/commands/group/bld.inf	Thu Jul 29 12:03:43 2010 +1000
@@ -445,3 +445,10 @@
 PRJ_MMPFILES
 ..\memspy\memspy.mmp
 #endif
+
+#ifdef FSHELL_TESTEXECUTE_SUPPORT
+PRJ_EXPORTS
+..\testexecute\testexecute.mmp
+PRJ_MMPFILES
+..\testexecute\testexecute.cif           z:\resource\cif\fshell\testexecute.cif
+#endif
--- a/commands/group/fshell_commands.iby	Thu Jul 29 12:02:58 2010 +1000
+++ b/commands/group/fshell_commands.iby	Thu Jul 29 12:03:43 2010 +1000
@@ -369,4 +369,9 @@
 FSHELL_COMMAND_INFO_FILE(fshell,top.cif)
 #endif
 
+#ifdef FSHELL_TESTEXECUTE_SUPPORT
+FSHELL_EXECUTABLE_FILE(fshell_testexecute.exe)
+FSHELL_COMMAND_INFO_FILE(fshell,testexecute.cif)
+#endif
+
 #endif // __FSHELL_COMMANDS_IBY__
--- a/commands/swi/swi.cpp	Thu Jul 29 12:02:58 2010 +1000
+++ b/commands/swi/swi.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -49,6 +49,7 @@
 CCmdSwi::CCmdSwi():
 CCommandBase(CCommandBase::EManualComplete)
 	{
+	SetExtension(this);
 	}
 
 const TDesC& CCmdSwi::Name() const
@@ -196,11 +197,88 @@
 // CCmdSwi::Finished
 // callback from the underlying AO's RunL
 //
-void CCmdSwi::Finished(const TInt aError)
+void CCmdSwi::Finished(TInt aError)
 	{
 	Complete(aError);
 	}
 
+#define CASE_RETURN_LIT(XXX, YYY) case XXX: { _LIT(_KLit, #YYY); return &_KLit; }
+const TDesC* CCmdSwi::StringifyError(TInt aError) const
+	{
+	switch (aError)
+		{
+		CASE_RETURN_LIT(-10100, KErrSISFieldIdMissing);
+		CASE_RETURN_LIT(-10101, KErrSISFieldLengthMissing);
+		CASE_RETURN_LIT(-10102, KErrSISFieldLengthInvalid);
+		CASE_RETURN_LIT(-10103, KErrSISStringInvalidLength);
+		CASE_RETURN_LIT(-10104, KErrSISSignedControllerSISControllerMissing);
+		CASE_RETURN_LIT(-10105, KErrSISControllerSISInfoMissing);
+		CASE_RETURN_LIT(-10106, KErrSISInfoSISUidMissing);
+		CASE_RETURN_LIT(-10107, KErrSISInfoSISNamesMissing);
+		CASE_RETURN_LIT(-10108, KErrSISFieldBufferTooShort);
+		CASE_RETURN_LIT(-10109, KErrSISStringArrayInvalidElement);
+		CASE_RETURN_LIT(-10110, KErrSISInfoSISVendorNamesMissing);
+		CASE_RETURN_LIT(-10111, KErrSISInfoSISVersionMissing);
+		CASE_RETURN_LIT(-10112, KErrSISControllerSISSupportedLanguagesMissing);
+		CASE_RETURN_LIT(-10113, KErrSISSupportedLanguagesInvalidElement);
+		CASE_RETURN_LIT(-10114, KErrSISLanguageInvalidLength);
+		CASE_RETURN_LIT(-10115, KErrSISContentsSISSignedControllerMissing);
+		CASE_RETURN_LIT(-10116, KErrSISContentsSISDataMissing);
+		CASE_RETURN_LIT(-10117, KErrSISDataSISFileDataUnitMissing);
+		CASE_RETURN_LIT(-10118, KErrSISFileDataUnitTargetMissing);
+		CASE_RETURN_LIT(-10119, KErrSISFileOptionsMissing);
+		CASE_RETURN_LIT(-10120, KErrSISFileDataUnitDescriptorMissing);
+		CASE_RETURN_LIT(-10121, KErrSISFileDataDescriptionMissing);
+		CASE_RETURN_LIT(-10122, KErrSISContentsMissing);
+		CASE_RETURN_LIT(-10123, KErrSISEmbeddedControllersMissing);
+		CASE_RETURN_LIT(-10124, KErrSISEmbeddedDataUnitsMissing);
+		CASE_RETURN_LIT(-10125, KErrSISControllerOptionsMissing);
+		CASE_RETURN_LIT(-10126, KErrSISExpressionMissing);
+		CASE_RETURN_LIT(-10127, KErrSISExpressionStringValueMissing);
+		CASE_RETURN_LIT(-10128, KErrSISOptionsStringMissing);
+		CASE_RETURN_LIT(-10129, KErrSISFileOptionsExpressionMissing);
+		CASE_RETURN_LIT(-10130, KErrSISExpressionHeadValueMissing);
+		CASE_RETURN_LIT(-10131, KErrSISEmbeddedSISOptionsMissing);
+		CASE_RETURN_LIT(-10132, KErrSISInfoSISUpgradeRangeMissing);
+		CASE_RETURN_LIT(-10133, KErrSISDependencyMissingUid);
+		CASE_RETURN_LIT(-10134, KErrSISDependencyMissingVersion);
+		CASE_RETURN_LIT(-10135, KErrSISDependencyMissingNames);
+		CASE_RETURN_LIT(-10136, KErrSISPrerequisitesMissingDependency);
+		CASE_RETURN_LIT(-10137, KErrSISControllerMissingPrerequisites);
+		CASE_RETURN_LIT(-10138, KErrSISUpgradeRangeMissingVersion);
+		CASE_RETURN_LIT(-10139, KErrSISUnexpectedFieldType);
+		CASE_RETURN_LIT(-10140, KErrSISExpressionUnknownOperator);
+		CASE_RETURN_LIT(-10141, KErrSISArrayReadError);
+		CASE_RETURN_LIT(-10142, KErrSISArrayTypeMismatch);
+		CASE_RETURN_LIT(-10143, KErrSISInvalidStringLength);
+		CASE_RETURN_LIT(-10144, KErrSISCompressionNotSupported);
+		CASE_RETURN_LIT(-10145, KErrSISTooDeeplyEmbedded);
+		CASE_RETURN_LIT(-10146, KErrSISInvalidTargetFile);
+		CASE_RETURN_LIT(-10147, KErrSISWouldOverWrite);
+		CASE_RETURN_LIT(-10148, KErrSISInfoMissingRemoveDirectories);
+		CASE_RETURN_LIT(-10149, KErrSISNotEnoughSpaceToInstall);
+		CASE_RETURN_LIT(-10200, KErrInstallerLeave);
+		CASE_RETURN_LIT(-10250, KErrPolicyFileCorrupt);
+		CASE_RETURN_LIT(-10251, KErrSignatureSchemeNotSupported);
+		CASE_RETURN_LIT(-10252, KErrDigestNotSupported);
+		CASE_RETURN_LIT(-10253, KErrBadHash);
+		CASE_RETURN_LIT(-10254, KErrSecurityError);
+		CASE_RETURN_LIT(-10263, KErrBadUsage);
+		CASE_RETURN_LIT(-10260, KErrInvalidType); 
+		CASE_RETURN_LIT(-10261, KErrInvalidExpression); 
+		CASE_RETURN_LIT(-10262, KErrExpressionToComplex); 
+		CASE_RETURN_LIT(-10255, KErrMissingBasePackage); 
+		CASE_RETURN_LIT(-10256, KErrInvalidUpgrade); 
+		CASE_RETURN_LIT(-10257, KErrInvalidEclipsing);
+		CASE_RETURN_LIT(-10258, KErrWrongHeaderFormat);
+		CASE_RETURN_LIT(-10259, KErrCapabilitiesMismatch); 
+		CASE_RETURN_LIT(-10270, KErrLegacySisFile);
+		CASE_RETURN_LIT(-10271, KErrInvalidSoftwareTypeRegistrationFile); 
+		default:
+			return NULL;
+		}
+	}
+
 //
 // Sis installer AO
 //
--- a/commands/swi/swi.h	Thu Jul 29 12:02:58 2010 +1000
+++ b/commands/swi/swi.h	Thu Jul 29 12:03:43 2010 +1000
@@ -178,7 +178,7 @@
 // CCmdSwi
 // Fshell-console based class handling swi related functionality
 //
-class CCmdSwi : public CCommandBase, public MCmdSwiParent
+class CCmdSwi : public CCommandBase, public MCmdSwiParent, public MCommandExtensionsV1
 	{
 public:
 	static CCommandBase* NewLC();
@@ -194,11 +194,12 @@
 	virtual void DoRunL();
 	virtual void ArgumentsL(RCommandArgumentList& aArguments);
 	virtual void OptionsL(RCommandOptionList& aOptions);
+	const TDesC* StringifyError(TInt aError) const;
 		
 	// MCmdSwiParent hooks 	
 	virtual RIoConsoleReadHandle& Input();
 	virtual RIoConsoleWriteHandle& Output(TInt aError);
-	virtual void Finished(const TInt aError);
+	virtual void Finished(TInt aError);
 	virtual TBool GetAnswer();
 private:
 #ifndef SYMBIAN_JAVA_NOT_INCLUDED
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/testexecute/ProxyServer.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,433 @@
+// ProxyServer.cpp
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+#include "ProxyServer.h"
+#include <fshell/memoryaccess.h>
+
+#define LOG(x...)
+#define LOG8(x...)
+//#include <e32debug.h>
+//#define LOG(x...) RDebug::Print(x)
+//#define LOG8(x...) RDebug::Printf(x)
+
+//const TInt KShutdownProxy = 1000;
+//const TInt KPingProxy = 1001;
+
+NONSHARABLE_CLASS(CAsyncWaiter) : public CActive
+	{
+public:
+	CAsyncWaiter(RUnderlyingSession& aRealSession, const RMessage2& aOriginalMessage, const TIpcArgs& aArgs);
+	~CAsyncWaiter();
+	//void ForwardMessageL();
+
+protected:
+	void RunL();
+	void DoCancel();
+
+private:
+	RUnderlyingSession& iRealSession;
+	RMessage2 iMsg;
+	TIpcArgs iArgs;
+	};
+
+CProxyServer* CProxyServer::NewInSeparateThreadL(const TDesC& aServerToReplace, MMessageHandler* aHandler)
+	{
+	CProxyServer* self = new(ELeave) CProxyServer(aServerToReplace, aHandler);
+	CleanupStack::PushL(self);
+	self->ThreadConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CProxyServer::CProxyServer(const TDesC& aServerToReplace, MMessageHandler* aHandler)
+	: CServer2(0, ESharableSessions), iServerName(aServerToReplace), iHandler(aHandler)
+	{
+	// Name the server after tid and this pointer, should be unique enough
+	iRealServerName.AppendNum(RThread().Id(), EHex);
+	iRealServerName.Append('.');
+	iRealServerName.AppendNum((TInt)this, EHex);
+	}
+
+void CProxyServer::ThreadConstructL()
+	{
+	User::LeaveIfError(iServerThread.Create(iRealServerName, &StartServerThreadFunction, 8192, NULL, this));
+	TRequestStatus stat;
+	iServerThread.Rendezvous(stat);
+	if (stat == KRequestPending)
+		{
+		iServerThread.Resume();
+		}
+	else
+		{
+		iServerThread.Kill(stat.Int());
+		}
+	User::WaitForRequest(stat);
+	User::LeaveIfError(stat.Int());
+	}
+
+void CProxyServer::ConstructL()
+	{
+	iShutdownCallback = new(ELeave) CAsyncCallBack(CActive::EPriorityHigh);
+	iShutdownCallback->Set(TCallBack(&Shutdown, this));
+
+	User::LeaveIfError(iMemAccess.Open());
+	if (iRealServerName.Length() > iServerName.Length()) User::Leave(KErrTooBig); // Mem access doesn't like this
+
+	_LIT(KTempName, "TemporaryReallyLongServerNameThatLeavesUsSpaceToManuever");
+	StartL(KTempName);
+
+	TServerKernelInfoBuf buf;
+	TInt err = iMemAccess.GetObjectInfo(EServer, iServerName, buf);
+	User::LeaveIfError(err);
+	TUint8* realServer = buf().iAddressOfKernelObject;
+	err = iMemAccess.GetObjectInfo(EServer, KTempName, buf);
+	User::LeaveIfError(err);
+	TUint8* myServer = buf().iAddressOfKernelObject;
+
+	// Should really have some kind of swap operation here...
+	TBuf8<KMaxName> name8;
+	name8.Copy(iRealServerName);
+	iMemAccess.InPlaceObjectRename(EServer, realServer, name8);
+	name8.Copy(iServerName);
+	iMemAccess.InPlaceObjectRename(EServer, myServer, name8);
+	iProxying = ETrue;
+	}
+
+TInt CProxyServer::Shutdown(TAny* aSelf)
+	{
+	CProxyServer* self = static_cast<CProxyServer*>(aSelf);
+	delete self;
+	CActiveScheduler::Stop();
+	return 0;
+	}
+
+void CProxyServer::Destroy()
+	{
+	if (iShutdownCallback && iServerThread.Handle() && iServerThread.Id() != RThread().Id()) // Don't try shutting down the thread if the server is actually running in the main thread
+		{
+		TRequestStatus stat;
+		// This is far harder than it should be... need to make sure we don't reference any member vars after calling the shutdown callback
+		RThread serverThread;
+		Mem::Swap(&serverThread, &iServerThread, sizeof(RThread));
+		serverThread.Logon(stat);
+		iShutdownCallback->CallBack();
+		User::WaitForRequest(stat);
+		serverThread.Close();
+		}
+	else
+		{
+		delete this;
+		}
+	}
+
+CProxyServer::~CProxyServer()
+	{
+	if (iProxying)
+		{
+		TServerKernelInfoBuf buf;
+		TInt err = iMemAccess.GetObjectInfo(EServer, iRealServerName, buf);
+		if (!err)
+			{
+			TUint8* realServer = buf().iAddressOfKernelObject;
+			TBuf8<KMaxName> name8;
+			name8.Copy(iServerName);
+			iMemAccess.InPlaceObjectRename(EServer, realServer, name8);
+			// Temporarily both us and the real server will have name iServerName. When we finish destructing, we'll clean up and the system should be back in a sensible state
+			}
+		}
+	delete iShutdownCallback;
+	iServerThread.Close();
+	iMemAccess.Close();
+	}
+
+CSession2* CProxyServer::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const
+	{
+	CProxySession* res = new(ELeave) CProxySession();
+	CleanupStack::PushL(res);
+	res->ConstructL(iRealServerName, aVersion);
+	CleanupStack::Pop(res);
+	return res;
+	}
+
+
+void CProxyServer::ServerThreadRunL()
+	{
+	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+	
+	ConstructL();
+	RThread::Rendezvous(KErrNone);
+
+	CActiveScheduler::Start();
+	CleanupStack::PopAndDestroy(scheduler);
+	}
+
+TInt CProxyServer::StartServerThreadFunction(TAny* aSelf)
+	{
+	TInt err = KErrNoMemory;
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	if (cleanup)
+		{
+		TRAP(err, static_cast<CProxyServer*>(aSelf)->ServerThreadRunL());
+		delete cleanup;
+		}
+	return err;
+	}
+
+MMessageHandler* CProxyServer::Handler() const
+	{
+	return iHandler;
+	}
+
+//
+
+void CProxySession::ConstructL(const TDesC& aServerName, const TVersion& aVersion)
+	{
+	User::LeaveIfError(iSession.CreateSession(aServerName, aVersion));
+	}
+
+CProxyServer& CProxySession::Server()
+	{
+	return *const_cast<CProxyServer*>(static_cast<const CProxyServer*>(CSession2::Server()));
+	}
+
+const CProxyServer& CProxySession::Server() const
+	{
+	return *static_cast<const CProxyServer*>(CSession2::Server());
+	}
+
+void CProxySession::ServiceL(const RMessage2 &aMessage)
+	{
+	MMessageHandler* handler = Server().Handler();
+	TBool handled = EFalse;
+	if (handler)
+		{
+		handled = handler->HandleMessageL(this, aMessage);
+		}
+
+	if (!handled)
+		{
+		ForwardUnhandledMessageL(aMessage);
+		}
+	}
+
+TInt Val(const RMessage2& aMessage, TInt aIndex)
+	{
+	switch (aIndex)
+		{
+	case 0:
+		return aMessage.Int0();
+	case 1:
+		return aMessage.Int1();
+	case 2:
+		return aMessage.Int2();
+	case 3:
+		return aMessage.Int3();
+	default:
+		return 0;
+		}
+	}
+
+void CleanupArgs(TAny* aArgs)
+	{
+	TIpcArgs& args = *static_cast<TIpcArgs*>(aArgs);
+	for (TInt i = 0; i < KMaxMessageArguments; i++)
+		{
+		if (args.iFlags & (TIpcArgs::EFlagDes<<(i*TIpcArgs::KBitsPerType)))
+			{
+			LOG8("+++ deleting %x", args.iArgs[i]);
+			delete (TAny*)args.iArgs[i];
+			}
+		}
+	args.iFlags = 0;
+	}
+
+void CProxySession::ForwardUnhandledMessageL(const RMessage2& aMessage)
+	{
+	TIpcArgs args;
+	CleanupStack::PushL(TCleanupItem(&CleanupArgs, &args));
+	
+	LOG(_L("Forwarding message fn=%d"), aMessage.Function());
+
+	for (TInt i = 0; i < KMaxMessageArguments; i++)
+		{
+		// For each arg, try and figure out if it's a descriptor and if so what type
+		TInt len = aMessage.GetDesLength(i);
+		if (len < 0)
+			{
+			// Not a descriptor
+			args.Set(i, Val(aMessage, i));
+			LOG(_L("Int arg %d: %d"), i, args.iArgs[i]);
+			}
+		else
+			{
+			// It's a descriptor, now see if it's 16-bit or 8-bit
+			TBuf<1> wbuf;
+			TInt err = aMessage.Read(i, wbuf); // This check only works if platsec enforcement is turned on (!) but fshell.bat was the only thing that generally ran with enforcement off, and I've fixed that
+			if (err == KErrNone)
+				{
+				// 16-bit
+				// Gaah where's HBuf when you need it
+				TPtr* buf = (TPtr*)User::AllocL(len*2 + sizeof(TPtr));
+				new(buf) TPtr((TUint16*)(buf+1), len);
+				aMessage.ReadL(i, *buf);
+
+				// Figure out if it's writeable by trying to write back what we just read
+				TBool writeable = (aMessage.Write(i, *buf) == KErrNone);
+
+				if (writeable)
+					{
+					LOG(_L("TDes16 arg %d: %S"), i, buf);
+					args.Set(i, buf);
+					}
+				else
+					{
+					LOG(_L("TDesC16 arg %d: %S"), i, buf);
+					args.Set(i, (const TDesC16*)buf);
+					}
+				}
+			else
+				{
+				// 8-bit
+				// Gaah where's HBuf when you need it
+				TPtr8* buf = (TPtr8*)User::AllocL(len + sizeof(TPtr8));
+				new(buf) TPtr8((TUint8*)(buf+1), len);
+				aMessage.ReadL(i, *buf);
+
+				// Figure out if it's writeable by trying to write back what we just read
+				TBool writeable = (aMessage.Write(i, *buf) == KErrNone);
+
+				if (writeable)
+					{
+					LOG8("TDes8 arg %d: %S", i, buf);
+					args.Set(i, buf);
+					}
+				else
+					{
+					LOG8("TDesC8 arg %d: %S", i, buf);
+					args.Set(i, (const TDesC8*)buf);
+					}
+				}
+			}
+		}
+	ForwardMessageArgsL(aMessage, args);
+	CleanupStack::Pop(&args); // ForwardMessageArgs takes ownership
+	}
+
+void CProxySession::ForwardMessageArgsL(const RMessage2& aMessage, const TIpcArgs& aArgs)
+	{
+	CAsyncWaiter* waiter = new(ELeave) CAsyncWaiter(iSession, aMessage, aArgs);
+	// That's all that's needed
+	}
+
+void CProxySession::Disconnect(const RMessage2 &aMessage)
+	{
+	iSession.Close();
+	//TODO Need to wait for any CAsyncWaiters to be completed? If so, do it here and defer the super call until that time
+	CSession2::Disconnect(aMessage);
+	}
+
+// CAsyncWaiter
+
+CAsyncWaiter::CAsyncWaiter(RUnderlyingSession& aRealSession, const RMessage2& aOriginalMessage, const TIpcArgs& aArgs)
+	: CActive(CActive::EPriorityStandard), iRealSession(aRealSession), iMsg(aOriginalMessage), iArgs(aArgs)
+	{
+	CActiveScheduler::Add(this);
+	LOG(_L("Sending to real server: fn=%d, args=%x,%x,%x,%x flags=%x"), aOriginalMessage.Function(), iArgs.iArgs[0], iArgs.iArgs[1], iArgs.iArgs[2], iArgs.iArgs[3], iArgs.iFlags);
+	iRealSession.SendReceive(aOriginalMessage.Function(), iArgs, iStatus);
+	SetActive();
+	}
+
+CAsyncWaiter::~CAsyncWaiter()
+	{
+	CleanupArgs(&iArgs);
+	}
+
+void CAsyncWaiter::RunL()
+	{
+	const TInt serverErr = iStatus.Int();
+	TInt writeErr = KErrNone;
+
+	// First check for any TDes args that we need to write back to the real client
+	for (TInt i = 0; i < KMaxMessageArguments; i++)
+		{
+		if ((iArgs.iFlags & (TIpcArgs::EFlagDes<<(i*TIpcArgs::KBitsPerType))) && !(iArgs.iFlags & (TIpcArgs::EFlagConst<<(i*TIpcArgs::KBitsPerType))))
+			{
+			if (iArgs.iFlags & (TIpcArgs::EFlag16Bit<<(i*TIpcArgs::KBitsPerType)))
+				{
+				TDes16* des = (TDes16*)iArgs.iArgs[i];
+				writeErr = iMsg.Write(i, *des);
+				LOG(_L("Writing back %S returned %d"), des, writeErr);
+				}
+			else
+				{
+				TDes8* des = (TDes8*)iArgs.iArgs[i];
+				writeErr = iMsg.Write(i, *des);
+				LOG8("Writing back %S returned %d", des, writeErr);
+				}
+
+			if (writeErr) break; // Who knows how the real server would have handled such a case
+			}
+		}
+
+	LOG(_L("Completing original request function %d with writeErr=%d serverErr=%d"), iMsg.Function(), writeErr, serverErr);
+	if (writeErr) iMsg.Complete(writeErr);
+	else iMsg.Complete(serverErr);
+
+	delete this; // Our work here is done
+	}
+
+void CAsyncWaiter::DoCancel()
+	{
+	// We never call Cancel on our waiters
+	}
+
+/*
+EXPORT_C TInt ShutdownProxyNotifier()
+	{
+	RDebugNotifier notifier;
+	TInt err = notifier.Connect();
+	if (err == KErrNotFound)
+		{
+		// Oh dear, !Notifier isn't running. Meaning we renamed it then crashed, probably. Try renaming the real one
+		RMemoryAccess::LoadDriver();
+		RMemoryAccess mem;
+		err = mem.Open();
+		if (err) return err;
+		TServerKernelInfoBuf buf;
+		TInt err = mem.GetObjectInfo(EServer, KRealNotifierServerName, buf);
+		if (!err)
+			{
+			TUint8* realServer = buf().iAddressOfKernelObject;
+			mem.InPlaceObjectRename(EServer, realServer, _L8("!Notifier"));
+			}
+		mem.Close();
+		return err;
+		}
+
+	err = notifier.ShutdownProxy();
+	if (err == KErrServerTerminated) err = KErrNone; // It's expected to get KErrServerTerminated, because we deliberately don't complete the message. This way the client is more likely to get the completion once the server has actually gone, and not slightly before
+	notifier.Close();
+
+	return err;
+	}
+
+EXPORT_C TBool NotifierProxyIsRunning()
+	{
+	RDebugNotifier notifier;
+	TInt err = notifier.Connect();
+	if (err) return EFalse; // Not even original notifier is running?!
+	err = notifier.PingProxy();
+	notifier.Close();
+	return err == KErrNone; // The real proxy will return KErrNotSupported in this scenario
+	}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/testexecute/ProxyServer.h	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,82 @@
+// ProxyServer.h
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+#ifndef PROXYSERVER_H
+#define PROXYSERVER_H
+
+#include <fshell/memoryaccess.h>
+#include <e32base.h>
+
+class CProxySession;
+
+class MMessageHandler
+	{
+public:
+	virtual TBool HandleMessageL(CProxySession* aSession, const RMessage2& aMessage)=0;
+	};
+
+NONSHARABLE_CLASS(CProxyServer) : public CServer2
+	{
+public:
+	static CProxyServer* NewInSeparateThreadL(const TDesC& aServerToReplace, MMessageHandler* aHandler=NULL);
+	void Destroy(); // This should be used instead of delete - the server object has to be destroyed from the thread in which it was started
+	MMessageHandler* Handler() const;
+
+protected:
+	CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
+
+private:
+	~CProxyServer();
+	CProxyServer(const TDesC& aServerToReplace, MMessageHandler* aHandler);
+	void ConstructL();
+	void ThreadConstructL();
+	static TInt StartServerThreadFunction(TAny* aSelf);
+	void ServerThreadRunL();
+	static TInt Shutdown(TAny* aSelf);
+
+private:
+	RMemoryAccess iMemAccess;
+	TBool iProxying;
+	TName iServerName;
+	TName iRealServerName;
+	RThread iServerThread;
+	MMessageHandler* iHandler;
+	CAsyncCallBack* iShutdownCallback;
+	};
+
+class RUnderlyingSession : public RSessionBase
+	{
+public:
+	friend class CProxySession;
+	friend class CAsyncWaiter;
+	};
+
+NONSHARABLE_CLASS(CProxySession) : public CSession2
+	{
+public:
+	void ConstructL(const TDesC& aServerName, const TVersion& aVersion);
+	void ForwardUnhandledMessageL(const RMessage2& aMessage);
+	void ForwardMessageArgsL(const RMessage2& aMessage, const TIpcArgs& aArgs);
+
+protected:
+	void ServiceL(const RMessage2 &aMessage);
+	void Disconnect(const RMessage2 &aMessage);
+
+private:
+	CProxyServer& Server();
+	const CProxyServer& Server() const;
+
+private:
+	RUnderlyingSession iSession;
+	};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/testexecute/testexecute.cif	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,70 @@
+# testexecute.cif
+# 
+# Copyright (c) 2010 Accenture. All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+# 
+# Initial Contributors:
+# Accenture - Initial contribution
+#
+==name testexecute
+
+==short-description
+
+Fshell wrapper for testexecute.exe.
+
+==long-description
+
+An fshell exe that wraps up a Test Execute script run and redirects its output to the fshell console.
+
+==option bool d debug
+
+Used to put the system into debug mode. This means that the C<PAUSE> command pauses the script engine until the user hits a key.
+
+==option string i include
+
+(testexecute.exe's equivalent option is called C<-tci>. For compatability this is also allowed here.)
+
+Used to specify the test cases to be included during execution. The option is followed by a list of test case IDs to be included or excluded. You can specify the test case IDs in three different ways as follows:
+
+=over 5
+
+=item *
+
+A list of comma-separated test case IDs 
+
+=item *
+
+A range of test case IDs 
+
+=item *
+
+A .tcs file containing the test case IDs delimited by a new-line character. 
+
+=back
+
+You can specify the test case IDs using all the three different ways listed above. For example, in the following testexecute command, the test cases list is a combination of comma-separated test case IDs, test case ID range and a .tcs file containing IDs of the test cases to be included during execution: 
+
+ c:\>testexecute c:\tefintegrationtest\TEFIntegrationTest-regular.script -tci TEST-001,TEST-002,TEST-008:TEST-015,some.tcs
+
+==option bool t ignore
+
+For compatibility with testeexecute.exe, so you can specify includes with C<-tci>, which is a syntax fshell doesn't normally accept. Has no effect.
+
+==option bool c ignore2
+
+For compatibility with testeexecute.exe, so you can specify includes with C<-tci>, which is a syntax fshell doesn't normally accept. Has no effect.
+
+==option string x exclude
+
+Used to specify the test cases to be excluded during execution. Takes same syntax as C<--include>.
+
+==argument filename script-file optional
+
+The TEF script to execute. If not specified, the command replaces the TEF log server and waits forever for any logs to be written, and prints them to the console when they occur.
+
+==copyright
+
+Copyright (c) 2010 Accenture. All rights reserved.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/testexecute/testexecute.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,205 @@
+// testexecute.cpp
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <fshell/memoryaccesscmd.h>
+#include <fshell/descriptorutils.h>
+#include "proxyserver.h"
+#include <test/testexecutelogger.h>
+
+using namespace IoUtils;
+
+class CCmdTestExecute : public CMemoryAccessCommandBase, public MMessageHandler
+	{
+public:
+	static CCommandBase* NewLC();
+	~CCmdTestExecute();
+private:
+	CCmdTestExecute();
+
+private: // From MMessageHandler
+	virtual TBool HandleMessageL(CProxySession* aSession, const RMessage2& aMessage);
+
+private: // From CCommandBase.
+	virtual const TDesC& Name() const;
+	virtual void DoRunL();
+	virtual void ArgumentsL(RCommandArgumentList& aArguments);
+	virtual void OptionsL(RCommandOptionList& aOptions);
+
+private: // From CActive
+	void RunL();
+	void DoCancel();
+
+	class CLogonCompleter : public CActive
+		{
+	public:
+		CLogonCompleter(CCmdTestExecute* aCommand) : CActive(CActive::EPriorityStandard), iCommand(aCommand)
+			{
+			CActiveScheduler::Add(this);
+			iCommand->iTefProc.Logon(iStatus);
+			SetActive();
+			}
+		void RunL() { iCommand->Complete(iStatus.Int()); }
+		void DoCancel() { iCommand->iTefProc.LogonCancel(iStatus); }
+		~CLogonCompleter() { Cancel(); }
+
+	private:
+		CCmdTestExecute* iCommand;
+		};
+
+private:
+	CProxyServer* iProxy;
+	RTestExecuteLogServ iLogger;
+	RBuf8 iTempBuf;
+
+	TFileName2 iScriptFile;
+	TBool iIgnoredT, iIgnoredC;
+	HBufC* iIncludes;
+	HBufC* iExcludes;
+	TBool iDebug;
+	CLogonCompleter* iLogonCompleter;
+	RProcess iTefProc;
+	};
+
+
+EXE_BOILER_PLATE(CCmdTestExecute)
+
+CCommandBase* CCmdTestExecute::NewLC()
+	{
+	CCmdTestExecute* self = new(ELeave) CCmdTestExecute();
+	CleanupStack::PushL(self);
+	self->BaseConstructL();
+	return self;
+	}
+
+CCmdTestExecute::~CCmdTestExecute()
+	{
+	Cancel();
+	if (iProxy)
+		{
+		iProxy->Destroy();
+		}
+	iLogger.Close();
+	iTempBuf.Close();
+	delete iIncludes;
+	delete iExcludes;
+	delete iLogonCompleter;
+	iTefProc.Close();
+	}
+
+CCmdTestExecute::CCmdTestExecute()
+	: CMemoryAccessCommandBase(EManualComplete | ESharableIoSession)
+	{
+	iTefProc.SetHandle(0); // Don't default to the current process
+	}
+
+const TDesC& CCmdTestExecute::Name() const
+	{
+	_LIT(KName, "testexecute");	
+	return KName;
+	}
+
+void CCmdTestExecute::ArgumentsL(RCommandArgumentList& aArguments)
+	{
+	aArguments.AppendFileNameL(iScriptFile, _L("script-file"));
+	}
+
+void CCmdTestExecute::OptionsL(RCommandOptionList& aOptions)
+	{
+	aOptions.AppendBoolL(iDebug, _L("debug"));
+	aOptions.AppendBoolL(iIgnoredT, _L("ignore"));
+	aOptions.AppendBoolL(iIgnoredC, _L("ignore2"));
+	aOptions.AppendStringL(iIncludes, _L("include"));
+	aOptions.AppendStringL(iExcludes, _L("exclude"));
+	}
+
+#define CTRL(x) ((x)-'a'+1)
+
+void CCmdTestExecute::DoRunL()
+	{
+	LoadMemoryAccessL();
+	iTempBuf.CreateL(1024);
+	User::LeaveIfError(Stdin().CaptureKey(CTRL('c'), 0, 0)); // So we can do cleanup
+	Stdin().WaitForKey(iStatus);
+	SetActive();
+
+
+	User::LeaveIfError(iLogger.Connect()); // Keep it open
+	iLogger.CreateLog(_L("\\logs\\testexecute\\fshelllovesyou"), RTestExecuteLogServ::ELogModeOverWrite); // The server won't actually stay open unless you call CreateLog!
+
+	// Set up our proxy
+	iProxy = CProxyServer::NewInSeparateThreadL(_L("TestExecuteLogEngine"), this);
+
+	if (iScriptFile.Length())
+		{
+		LtkUtils::RLtkBuf cmdLine;
+		CleanupClosePushL(cmdLine);
+		cmdLine.AppendL(iScriptFile);
+		if (iDebug) cmdLine.AppendL(_L(" -d"));
+		if (iIncludes) cmdLine.AppendFormatL(_L(" -tci %S"), iIncludes);
+		if (iExcludes) cmdLine.AppendFormatL(_L(" -tcx %S"), iExcludes);
+
+		LeaveIfErr(iTefProc.Create(_L("testexecute.exe"), cmdLine), _L("Couldn't create testexecute.exe %S"), &cmdLine);
+		iLogonCompleter = new(ELeave) CLogonCompleter(this);
+		iTefProc.Resume();
+		CleanupStack::PopAndDestroy(&cmdLine);
+		}
+	else
+		{
+		// Just do some tests
+		RTestExecuteLogServ newlogger;
+		LeaveIfErr(newlogger.Connect(), _L("Couldn't connect to proxied RTestExecuteLogServ"));
+
+		newlogger.CreateLog(_L("\\logs\\testexecute\\scriptyscripty"), RTestExecuteLogServ::ELogModeOverWrite);
+		newlogger.Write(_L("I AM A LOG"));
+		newlogger.Close();
+		}
+	}
+
+TBool CCmdTestExecute::HandleMessageL(CProxySession* /*aSession*/, const RMessage2& aMessage)
+	{
+	switch (aMessage.Function())
+		{
+	case RTestExecuteLogServ::EWriteLog:
+		{
+		aMessage.ReadL(0, iTempBuf);
+		Write(iTempBuf.Expand());
+		break;
+		}
+	default:
+		break;
+		}
+
+	return EFalse; // We allow everything to go through to the real TEF as well
+	}
+
+void CCmdTestExecute::RunL()
+	{
+	if (Stdin().KeyCode() == CTRL('c'))
+		{
+		Printf(_L("CTRL-C detected, cleaning up proxy server...\r\n"));
+		iProxy->Destroy();
+		iProxy = NULL;
+		Printf(_L("Exiting...\r\n"));
+		SetErrorReported(ETrue); // Supress complaints about the cancel
+		Complete(KErrCancel);
+		}
+	else
+		{
+		Stdin().WaitForKey(iStatus);
+		SetActive();
+		}
+	}
+
+void CCmdTestExecute::DoCancel()
+	{
+	Stdin().WaitForKeyCancel();
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/commands/testexecute/testexecute.mmp	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,29 @@
+// testexecute.mmp
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <fshell/common.mmh>
+
+target			fshell_testexecute.exe
+targettype		exe
+uid				FSHELL_UID2_FSHELL_EXE FSHELL_UID_TESTEXECUTE
+capability		FSHELL_CAP_MMP_NORMAL
+
+userinclude		.
+#include <fshell/fsh_system_include.mmh>
+sourcepath		.
+source			testexecute.cpp
+source			proxyserver.cpp
+
+library			euser.lib
+library			iocli.lib
+library			ltkutils.lib
+library			testexecutelogclient.lib testexecuteutils.lib
--- a/core/group/bld.inf	Thu Jul 29 12:02:58 2010 +1000
+++ b/core/group/bld.inf	Thu Jul 29 12:03:43 2010 +1000
@@ -98,7 +98,6 @@
 
 .\autostart.script                     z:\system\console\scripts\autostart.script
 .\comm.script                          z:\system\console\scripts\comm.script
-.\fshell.bat                           \epoc32\tools\fshell.bat
 
 PRJ_MMPFILES
 gnumakefile .\fshell_version.mk
--- a/core/group/fshell.bat	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-@REM fshell.bat
-@REM 
-@REM Copyright (c) 2010 Accenture. All rights reserved.
-@REM This component and the accompanying materials are made available
-@REM under the terms of the "Eclipse Public License v1.0"
-@REM which accompanies this distribution, and is available
-@REM at the URL "http://www.eclipse.org/legal/epl-v10.html".
-@REM 
-@REM Initial Contributors:
-@REM Accenture - Initial contribution
-@REM
-@%epocroot%epoc32\release\winscw\udeb\fshell.exe -mltkconsole -dnogui  -- --console win32cons.dll %*
-@if %ERRORLEVEL% NEQ 0 echo fshell.exe exited with error %ERRORLEVEL%
\ No newline at end of file
--- a/core/src/command_factory.cpp	Thu Jul 29 12:02:58 2010 +1000
+++ b/core/src/command_factory.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -472,10 +472,6 @@
 			}
 		}
 
-	//_LIT(KDllExtension, ".dll");
-	//TUidType dllUids(KNullUid, KFshellDllUid, KNullUid);
-	//AppendExternalCommandsL(dllUids, KDllExtension);
-
 	_LIT(KExeExtension, ".exe");
 	TUidType exeUids(KNullUid, KFshellExeUid, KNullUid);
 	AppendExternalCommandsL(exeUids, KExeExtension);
--- a/documentation/common_mmh.pod	Thu Jul 29 12:02:58 2010 +1000
+++ b/documentation/common_mmh.pod	Thu Jul 29 12:03:43 2010 +1000
@@ -202,7 +202,7 @@
 
 Indicates that the baseline is recent enough to be aware of the flexible memory model. It doesn't necessarily mean that the flexible model is actually the one being used. It generally guards kernel APIs that weren't introduced until the FMM was (such as Kern::ChunkUserBase).
 
-=item FSHELL_SPCRE_SUPPORT
+=item FSHELL_[NO_]SPCRE_SUPPORT
 
 The regular expression libraries spcre.dll and libpcre.dll are available.
 
@@ -214,6 +214,10 @@
 
 The MemSpy Engine APIs are available.
 
+=item FSHELL_TESTEXECUTE_SUPPORT
+
+The TestExecute APIs are available.
+
 =back
 
 A couple of further macros follow - these are specifically for platforms that provide an custom implementation of the relevant command rather than using fshell's built-in version.
--- a/documentation/fshell_builddocs.mk	Thu Jul 29 12:02:58 2010 +1000
+++ b/documentation/fshell_builddocs.mk	Thu Jul 29 12:03:43 2010 +1000
@@ -9,13 +9,13 @@
 # Initial Contributors:
 # Accenture - Initial contribution
 #
-MAKMAKE :
-	..\tools\fsh-builddocs -i ../../epoc32/include pod-list.txt
+BLD :
+	..\tools\fsh-builddocs -i $(EPOCROOT)epoc32/include pod-list.txt
 
 RELEASABLES :
-	..\tools\fsh-builddocs -i ../../epoc32/include pod-list.txt -w
+	..\tools\fsh-builddocs -i $(EPOCROOT)epoc32/include pod-list.txt -w
 
 CLEAN :
-	..\tools\fsh-builddocs -i ../../epoc32/include pod-list.txt -c
+	..\tools\fsh-builddocs -i $(EPOCROOT)epoc32/include pod-list.txt -c
 
-MAKMAKE BLD FREEZE LIB CLEANLIB RESOURCE SAVESPACE FINAL : 
+MAKMAKE FREEZE LIB CLEANLIB RESOURCE SAVESPACE FINAL : 
--- a/documentation/getting_started.pod	Thu Jul 29 12:02:58 2010 +1000
+++ b/documentation/getting_started.pod	Thu Jul 29 12:03:43 2010 +1000
@@ -14,6 +14,8 @@
 
 __END__
 
+=head1 Getting started with FShell
+
 =head1 Retreiving the FShell Source Code
 
 I<Todo - add instructions for accessing the Mercurial repository.>
@@ -32,7 +34,7 @@
 
 =back
 
-Each of these platforms have a separate directory with F<\fshell\build>. In some platforms there may be further separate sub-directories for specific variants of the platform. You need to identify a suitable directory (that contains a file named F<bld.inf>) from which to build from. Open a command prompt and C<cd> to this directory.
+Each of these platforms have a separate directory with F<\fshell\build>. In some platforms there may be further separate sub-directories for specific variants of the platform. You need to identify a suitable directory (that contains a file named F<bld.inf>) from which to build from. For example to build for the Symbian^3 release you need to build from F<\fshell\build\sf\3>. Open a command prompt and C<cd> to this directory.
 
 You also need to identify the type of binaries you want to build. Common ones are:
 
@@ -48,11 +50,11 @@
 
 =item * C<gcce>
 
-Used for running fshell on either physical or simulated ARM hardware. Requires an installation of the GCC-E. I<Todo - does the SF provide builds of GCC-E?>
+Used for running fshell on either physical or simulated ARM hardware. Requires an installation of the GCC crosscompiler (for arm-none-symbianelf) - see here for more information: http://developer.symbian.org/wiki/index.php/The_GCCE_toolchain_initiative.
 
 =back
 
-Lastly, you need to identify the build variant you plan to use, either debug (C<udeb>) or release (C<urel>). Commonly, C<udeb> is used on the emulator whereas C<urel> is used on target hardward. For the purposes of this introduction we will assume that you will be building C<winscw udeb> and C<armv5 urel>.
+Lastly, you need to identify the build variant you plan to use, either debug (C<udeb>) or release (C<urel>). Commonly, C<udeb> is used on the emulator whereas C<urel> is used on target hardware. For the purposes of this introduction we will assume that you will be building C<winscw udeb> and C<armv5 urel>.
 
 =head2 SBSv1 (aka abld)
 
@@ -62,7 +64,25 @@
 
 =head2 SBSv2 (aka Raptor)
 
-  M:\fshell\build\sf\2>sbs -c armv5_urel -c winscw_udeb
+  M:\fshell\build\sf\2>sbs -c armv5_urel
+  M:\fshell\build\sf\2>sbs -c winscw_udeb
+
+I<Note:> There are currently some concurrency issues in the build process that mean we don't recommend building multiple platforms in a single invocation of sbs. Ie do the above rather than C<sbs -c armv5_urel -c winscw_udeb>. In some cases you may even need to add the option C<-j 1> to sbs to have it run completely single-threaded. We'll fix this as soon as we can!
+
+=head2 Notes on building for GCC
+
+Fshell has only been tested to build with GCC-E 4.4.1, and the legacy 3.4.2.
+
+I<Note:> The SF website appears to be out of date with regards to how to build with GCC-E on Raptor - at the time of writing the way to build is as follows:
+
+  S:\fshell\build\sf\3>set SBS_GCCE432BIN=Nothing
+  S:\fshell\build\sf\3>set SBS_GCCE433BIN=Nothing
+  S:\fshell\build\sf\3>set SBS_GCCE441BIN=c:/apps/gcce/bin
+  S:\fshell\build\sf\3>sbs -c arm.v5.urel.gcce4_4_1
+
+You may also need to update the compiler support libraries - I had to unzip rt_3_1_bin.zip from \sf\os\kernelhwsrv\kernel\eka\compsupp from a different baseline. (Unzip over \epoc32\release\armv5). The working libraries I used had datestamp of 28/1/2009, the non-working ones were 1/1/2009.
+
+There's one final gotcha if you want to build with GCC-E - at the time of writing the makefiles produced by SBS for PIPS executables is incorrect, therefore you need to add C<#define FSHELL_NO_PIPS_SUPPORT> to \fshell\build\sf\platform_shared.mmh. Hopefully this is a temporary measure.
 
 =head1 Installation
 
--- a/libraries/btrace_parser/inc/btrace_parser.h	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/btrace_parser/inc/btrace_parser.h	Thu Jul 29 12:03:43 2010 +1000
@@ -8,7 +8,7 @@
 // 
 // Initial Contributors:
 // Accenture - Initial contribution
-//
+
 // Backwards Compatibility:
 // The interfaces defined in this file should be considered INTERNAL to the
 // fshell project as they may be subject to change. Expect to have to absorb
--- a/libraries/iosrv/bwins/iocliu.def	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/iosrv/bwins/iocliu.def	Thu Jul 29 12:03:43 2010 +1000
@@ -542,4 +542,7 @@
 	?Type@TValue@IoUtils@@QBEIXZ @ 541 NONAME ; unsigned int IoUtils::TValue::Type(void) const
 	?ValuePtr@TValue@IoUtils@@QBEPAXXZ @ 542 NONAME ; void * IoUtils::TValue::ValuePtr(void) const
 	?EnumValueList@TValue@IoUtils@@QBEABVTDesC16@@XZ @ 543 NONAME ; class TDesC16 const & IoUtils::TValue::EnumValueList(void) const
+	?StringifyError@MCommandExtensionsV1@IoUtils@@UBEPBVTDesC16@@H@Z @ 544 NONAME ; class TDesC16 const * IoUtils::MCommandExtensionsV1::StringifyError(int) const
+	?ExtensionVersion@MCommandExtensionsV1@IoUtils@@UBE?AW4TCommandExtensionVersion@2@XZ @ 545 NONAME ; enum IoUtils::TCommandExtensionVersion IoUtils::MCommandExtensionsV1::ExtensionVersion(void) const
+	?SetExtension@CCommandBase@IoUtils@@IAEXPAVMCommandExtensionsV1@2@@Z @ 546 NONAME ; void IoUtils::CCommandBase::SetExtension(class IoUtils::MCommandExtensionsV1 *)
 
--- a/libraries/iosrv/client/command_base.cpp	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/iosrv/client/command_base.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -3067,7 +3067,12 @@
 	TOverflowTruncate overflow;
 	aDes = _L("Error: ");
 	aDes.AppendFormatList(aFmt, aList, &overflow);
-	aDes.AppendFormat(_L(" : %S (%d)\r\n"), &overflow, Stringify::Error(aError), aError);
+	const TDesC* errorDesc = NULL;
+	// See if we have an extension that knows about this error
+	if (iExtension) errorDesc = iExtension->StringifyError(aError);
+	// If the extension didn't know, fall back to Stringify::Error() to handle the system ones
+	if (errorDesc == NULL) errorDesc = Stringify::Error(aError);
+	aDes.AppendFormat(_L(" : %S (%d)\r\n"), &overflow, errorDesc, aError);
 	}
 
 void CCommandBase::FormatWarningText(TDes& aDes, TRefByValue<const TDesC> aFmt, VA_LIST& aList) const
@@ -3835,4 +3840,19 @@
 	iReadHandle.CancelNotifyChange();
 	}
 
-	
+// 
+
+EXPORT_C TCommandExtensionVersion MCommandExtensionsV1::ExtensionVersion() const
+	{
+	return ECommandExtensionV1;
+	}
+
+EXPORT_C const TDesC* MCommandExtensionsV1::StringifyError(TInt /*aError*/) const
+	{
+	return NULL; // By default we don't have anything additional
+	}
+
+EXPORT_C void CCommandBase::SetExtension(MCommandExtensionsV1* aExtension)
+	{
+	iExtension = aExtension;
+	}
--- a/libraries/iosrv/eabi/iocliu.def	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/iosrv/eabi/iocliu.def	Thu Jul 29 12:03:43 2010 +1000
@@ -614,4 +614,9 @@
 	_ZNK7IoUtils6TValue4TypeEv @ 613 NONAME
 	_ZNK7IoUtils6TValue8ValuePtrEv @ 614 NONAME
 	_ZNK7IoUtils6TValue13EnumValueListEv @ 615 NONAME
+	_ZN7IoUtils12CCommandBase12SetExtensionEPNS_20MCommandExtensionsV1E @ 616 NONAME
+	_ZNK7IoUtils20MCommandExtensionsV114StringifyErrorEi @ 617 NONAME
+	_ZNK7IoUtils20MCommandExtensionsV116ExtensionVersionEv @ 618 NONAME
+	_ZTIN7IoUtils20MCommandExtensionsV1E @ 619 NONAME
+	_ZTVN7IoUtils20MCommandExtensionsV1E @ 620 NONAME
 
--- a/libraries/iosrv/inc/ioutils.h	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/iosrv/inc/ioutils.h	Thu Jul 29 12:03:43 2010 +1000
@@ -638,6 +638,20 @@
 	static HBufC* ReadLC(TLex& aLex, const TChar& aEscapeChar, CCommandBase* aErrorContext, TUint aReadMode);
 	};
 
+enum TCommandExtensionVersion
+	{
+	ECommandExtensionV1 = 1,
+	};
+
+class MCommandExtensionsV1
+	{
+public:
+	IMPORT_C virtual TCommandExtensionVersion ExtensionVersion() const; // Don't override this yourself!
+	
+	// Override this if you have custom error codes you want CCommandBase to understand
+	IMPORT_C virtual const TDesC* StringifyError(TInt aError) const;
+	};
+
 class CCommandBase : public CActive
 	{
 public:
@@ -713,6 +727,7 @@
 protected:
 	IMPORT_C CCommandBase();
 	IMPORT_C CCommandBase(TUint aFlags);
+	IMPORT_C void SetExtension(MCommandExtensionsV1* aExtension);
 	IMPORT_C virtual void BaseConstructL();
 	IMPORT_C void CreateEnvironmentL(CEnvironment* aEnv);
 
@@ -796,11 +811,11 @@
 	CReaderChangeNotifier* iReadChangeNotifier;
 	TInt iCompletionReason;
 	CCommandInfoFile* iCif;
+	MCommandExtensionsV1* iExtension;
 	void* iSpare1;
 	void* iSpare2;
 	void* iSpare3;
 	void* iSpare4;
-	void* iSpare5;
 	};
 
 
--- a/libraries/memoryaccess/MemoryAccess.mmp	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/memoryaccess/MemoryAccess.mmp	Thu Jul 29 12:03:43 2010 +1000
@@ -36,7 +36,9 @@
 source		hwbreak.cia
 #endif
 
-#ifdef EABI
+#if defined(EABI) && !defined(GCCE)
+macro		SUPPORT_BREAKPOINT_STUFF
+// This doesn't build with GCC-E
 source		TrkNextInstructionAfterPC.cpp
 #endif
 
--- a/libraries/memoryaccess/fdebuggerkernel.cpp	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/memoryaccess/fdebuggerkernel.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -1496,7 +1496,7 @@
 
 TInt DDebuggerEventHandler::MoveBreakpointToNextInstructionForThread(DThread* aThread, SBreakpoint* aBreakpoint)
 	{
-#ifdef __EABI__
+#ifdef SUPPORT_BREAKPOINT_STUFF
 	ASSERT_BREAKPOINT_LOCKED();
 	TUint32 notUsed = 0;
 	TBool aModeChange = EFalse;
--- a/libraries/spcre/bwins/spcreu.def	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/spcre/bwins/spcreu.def	Thu Jul 29 12:03:43 2010 +1000
@@ -4,32 +4,32 @@
 	?GlobalReplaceL@CRegEx@@QBEHABVTDesC8@@AAVTDes8@@@Z @ 3 NONAME ; int CRegEx::GlobalReplaceL(class TDesC8 const &, class TDes8 &) const
 	?FindAndConsumeL@CRegEx@@QBEHAAVTDes8@@@Z @ 4 NONAME ; int CRegEx::FindAndConsumeL(class TDes8 &) const
 	?ParseTUint8Hex@TRegExArg@@SAHABVTDesC8@@PAX@Z @ 5 NONAME ; int TRegExArg::ParseTUint8Hex(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PAVTChar@@P6AHABVTDesC8@@PAX@Z@Z @ 6 NONAME ; TRegExArg::TRegExArg(class TChar *, int (*)(class TDesC8 const &, void *))
-	??0TRegExArg@@QAE@PAJ@Z @ 7 NONAME ; TRegExArg::TRegExArg(long *)
-	??0TRegExArg@@QAE@PAJP6AHABVTDesC8@@PAX@Z@Z @ 8 NONAME ; TRegExArg::TRegExArg(long *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAVTChar@@P6AHABVTDesC8@@PAX@Z@Z @ 6 NONAME ABSENT ; TRegExArg::TRegExArg(class TChar *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAJ@Z @ 7 NONAME ABSENT ; TRegExArg::TRegExArg(long *)
+	??0TRegExArg@@QAE@PAJP6AHABVTDesC8@@PAX@Z@Z @ 8 NONAME ABSENT ; TRegExArg::TRegExArg(long *, int (*)(class TDesC8 const &, void *))
 	??0TRegExOptions@@QAE@XZ @ 9 NONAME ; TRegExOptions::TRegExOptions(void)
 	?PartialMatchL@CRegEx@@QBEHABVTDesC8@@ABVTRegExArg@@11@Z @ 10 NONAME ; int CRegEx::PartialMatchL(class TDesC8 const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	?DoMatchL@CRegEx@@QBEHABVTDesC8@@W4TAnchor@1@AAHABV?$RPointerArray@$$CBVTRegExArg@@@@@Z @ 11 NONAME ; int CRegEx::DoMatchL(class TDesC8 const &, enum CRegEx::TAnchor, int &, class RPointerArray<class TRegExArg const > const &) const
 	?ParseTReal32@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 12 NONAME ; int TRegExArg::ParseTReal32(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PAVTPtrC8@@P6AHABVTDesC8@@PAX@Z@Z @ 13 NONAME ; TRegExArg::TRegExArg(class TPtrC8 *, int (*)(class TDesC8 const &, void *))
-	??0TRegExArg@@QAE@PAE@Z @ 14 NONAME ; TRegExArg::TRegExArg(unsigned char *)
+	??0TRegExArg@@QAE@PAVTPtrC8@@P6AHABVTDesC8@@PAX@Z@Z @ 13 NONAME ABSENT ; TRegExArg::TRegExArg(class TPtrC8 *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAE@Z @ 14 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned char *)
 	?ParseTInt16@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 15 NONAME ; int TRegExArg::ParseTInt16(class TDesC8 const &, void *)
 	?FindAndConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@111@Z @ 16 NONAME ; int CRegEx::FindAndConsumeL(class TDes8 &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	?FullMatchL@CRegEx@@QBEHABVTDesC8@@ABVTRegExArg@@@Z @ 17 NONAME ; int CRegEx::FullMatchL(class TDesC8 const &, class TRegExArg const &) const
 	?FindAndConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@11@Z @ 18 NONAME ; int CRegEx::FindAndConsumeL(class TDes8 &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
-	??0TRegExArg@@QAE@PAMP6AHABVTDesC8@@PAX@Z@Z @ 19 NONAME ; TRegExArg::TRegExArg(float *, int (*)(class TDesC8 const &, void *))
-	??0TRegExArg@@QAE@PACP6AHABVTDesC8@@PAX@Z@Z @ 20 NONAME ; TRegExArg::TRegExArg(signed char *, int (*)(class TDesC8 const &, void *))
-	??0TRegExArg@@QAE@PAVTDes8@@P6AHABVTDesC8@@PAX@Z@Z @ 21 NONAME ; TRegExArg::TRegExArg(class TDes8 *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAMP6AHABVTDesC8@@PAX@Z@Z @ 19 NONAME ABSENT ; TRegExArg::TRegExArg(float *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PACP6AHABVTDesC8@@PAX@Z@Z @ 20 NONAME ABSENT ; TRegExArg::TRegExArg(signed char *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAVTDes8@@P6AHABVTDesC8@@PAX@Z@Z @ 21 NONAME ABSENT ; TRegExArg::TRegExArg(class TDes8 *, int (*)(class TDesC8 const &, void *))
 	?FullMatchL@CRegEx@@QBEHABVTDesC8@@ABVTRegExArg@@111@Z @ 22 NONAME ; int CRegEx::FullMatchL(class TDesC8 const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	?ExtractL@CRegEx@@QBEHABVTDesC8@@0AAVTDes8@@@Z @ 23 NONAME ; int CRegEx::ExtractL(class TDesC8 const &, class TDesC8 const &, class TDes8 &) const
-	??0TRegExArg@@QAE@PAVTChar@@@Z @ 24 NONAME ; TRegExArg::TRegExArg(class TChar *)
+	??0TRegExArg@@QAE@PAVTChar@@@Z @ 24 NONAME ABSENT ; TRegExArg::TRegExArg(class TChar *)
 	?ParseTInt@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 25 NONAME ; int TRegExArg::ParseTInt(class TDesC8 const &, void *)
 	?ReplaceL@CRegEx@@QBEHABVTDesC8@@AAVTDes8@@@Z @ 26 NONAME ; int CRegEx::ReplaceL(class TDesC8 const &, class TDes8 &) const
 	?ParseTInt32@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 27 NONAME ; int TRegExArg::ParseTInt32(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PAG@Z @ 28 NONAME ; TRegExArg::TRegExArg(unsigned short *)
+	??0TRegExArg@@QAE@PAG@Z @ 28 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned short *)
 	?ParseTInt64Hex@TRegExArg@@SAHABVTDesC8@@PAX@Z @ 29 NONAME ; int TRegExArg::ParseTInt64Hex(class TDesC8 const &, void *)
 	?FullMatchL@CRegEx@@QBEHABVTDesC8@@@Z @ 30 NONAME ; int CRegEx::FullMatchL(class TDesC8 const &) const
-	??0TRegExArg@@QAE@PAK@Z @ 31 NONAME ; TRegExArg::TRegExArg(unsigned long *)
+	??0TRegExArg@@QAE@PAK@Z @ 31 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned long *)
 	?PartialMatchL@CRegEx@@QBEHABVTDesC8@@ABVTRegExArg@@111@Z @ 32 NONAME ; int CRegEx::PartialMatchL(class TDesC8 const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	??0TRegExArg@@QAE@PAIP6AHABVTDesC8@@PAX@Z@Z @ 33 NONAME ; TRegExArg::TRegExArg(unsigned int *, int (*)(class TDesC8 const &, void *))
 	??0TRegExArg@@QAE@PANP6AHABVTDesC8@@PAX@Z@Z @ 34 NONAME ; TRegExArg::TRegExArg(double *, int (*)(class TDesC8 const &, void *))
@@ -39,15 +39,15 @@
 	?FindAndConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@1@Z @ 38 NONAME ; int CRegEx::FindAndConsumeL(class TDes8 &, class TRegExArg const &, class TRegExArg const &) const
 	?DoMatchL@CRegEx@@QBEHABVTDesC8@@W4TAnchor@1@AAHABVTRegExArg@@333@Z @ 39 NONAME ; int CRegEx::DoMatchL(class TDesC8 const &, enum CRegEx::TAnchor, int &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	?ConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@1@Z @ 40 NONAME ; int CRegEx::ConsumeL(class TDes8 &, class TRegExArg const &, class TRegExArg const &) const
-	??0TRegExArg@@QAE@PAFP6AHABVTDesC8@@PAX@Z@Z @ 41 NONAME ; TRegExArg::TRegExArg(short *, int (*)(class TDesC8 const &, void *))
-	??0TRegExArg@@QAE@PAN@Z @ 42 NONAME ; TRegExArg::TRegExArg(double *)
+	??0TRegExArg@@QAE@PAFP6AHABVTDesC8@@PAX@Z@Z @ 41 NONAME ABSENT ; TRegExArg::TRegExArg(short *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAN@Z @ 42 NONAME ABSENT ; TRegExArg::TRegExArg(double *)
 	?FindAndConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@@Z @ 43 NONAME ; int CRegEx::FindAndConsumeL(class TDes8 &, class TRegExArg const &) const
-	??0TRegExArg@@QAE@PAGP6AHABVTDesC8@@PAX@Z@Z @ 44 NONAME ; TRegExArg::TRegExArg(unsigned short *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAGP6AHABVTDesC8@@PAX@Z@Z @ 44 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned short *, int (*)(class TDesC8 const &, void *))
 	?DoMatchL@CRegEx@@QBEHABVTDesC8@@W4TAnchor@1@AAHABVTRegExArg@@@Z @ 45 NONAME ; int CRegEx::DoMatchL(class TDesC8 const &, enum CRegEx::TAnchor, int &, class TRegExArg const &) const
 	?ParseTInt8@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 46 NONAME ; int TRegExArg::ParseTInt8(class TDesC8 const &, void *)
 	?ParseTInt64Radix@TRegExArg@@CAHABVTDesC8@@PAXW4TRadix@@@Z @ 47 NONAME ; int TRegExArg::ParseTInt64Radix(class TDesC8 const &, void *, enum TRadix)
 	?ParseTInt64@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 48 NONAME ; int TRegExArg::ParseTInt64(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PAM@Z @ 49 NONAME ; TRegExArg::TRegExArg(float *)
+	??0TRegExArg@@QAE@PAM@Z @ 49 NONAME ABSENT ; TRegExArg::TRegExArg(float *)
 	?ParseTUint@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 50 NONAME ; int TRegExArg::ParseTUint(class TDesC8 const &, void *)
 	?DoMatchL@CRegEx@@QBEHABVTDesC8@@W4TAnchor@1@AAH@Z @ 51 NONAME ; int CRegEx::DoMatchL(class TDesC8 const &, enum CRegEx::TAnchor, int &) const
 	??1CRegEx@@UAE@XZ @ 52 NONAME ; CRegEx::~CRegEx(void)
@@ -68,10 +68,10 @@
 	?ParseTUint8Octal@TRegExArg@@SAHABVTDesC8@@PAX@Z @ 67 NONAME ; int TRegExArg::ParseTUint8Octal(class TDesC8 const &, void *)
 	?NewLC@CRegEx@@SAPAV1@ABVTDesC8@@@Z @ 68 NONAME ; class CRegEx * CRegEx::NewLC(class TDesC8 const &)
 	?ParseTDes8@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 69 NONAME ; int TRegExArg::ParseTDes8(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PAI@Z @ 70 NONAME ; TRegExArg::TRegExArg(unsigned int *)
+	??0TRegExArg@@QAE@PAI@Z @ 70 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned int *)
 	?PartialMatchL@CRegEx@@QBEHABVTDesC8@@@Z @ 71 NONAME ; int CRegEx::PartialMatchL(class TDesC8 const &) const
 	?ParseTUint8@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 72 NONAME ; int TRegExArg::ParseTUint8(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PAKP6AHABVTDesC8@@PAX@Z@Z @ 73 NONAME ; TRegExArg::TRegExArg(unsigned long *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAKP6AHABVTDesC8@@PAX@Z@Z @ 73 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned long *, int (*)(class TDesC8 const &, void *))
 	?ParseTInt64Octal@TRegExArg@@SAHABVTDesC8@@PAX@Z @ 74 NONAME ; int TRegExArg::ParseTInt64Octal(class TDesC8 const &, void *)
 	?ConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@@Z @ 75 NONAME ; int CRegEx::ConsumeL(class TDes8 &, class TRegExArg const &) const
 	?ParseTUint8Radix@TRegExArg@@CAHABVTDesC8@@PAXW4TRadix@@@Z @ 76 NONAME ; int TRegExArg::ParseTUint8Radix(class TDesC8 const &, void *, enum TRadix)
@@ -79,23 +79,23 @@
 	??0TRegExArg@@QAE@PAH@Z @ 78 NONAME ; TRegExArg::TRegExArg(int *)
 	?ConsumeL@CRegEx@@QBEHAAVTDes8@@@Z @ 79 NONAME ; int CRegEx::ConsumeL(class TDes8 &) const
 	?ParseTUint16Hex@TRegExArg@@SAHABVTDesC8@@PAX@Z @ 80 NONAME ; int TRegExArg::ParseTUint16Hex(class TDesC8 const &, void *)
-	??0TRegExArg@@QAE@PA_J@Z @ 81 NONAME ; TRegExArg::TRegExArg(long long *)
+	??0TRegExArg@@QAE@PA_J@Z @ 81 NONAME ABSENT ; TRegExArg::TRegExArg(long long *)
 	?NewL@CRegEx@@SAPAV1@ABVTDesC8@@@Z @ 82 NONAME ; class CRegEx * CRegEx::NewL(class TDesC8 const &)
 	?FullMatchL@CRegEx@@QBEHABVTDesC8@@ABVTRegExArg@@11@Z @ 83 NONAME ; int CRegEx::FullMatchL(class TDesC8 const &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	?FullMatchL@CRegEx@@QBEHABVTDesC8@@ABVTRegExArg@@1@Z @ 84 NONAME ; int CRegEx::FullMatchL(class TDesC8 const &, class TRegExArg const &, class TRegExArg const &) const
 	?QuoteMetaL@CRegEx@@SAPAVHBufC8@@ABVTDesC8@@@Z @ 85 NONAME ; class HBufC8 * CRegEx::QuoteMetaL(class TDesC8 const &)
-	??0TRegExArg@@QAE@PAVTDes8@@@Z @ 86 NONAME ; TRegExArg::TRegExArg(class TDes8 *)
+	??0TRegExArg@@QAE@PAVTDes8@@@Z @ 86 NONAME ABSENT ; TRegExArg::TRegExArg(class TDes8 *)
 	?ConsumeL@CRegEx@@QBEHAAVTDes8@@ABVTRegExArg@@11@Z @ 87 NONAME ; int CRegEx::ConsumeL(class TDes8 &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	?NewLC@CRegEx@@SAPAV1@ABVTDesC8@@ABVTRegExOptions@@@Z @ 88 NONAME ; class CRegEx * CRegEx::NewLC(class TDesC8 const &, class TRegExOptions const &)
-	??0TRegExArg@@QAE@PAC@Z @ 89 NONAME ; TRegExArg::TRegExArg(signed char *)
-	??0TRegExArg@@QAE@PAVTPtrC8@@@Z @ 90 NONAME ; TRegExArg::TRegExArg(class TPtrC8 *)
-	??0TRegExArg@@QAE@PAF@Z @ 91 NONAME ; TRegExArg::TRegExArg(short *)
-	??0TRegExArg@@QAE@PAEP6AHABVTDesC8@@PAX@Z@Z @ 92 NONAME ; TRegExArg::TRegExArg(unsigned char *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAC@Z @ 89 NONAME ABSENT ; TRegExArg::TRegExArg(signed char *)
+	??0TRegExArg@@QAE@PAVTPtrC8@@@Z @ 90 NONAME ABSENT ; TRegExArg::TRegExArg(class TPtrC8 *)
+	??0TRegExArg@@QAE@PAF@Z @ 91 NONAME ABSENT ; TRegExArg::TRegExArg(short *)
+	??0TRegExArg@@QAE@PAEP6AHABVTDesC8@@PAX@Z@Z @ 92 NONAME ABSENT ; TRegExArg::TRegExArg(unsigned char *, int (*)(class TDesC8 const &, void *))
 	?ParseTPtrC8@TRegExArg@@CAHABVTDesC8@@PAX@Z @ 93 NONAME ; int TRegExArg::ParseTPtrC8(class TDesC8 const &, void *)
 	?DoMatchL@CRegEx@@QBEHABVTDesC8@@W4TAnchor@1@AAHABVTRegExArg@@33@Z @ 94 NONAME ; int CRegEx::DoMatchL(class TDesC8 const &, enum CRegEx::TAnchor, int &, class TRegExArg const &, class TRegExArg const &, class TRegExArg const &) const
 	??0TRegExOptions@@QAE@I@Z @ 95 NONAME ; TRegExOptions::TRegExOptions(unsigned int)
 	?ParseTUint32Radix@TRegExArg@@CAHABVTDesC8@@PAXW4TRadix@@@Z @ 96 NONAME ; int TRegExArg::ParseTUint32Radix(class TDesC8 const &, void *, enum TRadix)
-	??0TRegExArg@@QAE@PA_JP6AHABVTDesC8@@PAX@Z@Z @ 97 NONAME ; TRegExArg::TRegExArg(long long *, int (*)(class TDesC8 const &, void *))
-	??0TRegExArg@@QAE@PAHP6AHABVTDesC8@@PAX@Z@Z @ 98 NONAME ; TRegExArg::TRegExArg(int *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PA_JP6AHABVTDesC8@@PAX@Z@Z @ 97 NONAME ABSENT ; TRegExArg::TRegExArg(long long *, int (*)(class TDesC8 const &, void *))
+	??0TRegExArg@@QAE@PAHP6AHABVTDesC8@@PAX@Z@Z @ 98 NONAME ABSENT ; TRegExArg::TRegExArg(int *, int (*)(class TDesC8 const &, void *))
 	?NewL@CRegEx@@SAPAV1@ABVTDesC16@@ABVTRegExOptions@@@Z @ 99 NONAME ; class CRegEx * CRegEx::NewL(class TDesC16 const &, class TRegExOptions const &)
 
--- a/libraries/spcre/inc/tregexarg.h	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/spcre/inc/tregexarg.h	Thu Jul 29 12:03:43 2010 +1000
@@ -51,8 +51,8 @@
 	 
 // Type-specific parsers
 #define PCRE_MAKE_PARSER(type,name)															\
-	IMPORT_C TRegExArg(type* aType) : iArg(aType), iParser(name) { }						\
-	IMPORT_C TRegExArg(type* aType, Parser aParser) : iArg(aType), iParser(aParser) { }	
+	inline TRegExArg(type* aType) : iArg(aType), iParser(name) { }						\
+	inline TRegExArg(type* aType, Parser aParser) : iArg(aType), iParser(aParser) { }	
 	
 	PCRE_MAKE_PARSER(TChar,				ParseTChar)
 	PCRE_MAKE_PARSER(TInt8,				ParseTInt8)
--- a/libraries/spcre/libpcre/group/libpcre.mmp	Thu Jul 29 12:02:58 2010 +1000
+++ b/libraries/spcre/libpcre/group/libpcre.mmp	Thu Jul 29 12:03:43 2010 +1000
@@ -62,3 +62,9 @@
 
 library         euser.lib
 library         estlib.lib
+
+// Remove some of the many warnings that armcc doesn't like
+// Warning:  #546-D: transfer of control bypasses initialization of:
+// Warning:  #1134-D: literal treated as "long long"
+// Warning: C2874W: othercase may be used before being set
+option ARMCC --diag-supress 1134,2874,546
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/common/BMARM/console.def	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,3 @@
+EXPORTS
+	NewConsole @ 1 NONAME R3UNUSED ; (null)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/common/bwins/console.def	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,3 @@
+EXPORTS
+	NewConsole @ 1 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/common/eabi/console.def	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,3 @@
+EXPORTS
+	NewConsole @ 1 NONAME
+
--- a/plugins/consoles/defcons/bmarm/defconsu.def	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
-	NewConsole @ 1 NONAME R3UNUSED ; (null)
-
--- a/plugins/consoles/defcons/bwins/defconsu.def	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
-	NewConsole @ 1 NONAME
-
--- a/plugins/consoles/defcons/eabi/defconsu.def	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
-	NewConsole @ 1 NONAME
-
--- a/plugins/consoles/defcons/src/defcons.mmp	Thu Jul 29 12:02:58 2010 +1000
+++ b/plugins/consoles/defcons/src/defcons.mmp	Thu Jul 29 12:03:43 2010 +1000
@@ -14,9 +14,11 @@
 
 TARGET			defcons.dll
 TARGETTYPE		dll
-UID             0x1000008d 0x100039e7
+UID				0x1000008d 0x100039e7
+CAPABILITY		FSHELL_CAP_MMP_NORMAL
 
-CAPABILITY		FSHELL_CAP_MMP_NORMAL
+DEFFILE			..\..\common\~\console.def
+NOSTRICTDEF
 
 #include <fshell/fsh_system_include.mmh>
 
--- a/plugins/consoles/nullcons/BMARM/nullconsU.DEF	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
-	NewConsole @ 1 NONAME R3UNUSED ; (null)
-
--- a/plugins/consoles/nullcons/bwins/nullconsu.def	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
-	NewConsole @ 1 NONAME
-
--- a/plugins/consoles/nullcons/eabi/nullconsu.def	Thu Jul 29 12:02:58 2010 +1000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-EXPORTS
-	NewConsole @ 1 NONAME
-
--- a/plugins/consoles/nullcons/src/nullcons.mmp	Thu Jul 29 12:02:58 2010 +1000
+++ b/plugins/consoles/nullcons/src/nullcons.mmp	Thu Jul 29 12:03:43 2010 +1000
@@ -14,9 +14,11 @@
 
 TARGET			nullcons.dll
 TARGETTYPE		dll
-UID             0x1000008d 0x100039e7
+UID				0x1000008d 0x100039e7
+CAPABILITY		FSHELL_CAP_MMP_NORMAL
 
-CAPABILITY		FSHELL_CAP_MMP_NORMAL
+DEFFILE			..\..\common\~\console.def
+NOSTRICTDEF
 
 #include <fshell/fsh_system_include.mmh>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/tefcons/bld.inf	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,21 @@
+// bld.inf
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+#ifndef FSHELL_COMMON_MMH
+#include <fshell/common.mmh>
+#endif
+
+PRJ_EXPORTS
+//TODO sort this FSHELL_ROM_INCLUDE(tefcons.iby)
+
+PRJ_MMPFILES
+tefcons.mmp
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/tefcons/tefcons.cpp	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,164 @@
+// tefcons.cpp
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <e32std.h>
+#include <e32cons.h>
+#include <e32keys.h>
+#include <test/testexecutelogger.h>
+#include <fshell/consoleextensions.h>
+
+NONSHARABLE_CLASS(CTefConsole) : public CConsoleBase
+	{
+public:
+	CTefConsole();
+	virtual ~CTefConsole();
+	virtual TInt Create(const TDesC &aTitle,TSize aSize);
+	virtual void Read(TRequestStatus &aStatus);
+	virtual void ReadCancel();
+	virtual void Write(const TDesC &aDes);
+	virtual TPoint CursorPos() const;
+	virtual void SetCursorPosAbs(const TPoint &aPoint);
+	virtual void SetCursorPosRel(const TPoint &aPoint);
+	virtual void SetCursorHeight(TInt aPercentage);
+	virtual void SetTitle(const TDesC &aTitle);
+	virtual void ClearScreen();
+	virtual void ClearToEndOfLine();
+	virtual TSize ScreenSize() const;
+	virtual TKeyCode KeyCode() const;
+	virtual TUint KeyModifiers() const;
+	virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);
+
+	void WriteStdErr(const TDesC &aDes);
+
+private:
+	CTestExecuteLogger* iLogger;
+	};
+
+CTefConsole::CTefConsole()
+	{
+	}
+
+TInt CTefConsole::Create(const TDesC& aTitle, TSize /*aSize*/)
+	{
+	iLogger = new CTestExecuteLogger();
+	if (!iLogger) return KErrNoMemory;
+	TInt logMode = TLoggerOptions(ELogHTMLOnly);
+	TInt logLevel = RFileFlogger::TLogSeverity(ESevrAll);
+	iLogger->SetLoggerOptions(logMode);
+	TInt err = iLogger->Connect();
+	if (err) return err;
+	const TDesC& logFilePath(aTitle);
+	err = iLogger->HtmlLogger().CreateLog(logFilePath, RTestExecuteLogServ::ELogModeAppend);
+	if (err) return err;
+	iLogger->HtmlLogger().SetLogLevel(TLogSeverity(logLevel));
+
+	iLogger->HtmlLogger().Write(_L("<pre>\r\n")); // horrible horrible tef logging - the client is responsible for writing markup!
+	return KErrNone;
+	}
+
+
+CTefConsole::~CTefConsole()
+	{
+	if (iLogger)
+		{
+		iLogger->HtmlLogger().Write(_L("</pre>\r\n")); // horrible horrible tef logging - the client is responsible for writing markup!
+		iLogger->Close();
+		delete iLogger;
+		}
+	}
+
+void CTefConsole::Read(TRequestStatus &aStatus)
+	{
+	TRequestStatus *pS=(&aStatus);
+	User::RequestComplete(pS, KErrNotSupported);
+	}
+
+void CTefConsole::ReadCancel()
+	{
+	}
+
+void CTefConsole::Write(const TDesC& aDes)
+	{
+	//TODO sort out the file and line
+	//iLogger->LogExtra(((TText8*)__FILE__), __LINE__, ESevrInfo, aDes);
+	iLogger->HtmlLogger().Write(aDes);
+	}
+
+void CTefConsole::WriteStdErr(const TDesC &aDes)
+	{
+	//iLogger->LogExtra(((TText8*)__FILE__), __LINE__, ESevrErr, aDes);
+	iLogger->HtmlLogger().Write(aDes);
+	}
+
+TPoint CTefConsole::CursorPos() const
+	{
+	return TPoint(0,0);
+	}
+
+void CTefConsole::SetCursorPosAbs(const TPoint& /*aPoint*/)
+	{
+	}
+
+void CTefConsole::SetCursorPosRel(const TPoint& /*aPoint*/)
+	{
+	}
+
+void CTefConsole::SetCursorHeight(TInt /*aPercentage*/)
+	{
+	}
+
+void CTefConsole::SetTitle(const TDesC& /*aTitle*/)
+	{
+	}
+
+void CTefConsole::ClearScreen()
+	{
+	}
+
+void CTefConsole::ClearToEndOfLine()
+	{
+	}
+
+TSize CTefConsole::ScreenSize() const
+	{
+	return TSize(10,10);
+	}
+
+TKeyCode CTefConsole::KeyCode() const
+	{
+	return EKeyNull;
+	}
+
+TUint CTefConsole::KeyModifiers() const
+	{
+	return 0;
+	}
+
+extern "C" EXPORT_C TAny *NewConsole()
+	{
+	return(new CTefConsole);
+	}
+
+TInt CTefConsole::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
+	{
+	if (aExtensionId == ConsoleStdErr::KWriteStdErrConsoleExtension)
+		{
+		TDesC* des = (TDesC*)a1;
+		WriteStdErr(*des);
+		return KErrNone;
+		}
+	else
+		{
+		return CConsoleBase::Extension_(aExtensionId, a0, a1);
+		}
+	
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/tefcons/tefcons.mmp	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,29 @@
+// tefcons.mmp
+// 
+// Copyright (c) 2010 Accenture. All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+// 
+// Initial Contributors:
+// Accenture - Initial contribution
+//
+
+#include <fshell/common.mmh>
+
+TARGET			tefcons.dll
+TARGETTYPE		dll
+UID				0x1000008d 0x100039e7
+CAPABILITY		FSHELL_CAP_MMP_NORMAL
+
+DEFFILE			..\common\~\console.def
+NOSTRICTDEF
+
+#include <fshell/fsh_system_include.mmh>
+
+SOURCEPATH		.
+SOURCE			tefcons.cpp
+
+LIBRARY			euser.lib
+LIBRARY			testexecutelogclient.lib testexecuteutils.lib
--- a/plugins/consoles/win32cons/group/bld.inf	Thu Jul 29 12:02:58 2010 +1000
+++ b/plugins/consoles/win32cons/group/bld.inf	Thu Jul 29 12:03:43 2010 +1000
@@ -13,6 +13,11 @@
 #include <fshell/common.mmh>
 #endif
 
+PRJ_EXPORTS
+
+.\fshell.bat                           \epoc32\tools\fshell.bat
+.\fshellconsole.ini                    \epoc32\data\fshellconsole.ini
+
 PRJ_MMPFILES
 
 #if defined(WINS)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/win32cons/group/fshell.bat	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,13 @@
+@REM fshell.bat
+@REM 
+@REM Copyright (c) 2010 Accenture. All rights reserved.
+@REM This component and the accompanying materials are made available
+@REM under the terms of the "Eclipse Public License v1.0"
+@REM which accompanies this distribution, and is available
+@REM at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@REM 
+@REM Initial Contributors:
+@REM Accenture - Initial contribution
+@REM
+@%epocroot%epoc32\release\winscw\udeb\fshell.exe -mfshellconsole -dnogui  -- --console win32cons.dll %*
+@if %ERRORLEVEL% NEQ 0 echo fshell.exe exited with error %ERRORLEVEL%
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/consoles/win32cons/group/fshellconsole.ini	Thu Jul 29 12:03:43 2010 +1000
@@ -0,0 +1,16 @@
+# fshellconsole.ini
+# 
+# Copyright (c) 2010 Accenture. All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+# 
+# Initial Contributors:
+# Accenture - Initial contribution
+#
+PlatSecEnforcement ON
+PlatSecDiagnostics ON
+PlatSecProcessIsolation ON
+PlatSecEnforceSysBin ON
+PlatSecDisabledCaps NONE
--- a/tools/fsh-builddocs	Thu Jul 29 12:02:58 2010 +1000
+++ b/tools/fsh-builddocs	Thu Jul 29 12:03:43 2010 +1000
@@ -9,7 +9,7 @@
 # 
 # Initial Contributors:
 # Accenture - Initial contribution
-#
+
 # Description:
 # fsh-builddocs - A tool that generates HTML documentation from POD source files.
 
--- a/tools/fsh-buildsis	Thu Jul 29 12:02:58 2010 +1000
+++ b/tools/fsh-buildsis	Thu Jul 29 12:03:43 2010 +1000
@@ -1,7 +1,7 @@
 #!perl
 # fsh-buildsis
 # 
-# Copyright (c) 2008-2010 Accenture. All rights reserved.
+# Copyright (c) 2008 - 2010 Accenture. All rights reserved.
 # This component and the accompanying materials are made available
 # under the terms of the "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
@@ -9,7 +9,7 @@
 # 
 # Initial Contributors:
 # Accenture - Initial contribution
-#
+
 # Description:
 # fsh-buildsis - A tool that generates SIS files.
 
@@ -77,7 +77,7 @@
   #
   # 1) Run the pre-processor over the supplied .iby file and capture the output
   #    to a temporary file.
-  my $tempFileName = "$ENV{TEMP}\\ltkbs_temp.pkg";
+  my $tempFileName = "$ENV{TEMP}\\fsh-buildsis_temp.pkg";
   if (-e $tempFileName) {
     unlink $tempFileName;
   }
--- a/tools/fsh-buildsis.bat	Thu Jul 29 12:02:58 2010 +1000
+++ b/tools/fsh-buildsis.bat	Thu Jul 29 12:03:43 2010 +1000
@@ -1,3 +1,14 @@
+@REM fsh-buildsis.bat
+@REM 
+@REM Copyright (c) 2010 Accenture. All rights reserved.
+@REM This component and the accompanying materials are made available
+@REM under the terms of the "Eclipse Public License v1.0"
+@REM which accompanies this distribution, and is available
+@REM at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@REM 
+@REM Initial Contributors:
+@REM Accenture - Initial contribution
+@REM
 @echo off
 set script=%0%
 set script=%script:.bat=%
--- a/tools/fshell_copyright.pl	Thu Jul 29 12:02:58 2010 +1000
+++ b/tools/fshell_copyright.pl	Thu Jul 29 12:03:43 2010 +1000
@@ -48,7 +48,7 @@
   my @newlines = ();
   
   my $commentstart = "//";
-  if ($name =~ /\.(pl|pm|script|pod|ini|idf|esk|mk|cif)/i || !($name =~ /\./))
+  if ($name =~ /\.(pl|pm|script|pod|ini|idf|esk|mk|cif|flm)/i || !($name =~ /\./))
 	{
 	# Need to use # instead of //
 	# Second part of conditional is for perl scripts that don't specify any ending
--- a/tools/fshu.pm	Thu Jul 29 12:02:58 2010 +1000
+++ b/tools/fshu.pm	Thu Jul 29 12:03:43 2010 +1000
@@ -124,6 +124,10 @@
       mkpath($dir) or die "Couldn't make path \"$dir\": $!\n";
     }
   }
+  if ($dir =~ /^\\epoc32/) {
+    # If it starts with \epoc32, chop the leading backslash and stick on $EPOCROOT
+    $dir =~ s/^\\/$ENV{EPOCROOT}/;
+  }
 }
 
 sub CopyFile {