First public contribution.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32\sfile\sf_lwins.cpp
27 _LIT(KDirSystemPrograms,"\\System\\Programs\\");
28 _LIT(KDirSystemLibs,"\\System\\Libs\\");
29 _LIT8(KRomSystemLibs,"z:\\system\\libs\\");
31 _LIT(KDirSysBin,"\\sys\\bin\\");
32 _LIT8(KRomSysBin,"z:\\sys\\bin\\");
33 _LIT(KDirSystemBin,"\\System\\Bin\\");
34 _LIT8(KRomSystemBin,"z:\\system\\Bin\\");
37 extern TRequestStatus* ProcessDestructStatPtr;
38 extern TBool ProcessCreated;
42 /******************************************************************************
43 * Executable file find routines for WINS
44 ******************************************************************************/
46 TInt GetPEInfo(TProcessCreateInfo& aInfo)
48 // Extract the Uids, etc from the PE file
51 TBuf<MAX_PATH> ifilename;
52 ifilename.Copy(aInfo.iFileName);
53 TBuf<MAX_PATH> filename;
54 TInt r = MapEmulatedFileName(filename, ifilename);
57 Emulator::RImageFile pefile;
58 r = pefile.Open((LPCTSTR)filename.PtrZ()); //SL: Added cast
61 pefile.GetInfo(aInfo);
62 // Overide capabilities in image
63 for(TInt i=0; i<SCapabilitySet::ENCapW; i++)
65 aInfo.iS.iCaps[i] |= DisabledCapabilities[i];
66 aInfo.iS.iCaps[i] &= AllCapabilities[i];
74 TBool CheckIsDirectoryName(TProcessCreateInfo& aInfo)
76 // Attempt to get file attributes from Windows if attributes can't be found
77 // just assume not a directory otherwise check the directory bit
78 // Only intended for use by FindBin, FindDll and FindExe
81 TBuf<MAX_PATH> ifilename;
82 ifilename.Copy(aInfo.iFileName);
83 TBuf<MAX_PATH> filename;
84 if (MapEmulatedFileName(filename, ifilename) != KErrNone)
85 return EFalse; // just return EFalse as the error will be picked up later
87 DWORD attr = Emulator::GetFileAttributes((LPCTSTR)filename.PtrZ());
88 if (attr != -1 && (attr & FILE_ATTRIBUTE_DIRECTORY))
93 TInt FindBin(E32Image& aImage)
95 // WINS find Binary in system bin
96 // System directories on all drives Y-A,Z
99 __IF_DEBUG(Printf("FindBin"));
101 TInt len=aImage.iFileName.Length();
102 // check if it's a bare drive letter with no path
103 if (len>=3 && aImage.iFileName[1]==':' && aImage.iFileName[2]!='\\')
105 if (len + KRomSysBin().Length()-2 <= aImage.iFileName.MaxLength())
106 aImage.iFileName.Insert(2,KRomSysBin().Mid(2));
109 // Ensure consistent error codes with h/w, see DEF092502
110 // Unlike Symbian on h/w targets, on Windows searching
111 // for a driectory, including "." and "..", will return KErrorAccessDenied
112 if (CheckIsDirectoryName(aImage))
115 // first try and find it in the given directory
116 TInt r=GetPEInfo(aImage);
118 // Next : if looking at z:\sys\bin then look for it in emulator path
119 if (r == KErrNotFound || r == KErrPathNotFound)
121 if (aImage.iFileName.FindF(KRomSysBin) == 0)
123 aImage.iFileName.Delete(0, KRomSysBin().Length());
124 r = GetPEInfo(aImage);
127 if (r==KErrNotFound || r == KErrPathNotFound)
129 // Now try finding it in the EPOC scheme of things
130 TBuf<MAX_PATH> ifilename;
131 ifilename.Copy(aImage.iFileName);
132 TFindFile ff(gTheLoaderFs);
133 r=ff.FindByDir(ifilename,KDirSysBin);
136 aImage.iFileName.Copy(ff.File());
137 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
142 // Last chance look in emulator path for driveless things
143 if (aImage.iFileName.FindF(KRomSysBin().Mid(2)) == 0)
145 aImage.iFileName.Delete(0, KRomSysBin().Length()-2);
146 r = GetPEInfo(aImage);
150 __IF_DEBUG(Printf("Filename %S not found in ?:\\sys\\bin",&aImage.iFileName));
157 if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
160 // Next : if looking at z:\system\bin then look for it in emulator path
161 if (r == KErrNotFound || r == KErrPathNotFound)
163 if (aImage.iFileName.FindF(KRomSystemBin) == 0)
165 aImage.iFileName.Delete(0, KRomSystemBin().Length());
166 r = GetPEInfo(aImage);
169 if (r==KErrNotFound || r == KErrPathNotFound)
171 // Now try finding it in the EPOC scheme of things
172 TBuf<MAX_PATH> ifilename;
173 ifilename.Copy(aImage.iFileName);
174 TFindFile ff(gTheLoaderFs);
175 r=ff.FindByDir(ifilename,KDirSystemBin);
178 aImage.iFileName.Copy(ff.File());
179 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
184 __IF_DEBUG(Printf("Filename %S not found",&aImage.iFileName));
193 TInt FindExe(E32Image& aImage)
195 // WINS find executable
196 // System directories on all drives Y-A,Z
199 __IF_DEBUG(Printf("FindExe"));
201 TInt len = aImage.iFileName.Length();
202 // check if it's a bare drive letter with no path
203 if (len >= 3 && aImage.iFileName[1]==':' && aImage.iFileName[2]!='\\')
205 if (len + KRomSysBin().Length()-2 <= aImage.iFileName.MaxLength())
206 aImage.iFileName.Insert(2,KRomSysBin().Mid(2));
208 // Ensure consistent error codes with h/w, see DEF092502
209 // Unlike Symbian on h/w targets, on Windows searching
210 // for a driectory, including "." and "..", will return KErrorAccessDenied
211 if (CheckIsDirectoryName(aImage))
214 // first try and find it in the given directory
215 TInt r=GetPEInfo(aImage);
217 // Next : if looking at z:\sys\bin then look for it in emulator path
218 if (r == KErrNotFound || r == KErrPathNotFound)
220 if (aImage.iFileName.FindF(KRomSysBin) == 0)
222 aImage.iFileName.Delete(0, KRomSysBin().Length());
223 r = GetPEInfo(aImage);
226 if (r==KErrNotFound || r == KErrPathNotFound)
228 // Now try finding it in the EPOC scheme of things
229 TBuf<MAX_PATH> ifilename;
230 ifilename.Copy(aImage.iFileName);
231 TFindFile ff(gTheLoaderFs);
232 r=ff.FindByDir(ifilename,KDirSysBin);
235 aImage.iFileName.Copy(ff.File());
236 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
241 __IF_DEBUG(Printf("Filename %S not found in ?:\\sys\\bin",&aImage.iFileName));
247 if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
250 // Next : if looking at z:\system\libs then look for it in emulator path
251 if (r == KErrNotFound || r == KErrPathNotFound)
253 if (aImage.iFileName.FindF(KRomSystemLibs) == 0)
255 aImage.iFileName.Delete(0, KRomSystemLibs().Length());
256 r = GetPEInfo(aImage);
259 if (r==KErrNotFound || r == KErrPathNotFound)
261 // Now try finding it in the EPOC scheme of things
262 TBuf<MAX_PATH> ifilename;
263 ifilename.Copy(aImage.iFileName);
264 TFindFile ff(gTheLoaderFs);
265 r=ff.FindByDir(ifilename,KDirSystemPrograms);
268 aImage.iFileName.Copy(ff.File());
269 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
274 __IF_DEBUG(Printf("Filename %S not found",&aImage.iFileName));
283 TInt FindDll(E32Image& aImage, const TDesC8* aPath)
285 // Search for a dll in the following sequence ...
286 // 1. Supplied path parameter
287 // 2. System directories on all drives
291 TInt len = aImage.iFileName.Length();
292 // check if it's a bare drive letter with no path
293 if (len >=3 && aImage.iFileName[1]==':' && aImage.iFileName[2]!='\\')
295 if (len + KRomSysBin().Length()-2 <= aImage.iFileName.MaxLength())
296 aImage.iFileName.Insert(2,KRomSysBin().Mid(2));
299 // Ensure consistent error codes with h/w, see DEF092502
300 // Unlike Symbian on h/w targets, on Windows searching
301 // for a driectory, including "." and "..", will return KErrorAccessDenied
302 if (CheckIsDirectoryName(aImage))
305 TInt r=GetPEInfo(aImage);
307 // Next : if looking at z:\system\libs then look for it in emulator path
308 if (r == KErrNotFound || r == KErrPathNotFound)
310 if (aImage.iFileName.FindF(KRomSysBin) == 0)
312 aImage.iFileName.Delete(0, KRomSysBin().Length());
313 r = GetPEInfo(aImage);
316 if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
317 if (r == KErrNotFound || r == KErrPathNotFound)
318 if (aImage.iFileName.FindF(KRomSystemLibs) == 0)
320 aImage.iFileName.Delete(0, KRomSystemLibs().Length());
321 r = GetPEInfo(aImage);
324 TBuf<MAX_PATH> ifilename;
325 ifilename.Copy(aImage.iFileName);
326 if (r==KErrNotFound || r == KErrPathNotFound)
328 // Now try finding it in the EPOC scheme of things
329 TFindFile ff(gTheLoaderFs);
330 __IF_DEBUG(Printf("FindDll aDllName %S, aPath %S",&aImage.iFileName,aPath?aPath:&KNullDesC8));
331 if (aPath && aPath->Length()!=0)
333 TBuf<MAX_PATH> ipath;
335 r=ff.FindByPath(ifilename, &ipath);
338 aImage.iFileName.Copy(ff.File());
339 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
346 r=ff.FindByDir(ifilename,KDirSysBin);
349 aImage.iFileName.Copy(ff.File());
350 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
355 if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
358 r=ff.FindByDir(ifilename,KDirSystemLibs);
361 aImage.iFileName.Copy(ff.File());
362 __IF_DEBUG(Printf("Found file %S",&aImage.iFileName));
369 __IF_DEBUG(Printf("Filename %S not found",&aImage.iFileName));
377 /******************************************************************************
378 * WINS specific E32Image functions
379 ******************************************************************************/
381 TInt E32Image::ProcessFileName()
383 // Get the properly capitalised file name and root name
388 TInt r = fni.Set(iFileName, 0);
391 iRootNameOffset = fni.iBasePos;
392 iRootNameLength = fni.iLen - fni.iBasePos;
393 iExtOffset = fni.iExtPos;
394 // TBuf<MAX_PATH> filename;
395 // TInt r=MapEmulatedFileName(filename, iFileName);
398 // WIN32_FIND_DATA w32fd;
399 // HANDLE h=Emulator::FindFirstFile(filename.PtrZ(), &w32fd);
401 // return Emulator::LastError();
402 // TPtrC real_filename((const TText*)&w32fd.cFileName[0]);
404 // iFileName.SetLength(slash+1);
405 // iFileName+=real_filename;
406 __IF_DEBUG(Printf("ProcessFileName: %S,%d,%d,%d",&iFileName,iRootNameOffset,iRootNameLength,iExtOffset));
410 TInt E32Image::LoadProcess(const RLdrReq& aReq)
412 __IF_DEBUG(Printf("E32Image::LoadProcess %S",&aReq.iFileName));
414 iFileName=*aReq.iFileName;
415 TInt r=FindExe(*this);
421 r=CheckUids(iUids, aReq.iRequestedUids);
424 r = aReq.iMsg->Client((RThread&)aReq.iClientThread);
427 iClientHandle=aReq.iClientThread.Handle();
429 iDestructStat = ProcessDestructStatPtr;
431 iFlags |= EDataUnpaged; // Data paging is not supported on the emulator
432 r=E32Loader::ProcessCreate(*this, aReq.iCmd);
433 __IF_DEBUG(Printf("Done E32Loader::ProcessCreate %d",r));
437 ProcessCreated = ETrue;
439 iClientProcessHandle=iProcessHandle;
440 r=E32Loader::ProcessLoaded(*this);
444 // Load a code segment, plus all imports if main loadee
445 TInt E32Image::LoadCodeSeg(const RLdrReq& aReq)
447 __IF_DEBUG(Printf("E32Image::LoadCodeSeg %S",aReq.iFileName));
449 const TDesC8& reqName=*aReq.iFileName;
450 const TDesC8* searchPath=aReq.iPath;
453 TInt r=FindDll(*this, searchPath);
456 // Hack to support EXEDLLs which are DLLs but have EXE file extentions
459 if(iFileName.Right(4).CompareF(_L8(".DLL"))==0)
461 TUint8* p = (TUint8*)iFileName.Ptr() + iFileName.Length() - 3;
465 r=FindDll(*this, searchPath);
473 r=CheckUids(iUids, aReq.iRequestedUids);
479 // Check that we can legally load the DLL into the process
480 r=aReq.CheckSecInfo(iS);
486 __IF_DEBUG(Printf("Checking uids for %S", &iFileName));
487 if (iUids[0]!=KDynamicLibraryUid && iUids[0]!=KExecutableImageUid)
488 return KErrNotSupported;
489 r=CheckAlreadyLoaded();
490 if (r!=KErrNone || iAlreadyLoaded)
492 __IF_DEBUG(Printf("<LoadCodeSeg AlreadyLoaded %d",r));
493 return r; // already loaded, either share or give up
495 __IF_DEBUG(Printf("CodeSeg create"));
496 r=E32Loader::CodeSegCreate(*this);
498 r=E32Loader::CodeSegLoaded(*this);
500 __IF_DEBUG(Printf("<LoadCodeSeg, r=%d",r));
505 TInt ReadCapabilities(RLdrReq& aReq)
510 E32Image* e=new E32Image;
514 e->iFileName=*aReq.iFileName;
515 TInt r=GetPEInfo(*e);
516 if (r==KErrNotFound || r == KErrPathNotFound)
518 // z:\sys\bin\* may be found in emulator path
519 if (e->iFileName.FindF(KRomSysBin) == 0)
521 e->iFileName.Delete(0, KRomSysBin().Length());
526 if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
527 if (r==KErrNotFound || r == KErrPathNotFound)
529 // z:\system\bin\* may be found in emulator path
530 if (e->iFileName.FindF(KRomSystemBin) == 0)
532 e->iFileName.Delete(0, KRomSystemBin().Length());
536 TPtrC8 caps((const TUint8*)&e->iS.iCaps, sizeof(e->iS.iCaps));
538 r=aReq.iMsg->Write(2, caps);
543 TInt GetModuleInfo(RLdrReq& aReq)
545 // Read capabilities from file found
548 __IF_DEBUG(Printf("ReadModuleInfo %S",aReq.iFileName));
549 TFileNameInfo& fi = aReq.iFileNameInfo;
550 TInt r = KErrNotSupported;
552 // must specify a fully qualified name
553 if (fi.DriveLen() && fi.PathLen())
555 E32Image* e=new E32Image;
559 e->iFileName = *aReq.iFileName;
561 if (r==KErrNotFound || r == KErrPathNotFound)
563 // z:\system\bin\* may be found in emulator path
564 if (e->iFileName.FindF(KRomSysBin) == 0)
566 e->iFileName.Delete(0, KRomSysBin().Length());
570 if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
572 if (e->iFileName.FindF(KRomSystemBin) == 0)
574 e->iFileName.Delete(0, KRomSystemBin().Length());
580 RLibrary::TInfo ret_info;
581 memclr(&ret_info,sizeof(ret_info));
582 ret_info.iModuleVersion = e->iModuleVersion;
583 ret_info.iUids = e->iUids;
584 *(SSecurityInfo*)&ret_info.iSecurityInfo = e->iS;
585 TPckgC<RLibrary::TInfo> ret_pckg(ret_info);
586 r = aReq.iMsg->Write(2, ret_pckg);
593 TInt GetInfoFromHeader(const RLoaderMsg& /*aMsg*/)
596 r = KErrNotSupported;