diff -r 000000000000 -r a41df078684a userlibandfileserver/fileserver/sfile/sf_lwins.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/sfile/sf_lwins.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,601 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// f32\sfile\sf_lwins.cpp +// +// + +#include "sf_std.h" +#include +#include "sf_image.h" +#include +#include +#include +#include +#include + +_LIT(KDirSystemPrograms,"\\System\\Programs\\"); +_LIT(KDirSystemLibs,"\\System\\Libs\\"); +_LIT8(KRomSystemLibs,"z:\\system\\libs\\"); + +_LIT(KDirSysBin,"\\sys\\bin\\"); +_LIT8(KRomSysBin,"z:\\sys\\bin\\"); +_LIT(KDirSystemBin,"\\System\\Bin\\"); +_LIT8(KRomSystemBin,"z:\\system\\Bin\\"); + +#ifdef _DEBUG +extern TRequestStatus* ProcessDestructStatPtr; +extern TBool ProcessCreated; +#endif + + +/****************************************************************************** + * Executable file find routines for WINS + ******************************************************************************/ + +TInt GetPEInfo(TProcessCreateInfo& aInfo) +// +// Extract the Uids, etc from the PE file +// + { + TBuf ifilename; + ifilename.Copy(aInfo.iFileName); + TBuf filename; + TInt r = MapEmulatedFileName(filename, ifilename); + if (r == KErrNone) + { + Emulator::RImageFile pefile; + r = pefile.Open(filename.PtrZ()); + if (r == KErrNone) + { + pefile.GetInfo(aInfo); + // Overide capabilities in image + for(TInt i=0; i ifilename; + ifilename.Copy(aInfo.iFileName); + TBuf filename; + if (MapEmulatedFileName(filename, ifilename) != KErrNone) + return EFalse; // just return EFalse as the error will be picked up later + + DWORD attr = Emulator::GetFileAttributes(filename.PtrZ()); + if (attr != -1 && (attr & FILE_ATTRIBUTE_DIRECTORY)) + return ETrue; + return EFalse; + } + +TInt FindBin(E32Image& aImage) +// +// WINS find Binary in system bin +// System directories on all drives Y-A,Z +// + { + __IF_DEBUG(Printf("FindBin")); + + TInt len=aImage.iFileName.Length(); + // check if it's a bare drive letter with no path + if (len>=3 && aImage.iFileName[1]==':' && aImage.iFileName[2]!='\\') + { + if (len + KRomSysBin().Length()-2 <= aImage.iFileName.MaxLength()) + aImage.iFileName.Insert(2,KRomSysBin().Mid(2)); + } + + // Ensure consistent error codes with h/w, see DEF092502 + // Unlike Symbian on h/w targets, on Windows searching + // for a driectory, including "." and "..", will return KErrorAccessDenied + if (CheckIsDirectoryName(aImage)) + return KErrNotFound; + + // first try and find it in the given directory + TInt r=GetPEInfo(aImage); + + // Next : if looking at z:\sys\bin then look for it in emulator path + if (r == KErrNotFound || r == KErrPathNotFound) + { + if (aImage.iFileName.FindF(KRomSysBin) == 0) + { + aImage.iFileName.Delete(0, KRomSysBin().Length()); + r = GetPEInfo(aImage); + } + + if (r==KErrNotFound || r == KErrPathNotFound) + { + // Now try finding it in the EPOC scheme of things + TBuf ifilename; + ifilename.Copy(aImage.iFileName); + TFindFile ff(gTheLoaderFs); + r=ff.FindByDir(ifilename,KDirSysBin); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + else + { + // Last chance look in emulator path for driveless things + if (aImage.iFileName.FindF(KRomSysBin().Mid(2)) == 0) + { + aImage.iFileName.Delete(0, KRomSysBin().Length()-2); + r = GetPEInfo(aImage); + } + else + { + __IF_DEBUG(Printf("Filename %S not found in ?:\\sys\\bin",&aImage.iFileName)); + r=KErrNotFound; + } + } + } + } + + if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + return r; + + // Next : if looking at z:\system\bin then look for it in emulator path + if (r == KErrNotFound || r == KErrPathNotFound) + { + if (aImage.iFileName.FindF(KRomSystemBin) == 0) + { + aImage.iFileName.Delete(0, KRomSystemBin().Length()); + r = GetPEInfo(aImage); + } + + if (r==KErrNotFound || r == KErrPathNotFound) + { + // Now try finding it in the EPOC scheme of things + TBuf ifilename; + ifilename.Copy(aImage.iFileName); + TFindFile ff(gTheLoaderFs); + r=ff.FindByDir(ifilename,KDirSystemBin); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + else + { + __IF_DEBUG(Printf("Filename %S not found",&aImage.iFileName)); + r=KErrNotFound; + } + } + } + return r; + } + + +TInt FindExe(E32Image& aImage) +// +// WINS find executable +// System directories on all drives Y-A,Z +// + { + __IF_DEBUG(Printf("FindExe")); + + TInt len = aImage.iFileName.Length(); + // check if it's a bare drive letter with no path + if (len >= 3 && aImage.iFileName[1]==':' && aImage.iFileName[2]!='\\') + { + if (len + KRomSysBin().Length()-2 <= aImage.iFileName.MaxLength()) + aImage.iFileName.Insert(2,KRomSysBin().Mid(2)); + } + // Ensure consistent error codes with h/w, see DEF092502 + // Unlike Symbian on h/w targets, on Windows searching + // for a driectory, including "." and "..", will return KErrorAccessDenied + if (CheckIsDirectoryName(aImage)) + return KErrNotFound; + + // first try and find it in the given directory + TInt r=GetPEInfo(aImage); + + // Next : if looking at z:\sys\bin then look for it in emulator path + if (r == KErrNotFound || r == KErrPathNotFound) + { + if (aImage.iFileName.FindF(KRomSysBin) == 0) + { + aImage.iFileName.Delete(0, KRomSysBin().Length()); + r = GetPEInfo(aImage); + } + + if (r==KErrNotFound || r == KErrPathNotFound) + { + // Now try finding it in the EPOC scheme of things + TBuf ifilename; + ifilename.Copy(aImage.iFileName); + TFindFile ff(gTheLoaderFs); + r=ff.FindByDir(ifilename,KDirSysBin); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + else + { + __IF_DEBUG(Printf("Filename %S not found in ?:\\sys\\bin",&aImage.iFileName)); + r=KErrNotFound; + } + } + } + + if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + return r; + + // Next : if looking at z:\system\libs then look for it in emulator path + if (r == KErrNotFound || r == KErrPathNotFound) + { + if (aImage.iFileName.FindF(KRomSystemLibs) == 0) + { + aImage.iFileName.Delete(0, KRomSystemLibs().Length()); + r = GetPEInfo(aImage); + } + + if (r==KErrNotFound || r == KErrPathNotFound) + { + // Now try finding it in the EPOC scheme of things + TBuf ifilename; + ifilename.Copy(aImage.iFileName); + TFindFile ff(gTheLoaderFs); + r=ff.FindByDir(ifilename,KDirSystemPrograms); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + else + { + __IF_DEBUG(Printf("Filename %S not found",&aImage.iFileName)); + r=KErrNotFound; + } + } + } + return r; + } + +// WINS FindDll +TInt FindDll(E32Image& aImage, const TDesC8* aPath) +// +// Search for a dll in the following sequence ... +// 1. Supplied path parameter +// 2. System directories on all drives +// + { + + TInt len = aImage.iFileName.Length(); + // check if it's a bare drive letter with no path + if (len >=3 && aImage.iFileName[1]==':' && aImage.iFileName[2]!='\\') + { + if (len + KRomSysBin().Length()-2 <= aImage.iFileName.MaxLength()) + aImage.iFileName.Insert(2,KRomSysBin().Mid(2)); + } + + // Ensure consistent error codes with h/w, see DEF092502 + // Unlike Symbian on h/w targets, on Windows searching + // for a driectory, including "." and "..", will return KErrorAccessDenied + if (CheckIsDirectoryName(aImage)) + return KErrNotFound; + + TInt r=GetPEInfo(aImage); + + // Next : if looking at z:\system\libs then look for it in emulator path + if (r == KErrNotFound || r == KErrPathNotFound) + { + if (aImage.iFileName.FindF(KRomSysBin) == 0) + { + aImage.iFileName.Delete(0, KRomSysBin().Length()); + r = GetPEInfo(aImage); + } + + if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + if (r == KErrNotFound || r == KErrPathNotFound) + if (aImage.iFileName.FindF(KRomSystemLibs) == 0) + { + aImage.iFileName.Delete(0, KRomSystemLibs().Length()); + r = GetPEInfo(aImage); + } + + TBuf ifilename; + ifilename.Copy(aImage.iFileName); + if (r==KErrNotFound || r == KErrPathNotFound) + { + // Now try finding it in the EPOC scheme of things + TFindFile ff(gTheLoaderFs); + __IF_DEBUG(Printf("FindDll aDllName %S, aPath %S",&aImage.iFileName,aPath?aPath:&KNullDesC8)); + if (aPath && aPath->Length()!=0) + { + TBuf ipath; + ipath.Copy(*aPath); + r=ff.FindByPath(ifilename, &ipath); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + } + + if (r!=KErrNone) + { + r=ff.FindByDir(ifilename,KDirSysBin); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + } + + if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + if (r!=KErrNone) + { + r=ff.FindByDir(ifilename,KDirSystemLibs); + if (r==KErrNone) + { + aImage.iFileName.Copy(ff.File()); + __IF_DEBUG(Printf("Found file %S",&aImage.iFileName)); + r=GetPEInfo(aImage); + } + } + + if(r!=KErrNone) + { + __IF_DEBUG(Printf("Filename %S not found",&aImage.iFileName)); + r=KErrNotFound; + } + } + } + return r; + } + +/****************************************************************************** + * WINS specific E32Image functions + ******************************************************************************/ + +TInt E32Image::ProcessFileName() +// +// Get the properly capitalised file name and root name +// + { + + TFileNameInfo fni; + TInt r = fni.Set(iFileName, 0); + if (r!=KErrNone) + return r; + iRootNameOffset = fni.iBasePos; + iRootNameLength = fni.iLen - fni.iBasePos; + iExtOffset = fni.iExtPos; +// TBuf filename; +// TInt r=MapEmulatedFileName(filename, iFileName); +// if (r!=KErrNone) +// return r; +// WIN32_FIND_DATA w32fd; +// HANDLE h=Emulator::FindFirstFile(filename.PtrZ(), &w32fd); +// if (h==0) +// return Emulator::LastError(); +// TPtrC real_filename((const TText*)&w32fd.cFileName[0]); +// FindClose(h); +// iFileName.SetLength(slash+1); +// iFileName+=real_filename; + __IF_DEBUG(Printf("ProcessFileName: %S,%d,%d,%d",&iFileName,iRootNameOffset,iRootNameLength,iExtOffset)); + return KErrNone; + } + +TInt E32Image::LoadProcess(const RLdrReq& aReq) + { + __IF_DEBUG(Printf("E32Image::LoadProcess %S",&aReq.iFileName)); + + iFileName=*aReq.iFileName; + TInt r=FindExe(*this); + if (r!=KErrNone) + r=FindBin(*this); + if (r==KErrNone) + r=ProcessFileName(); + if (r==KErrNone) + r=CheckUids(iUids, aReq.iRequestedUids); + if (r!=KErrNone) + return r; + r = aReq.iMsg->Client((RThread&)aReq.iClientThread); + if (r!=KErrNone) + return r; + iClientHandle=aReq.iClientThread.Handle(); +#ifdef _DEBUG + iDestructStat = ProcessDestructStatPtr; +#endif + iFlags |= EDataUnpaged; // Data paging is not supported on the emulator + r=E32Loader::ProcessCreate(*this, aReq.iCmd); + __IF_DEBUG(Printf("Done E32Loader::ProcessCreate %d",r)); + if (r!=KErrNone) + return r; +#ifdef _DEBUG + ProcessCreated = ETrue; +#endif + iClientProcessHandle=iProcessHandle; + r=E32Loader::ProcessLoaded(*this); + return r; + } + +// Load a code segment, plus all imports if main loadee +TInt E32Image::LoadCodeSeg(const RLdrReq& aReq) + { + __IF_DEBUG(Printf("E32Image::LoadCodeSeg %S",aReq.iFileName)); + + const TDesC8& reqName=*aReq.iFileName; + const TDesC8* searchPath=aReq.iPath; + + iFileName=reqName; + TInt r=FindDll(*this, searchPath); + if (r!=KErrNone) + r=FindBin(*this); + // Hack to support EXEDLLs which are DLLs but have EXE file extentions + if(r==KErrNotFound) + { + if(iFileName.Right(4).CompareF(_L8(".DLL"))==0) + { + TUint8* p = (TUint8*)iFileName.Ptr() + iFileName.Length() - 3; + *p++ = 'E'; + *p++ = 'X'; + *p++ = 'E'; + r=FindDll(*this, searchPath); + if (r!=KErrNone) + r=FindBin(*this); + } + } + if (r==KErrNone) + r=ProcessFileName(); + if (r==KErrNone) + r=CheckUids(iUids, aReq.iRequestedUids); + + if(r==KErrNone) + { + if(this == iMain) + { + // Check that we can legally load the DLL into the process + r=aReq.CheckSecInfo(iS); + } + } + if (r!=KErrNone) + return r; + + __IF_DEBUG(Printf("Checking uids for %S", &iFileName)); + if (iUids[0]!=KDynamicLibraryUid && iUids[0]!=KExecutableImageUid) + return KErrNotSupported; + r=CheckAlreadyLoaded(); + if (r!=KErrNone || iAlreadyLoaded) + { + __IF_DEBUG(Printf("iMain=e; + e->iFileName=*aReq.iFileName; + TInt r=GetPEInfo(*e); + if (r==KErrNotFound || r == KErrPathNotFound) + { + // z:\sys\bin\* may be found in emulator path + if (e->iFileName.FindF(KRomSysBin) == 0) + { + e->iFileName.Delete(0, KRomSysBin().Length()); + r = GetPEInfo(*e); + } + } + + if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + if (r==KErrNotFound || r == KErrPathNotFound) + { + // z:\system\bin\* may be found in emulator path + if (e->iFileName.FindF(KRomSystemBin) == 0) + { + e->iFileName.Delete(0, KRomSystemBin().Length()); + r = GetPEInfo(*e); + } + } + TPtrC8 caps((const TUint8*)&e->iS.iCaps, sizeof(e->iS.iCaps)); + if (r==KErrNone) + r=aReq.iMsg->Write(2, caps); + delete e; + return r; + } + +TInt GetModuleInfo(RLdrReq& aReq) +// +// Read capabilities from file found +// + { + __IF_DEBUG(Printf("ReadModuleInfo %S",aReq.iFileName)); + TFileNameInfo& fi = aReq.iFileNameInfo; + TInt r = KErrNotSupported; + + // must specify a fully qualified name + if (fi.DriveLen() && fi.PathLen()) + { + E32Image* e=new E32Image; + if (!e) + return KErrNoMemory; + e->iMain = e; + e->iFileName = *aReq.iFileName; + r = GetPEInfo(*e); + if (r==KErrNotFound || r == KErrPathNotFound) + { + // z:\system\bin\* may be found in emulator path + if (e->iFileName.FindF(KRomSysBin) == 0) + { + e->iFileName.Delete(0, KRomSysBin().Length()); + r = GetPEInfo(*e); + } + + if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin)) + if(r!=KErrNone) + if (e->iFileName.FindF(KRomSystemBin) == 0) + { + e->iFileName.Delete(0, KRomSystemBin().Length()); + r = GetPEInfo(*e); + } + } + if (r == KErrNone) + { + RLibrary::TInfo ret_info; + memclr(&ret_info,sizeof(ret_info)); + ret_info.iModuleVersion = e->iModuleVersion; + ret_info.iUids = e->iUids; + *(SSecurityInfo*)&ret_info.iSecurityInfo = e->iS; + TPckgC ret_pckg(ret_info); + r = aReq.iMsg->Write(2, ret_pckg); + } + delete e; + } + return r; + } + +TInt GetInfoFromHeader(const RLoaderMsg& /*aMsg*/) + { + TInt r; + r = KErrNotSupported; + return r; + } + + +