os/kernelhwsrv/kernel/eka/euser/epoc/win32/emulator.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/euser/epoc/win32/emulator.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,841 @@
     1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#define _CRTIMP			// we want to use the static runtime library
    1.20 +#include <e32cmn.h>
    1.21 +#include <e32cmn_private.h>
    1.22 +#include <string.h>
    1.23 +#include <emulator.h>
    1.24 +#include <e32ldr.h>
    1.25 +#include <e32ldr_private.h>
    1.26 +#include <e32uid.h>
    1.27 +
    1.28 +#pragma data_seg(".data2")
    1.29 +#ifdef __VC32__
    1.30 +#pragma bss_seg(".data2")
    1.31 +#endif
    1.32 +static TBool UnicodeHost;
    1.33 +static Emulator::SInit Data;
    1.34 +#pragma data_seg()
    1.35 +#ifdef __VC32__
    1.36 +#pragma bss_seg()
    1.37 +#endif
    1.38 +
    1.39 +/**	
    1.40 +Initializes a module and prepares it to handle requests.
    1.41 +
    1.42 +@param aInit	An object of the structure SInit.
    1.43 +
    1.44 +@see SInit.
    1.45 +*/
    1.46 +EXPORT_C void Emulator::Init(const Emulator::SInit& aInit)
    1.47 +	{
    1.48 +	UnicodeHost = (GetVersion() & 0x80000000) ? FALSE : TRUE;
    1.49 +	Data = aInit;
    1.50 +	if (Data.iCodePage == 0)
    1.51 +		Data.iCodePage = CP_ACP;
    1.52 +	}
    1.53 +
    1.54 +LOCAL_C DWORD UStringLength(LPCSTR lpMultiByteStr)
    1.55 +//
    1.56 +// returns length of unicode string generated - assumes null terminated string
    1.57 +//
    1.58 +	{
    1.59 +	return MultiByteToWideChar(Data.iCodePage,0,lpMultiByteStr,-1,0,0);
    1.60 +	}
    1.61 +
    1.62 +
    1.63 +LOCAL_C DWORD ConvertToUnicode(LPCSTR aNarrow,LPWSTR aUnicode,DWORD aLength,BOOL aCharsRequired)
    1.64 +//
    1.65 +// Converts narrow string to unicode string
    1.66 +//
    1.67 +	{
    1.68 +	DWORD uniLength=UStringLength(aNarrow);
    1.69 +	if(uniLength>aLength || uniLength==0)
    1.70 +		return aCharsRequired ? uniLength : 0;
    1.71 +	uniLength=MultiByteToWideChar(Data.iCodePage,0,aNarrow,-1,aUnicode,aLength);
    1.72 +	// return number of characters excluding the null terminator
    1.73 +	return uniLength ? uniLength-1 : 0;
    1.74 +	}
    1.75 +
    1.76 +
    1.77 +LOCAL_C DWORD ConvertToNarrow(LPCWSTR aUnicode,LPSTR aNarrow,DWORD aLength)
    1.78 +//
    1.79 +// Converts unicode string to narrow string
    1.80 +//
    1.81 +	{
    1.82 +	return WideCharToMultiByte(Data.iCodePage,0,aUnicode,-1,aNarrow,aLength,"@",NULL);
    1.83 +	}
    1.84 +
    1.85 +template <TUint S>
    1.86 +struct Buf8
    1.87 +	{
    1.88 +public:
    1.89 +	Buf8(LPCWSTR aUnicode);
    1.90 +	inline operator LPCSTR() const
    1.91 +		{return iPtr;}
    1.92 +private:
    1.93 +	const char* iPtr;
    1.94 +	char iBuf[S];
    1.95 +	};
    1.96 +
    1.97 +template <TUint S>
    1.98 +Buf8<S>::Buf8(LPCWSTR aUnicode)
    1.99 +	{
   1.100 +	if (aUnicode)
   1.101 +		{
   1.102 +		iPtr = iBuf;
   1.103 +		ConvertToNarrow(aUnicode,iBuf,S);
   1.104 +		}
   1.105 +	else
   1.106 +		{
   1.107 +		iPtr = NULL;
   1.108 +		}
   1.109 +	}
   1.110 +
   1.111 +
   1.112 +
   1.113 +/**	
   1.114 +Acquires the global lock for host interaction.
   1.115 +*/
   1.116 +EXPORT_C void Emulator::Lock()
   1.117 +	{
   1.118 +	Data.iLock();
   1.119 +	}
   1.120 +
   1.121 +/**
   1.122 +Releases the global lock for host interaction.
   1.123 +This may overwrite the error code for this thread and that is not the behaviour expected, 
   1.124 +so save and restore it.
   1.125 +*/
   1.126 +EXPORT_C void Emulator::Unlock()
   1.127 +	{
   1.128 +	DWORD error=GetLastError();
   1.129 +	Data.iUnlock();
   1.130 +	SetLastError(error);
   1.131 +	}
   1.132 +
   1.133 +/**
   1.134 +Takes the current thread out of the emulator scheduling model.
   1.135 +*/
   1.136 +EXPORT_C void Emulator::Escape()
   1.137 +	{
   1.138 +	Data.iEscape();
   1.139 +	}
   1.140 +
   1.141 +/**
   1.142 +Returns the calling thread into the emulator scheduling model.
   1.143 +This may overwrite the error code for this thread and that is not the behaviour expected, 
   1.144 +so save and restore it.
   1.145 +*/
   1.146 +EXPORT_C void Emulator::Reenter()
   1.147 +	{
   1.148 +	DWORD error=GetLastError();
   1.149 +	Data.iReenter();
   1.150 +	SetLastError(error);
   1.151 +	}
   1.152 +
   1.153 +
   1.154 +/**
   1.155 +Jumps to the NThread Win32 SEH exception handler.
   1.156 +
   1.157 +@param aException	Describes an exception.
   1.158 +@param aContext		Describes the context.
   1.159 +	
   1.160 +@return   A handler to handle the exception occurred
   1.161 +*/
   1.162 +EXPORT_C DWORD Emulator::Win32SEHException(EXCEPTION_RECORD* aException, CONTEXT* aContext)
   1.163 +	{
   1.164 +	return Data.iException(aException, aContext);
   1.165 +	}
   1.166 +
   1.167 +
   1.168 +/**
   1.169 +This function wraps the Win32 CreateDirectory API (see http://msdn2.microsoft.com/en-us/library/aa363855.aspx).
   1.170 +*/  
   1.171 +EXPORT_C BOOL Emulator::CreateDirectory(LPCWSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes)
   1.172 +	{
   1.173 +	__LOCK_HOST;
   1.174 +
   1.175 +	if (UnicodeHost)
   1.176 +		return ::CreateDirectoryW(lpPathName, lpSecurityAttributes);
   1.177 +
   1.178 +	return ::CreateDirectoryA(Buf8<MAX_PATH>(lpPathName),lpSecurityAttributes);
   1.179 +	}
   1.180 +
   1.181 +#ifdef __VC32__
   1.182 +//disable unreachable code warning in VC++
   1.183 +#pragma warning (disable : 4702)
   1.184 +#endif
   1.185 +
   1.186 +
   1.187 +/**
   1.188 +Recursively ensures that the full directory exists.
   1.189 +	
   1.190 +@param aPathName  	Provides the path name.
   1.191 +
   1.192 +@return  TRUE, if the function succeeds
   1.193 +		 FALSE, if the function fails
   1.194 +*/
   1.195 +EXPORT_C BOOL Emulator::CreateAllDirectories(LPCSTR aPathName)
   1.196 +	{
   1.197 +	__LOCK_HOST;
   1.198 +
   1.199 +	char path[MAX_PATH];
   1.200 +	strcpy(path, aPathName);
   1.201 +	char* p = path;
   1.202 +	for (;;)
   1.203 +		{
   1.204 +		p = strchr(p, '\\');
   1.205 +		char temp=0;
   1.206 +		if (p)
   1.207 +			{
   1.208 +			temp = *++p;
   1.209 +			*p = '\0';
   1.210 +			}
   1.211 +		DWORD att = ::GetFileAttributesA(path);
   1.212 +		if ((att == -1 || !(att&FILE_ATTRIBUTE_DIRECTORY)) && !::CreateDirectoryA(path, NULL))
   1.213 +			return EFalse;
   1.214 +		if (!p)
   1.215 +			return ETrue;
   1.216 +		*p = temp;
   1.217 +		}
   1.218 +	}
   1.219 +#ifdef __VC32__
   1.220 +//enable unreachable code warning in VC++
   1.221 +#pragma warning (default : 4702)
   1.222 +#endif
   1.223 +
   1.224 +#ifndef INVALID_FILE_ATTRIBUTES	
   1.225 +#define INVALID_FILE_ATTRIBUTES	 ((DWORD)-1)
   1.226 +#endif
   1.227 +
   1.228 +
   1.229 +/**
   1.230 +This function wraps the Win32 CreateFile API (see http://msdn2.microsoft.com/en-us/library/aa363858.aspx).
   1.231 +It also modifies file attributes depending on whether the file is hidden or not.
   1.232 +*/
   1.233 +EXPORT_C HANDLE Emulator::CreateFile(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,
   1.234 +						   LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDistribution,
   1.235 +						   DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
   1.236 +	{
   1.237 +	__LOCK_HOST;
   1.238 +	HANDLE h;
   1.239 +	BOOL hidden = 0; 
   1.240 +	DWORD att = INVALID_FILE_ATTRIBUTES;
   1.241 +	if(dwCreationDistribution==CREATE_ALWAYS)
   1.242 +		{
   1.243 +		att = ::GetFileAttributes(lpFileName);
   1.244 +		if(att!=INVALID_FILE_ATTRIBUTES && (att&FILE_ATTRIBUTE_HIDDEN))
   1.245 +			{
   1.246 +			hidden = ::SetFileAttributes(lpFileName, (att&~FILE_ATTRIBUTE_HIDDEN));
   1.247 +			}
   1.248 +		}
   1.249 +		
   1.250 +	if (UnicodeHost)
   1.251 +		h = ::CreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDistribution,
   1.252 +							dwFlagsAndAttributes,hTemplateFile);
   1.253 +	else
   1.254 +		h = ::CreateFileA(Buf8<MAX_PATH>(lpFileName),dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDistribution,
   1.255 +						dwFlagsAndAttributes,hTemplateFile);
   1.256 +	
   1.257 +	if(hidden && h!=INVALID_HANDLE_VALUE)
   1.258 +		{
   1.259 +		::SetFileAttributes(lpFileName, att);
   1.260 +		}
   1.261 +	return h;
   1.262 +	}
   1.263 +
   1.264 +
   1.265 +/**
   1.266 +This function wraps the Win32 DeleteFile API (see http://msdn2.microsoft.com/en-us/library/aa363915.aspx).
   1.267 +*/
   1.268 +EXPORT_C BOOL Emulator::DeleteFile(LPCWSTR lpFileName)
   1.269 +	{
   1.270 +	__LOCK_HOST;
   1.271 +
   1.272 +	if (UnicodeHost)
   1.273 +		return ::DeleteFileW(lpFileName);
   1.274 +
   1.275 +	return ::DeleteFileA(Buf8<MAX_PATH>(lpFileName));
   1.276 +	}
   1.277 +
   1.278 +LOCAL_C TBool MapFindFileData(LPWIN32_FIND_DATAW lpFindFileData, LPWIN32_FIND_DATAA lpFindNarrow)
   1.279 +	{
   1.280 +	lpFindFileData->dwFileAttributes=lpFindNarrow->dwFileAttributes;
   1.281 +	lpFindFileData->ftCreationTime=lpFindNarrow->ftCreationTime;
   1.282 +	lpFindFileData->ftLastAccessTime=lpFindNarrow->ftLastAccessTime;
   1.283 +	lpFindFileData->ftLastWriteTime=lpFindNarrow->ftLastWriteTime;
   1.284 +	lpFindFileData->nFileSizeHigh=lpFindNarrow->nFileSizeHigh;
   1.285 +	lpFindFileData->nFileSizeLow=lpFindNarrow->nFileSizeLow;
   1.286 +	
   1.287 +	if(!MultiByteToWideChar(Data.iCodePage,0,lpFindNarrow->cFileName,-1,lpFindFileData->cFileName,MAX_PATH))
   1.288 +		return FALSE;
   1.289 +
   1.290 +	if(lpFindNarrow->cAlternateFileName!=NULL)
   1.291 +		{
   1.292 +		// magic number 14 comes from MS documentation
   1.293 +		if(!MultiByteToWideChar(Data.iCodePage,0,lpFindNarrow->cAlternateFileName,-1,lpFindFileData->cAlternateFileName,14))
   1.294 +			return FALSE;
   1.295 +		}
   1.296 +	return TRUE;
   1.297 +	}
   1.298 +
   1.299 +
   1.300 +/**
   1.301 +This function wraps the Win32 FindFirstFile API (see http://msdn2.microsoft.com/en-us/library/aa364418.aspx).	
   1.302 +*/
   1.303 +EXPORT_C HANDLE Emulator::FindFirstFile(LPCWSTR lpFileName,LPWIN32_FIND_DATAW lpFindFileData)
   1.304 +	{
   1.305 +	__LOCK_HOST;
   1.306 +
   1.307 +	if (UnicodeHost)
   1.308 +		return ::FindFirstFileW(lpFileName, lpFindFileData);
   1.309 +
   1.310 +	WIN32_FIND_DATAA lpFindNarrow;
   1.311 +	HANDLE h=::FindFirstFileA(Buf8<MAX_PATH>(lpFileName),&lpFindNarrow);
   1.312 +	if(h==INVALID_HANDLE_VALUE)
   1.313 +		return h;
   1.314 +
   1.315 +	if (!MapFindFileData(lpFindFileData, &lpFindNarrow))
   1.316 +		{
   1.317 +		FindClose(h);
   1.318 +		return INVALID_HANDLE_VALUE;
   1.319 +		}
   1.320 +
   1.321 +	return h;
   1.322 +	}
   1.323 +
   1.324 +
   1.325 +/**
   1.326 +This function wraps the Win32 FindNextFile API (see http://msdn2.microsoft.com/en-us/library/aa364428.aspx).	
   1.327 +*/
   1.328 +EXPORT_C BOOL Emulator::FindNextFile(HANDLE hFindFile,LPWIN32_FIND_DATAW lpFindFileData)
   1.329 +	{
   1.330 +	__LOCK_HOST;
   1.331 +
   1.332 +	if (UnicodeHost)
   1.333 +		return ::FindNextFileW(hFindFile, lpFindFileData);
   1.334 +
   1.335 +	WIN32_FIND_DATAA lpFindNarrow;
   1.336 +	if(!::FindNextFileA(hFindFile,&lpFindNarrow))
   1.337 +		return FALSE;
   1.338 +
   1.339 +	return MapFindFileData(lpFindFileData, &lpFindNarrow);
   1.340 +	}
   1.341 +
   1.342 +/**
   1.343 +This function wraps the Win32 GetDiskFreeSpace API (see http://msdn2.microsoft.com/en-us/library/aa364935.aspx).
   1.344 +*/
   1.345 +EXPORT_C BOOL Emulator::GetDiskFreeSpace(LPCWSTR lpRootPathName,LPDWORD lpSectorsPerCluster,\
   1.346 +							   LPDWORD lpBytesPerSector,LPDWORD lpNumberOfFreeClusters,\
   1.347 +							   LPDWORD lpTotalNumberOfClusters)
   1.348 +	{
   1.349 +	__LOCK_HOST;
   1.350 +
   1.351 +	if (UnicodeHost)
   1.352 +		return ::GetDiskFreeSpaceW(lpRootPathName,lpSectorsPerCluster,lpBytesPerSector,lpNumberOfFreeClusters,lpTotalNumberOfClusters);
   1.353 +
   1.354 +	return ::GetDiskFreeSpaceA(Buf8<MAX_PATH>(lpRootPathName),lpSectorsPerCluster,lpBytesPerSector,lpNumberOfFreeClusters,lpTotalNumberOfClusters);
   1.355 +
   1.356 +	}
   1.357 +
   1.358 +
   1.359 +/**
   1.360 +This function wraps the Win32 GetFileAttributes API (see http://msdn2.microsoft.com/en-us/library/aa364944.aspx).
   1.361 +*/
   1.362 +EXPORT_C DWORD Emulator::GetFileAttributes(LPCWSTR lpFileName)
   1.363 +	{
   1.364 +	__LOCK_HOST;
   1.365 +
   1.366 +	if (UnicodeHost)
   1.367 +		return ::GetFileAttributesW(lpFileName);
   1.368 +
   1.369 +	return ::GetFileAttributesA(Buf8<MAX_PATH>(lpFileName));
   1.370 +	}
   1.371 +
   1.372 +
   1.373 +/**
   1.374 +This function wraps the Win32 GetModuleHandle API (see http://msdn2.microsoft.com/en-us/library/ms683199.aspx).
   1.375 +*/
   1.376 +EXPORT_C HMODULE Emulator::GetModuleHandle(LPCWSTR lpModuleName)
   1.377 +	{
   1.378 +	__LOCK_HOST;
   1.379 +
   1.380 +	if (UnicodeHost)
   1.381 +		return ::GetModuleHandleW(lpModuleName);
   1.382 +
   1.383 +	return ::GetModuleHandleA(Buf8<MAX_PATH>(lpModuleName));
   1.384 +	}
   1.385 +
   1.386 +
   1.387 +/**
   1.388 +This function wraps the Win32 GetModuleFileName API (see http://msdn2.microsoft.com/en-us/library/ms683197.aspx).
   1.389 +*/
   1.390 +EXPORT_C DWORD Emulator::GetModuleFileName(HMODULE hModule, LPWSTR lpFilename)
   1.391 +	{
   1.392 +	__LOCK_HOST;
   1.393 +	if (UnicodeHost)
   1.394 +		return ::GetModuleFileNameW(hModule, lpFilename, MAX_PATH);
   1.395 +	char fn[MAX_PATH];
   1.396 +	DWORD r=::GetModuleFileNameA(hModule, fn, MAX_PATH);
   1.397 +	if (r>MAX_PATH||r==0)
   1.398 +		return 0;
   1.399 +	return ConvertToUnicode(fn, lpFilename, MAX_PATH, TRUE);
   1.400 +	}
   1.401 +
   1.402 +
   1.403 +/**
   1.404 +This function wraps the Win32 GetTempPath API (see http://msdn2.microsoft.com/en-us/library/Aa364992.aspx).
   1.405 +*/
   1.406 +EXPORT_C DWORD Emulator::GetTempPath(DWORD nBufferLength,LPWSTR lpBuff)
   1.407 +	{
   1.408 +	__LOCK_HOST;
   1.409 +
   1.410 +	if (UnicodeHost)
   1.411 +		return ::GetTempPathW(nBufferLength,lpBuff);
   1.412 +
   1.413 +	char path[MAX_PATH];
   1.414 +	DWORD r=::GetTempPathA(MAX_PATH,path);
   1.415 +	if(r>MAX_PATH||r==0)
   1.416 +		return 0;
   1.417 +	return ConvertToUnicode(path,lpBuff,nBufferLength,TRUE);
   1.418 +	}
   1.419 +
   1.420 +
   1.421 +/**
   1.422 +This function wraps the Win32 GetCurrentDirectory API (see http://msdn2.microsoft.com/en-us/library/aa364934.aspx).
   1.423 +*/
   1.424 +EXPORT_C DWORD Emulator::GetCurrentDirectory(DWORD nBufferLength,LPWSTR lpBuff)
   1.425 +	{
   1.426 +	__LOCK_HOST;
   1.427 +
   1.428 +	if (UnicodeHost)
   1.429 +		return ::GetCurrentDirectoryW(nBufferLength,lpBuff);
   1.430 +
   1.431 +	char path[MAX_PATH];
   1.432 +	DWORD r=::GetCurrentDirectoryA(MAX_PATH,path);
   1.433 +	if(r>MAX_PATH||r==0)
   1.434 +		return 0;
   1.435 +	return ConvertToUnicode(path,lpBuff,nBufferLength,TRUE);
   1.436 +	}
   1.437 +
   1.438 +
   1.439 +/**
   1.440 +This function wraps the Win32 GetVolumeInformation API (see http://msdn2.microsoft.com/en-us/library/aa364993.aspx).
   1.441 +*/
   1.442 +EXPORT_C BOOL Emulator::GetVolumeInformation(LPCWSTR lpRootPathName,LPWSTR lpVolumeNameBuffer,DWORD nVolumeNameSize,
   1.443 +								   LPDWORD lpVolumeSerialNumber,LPDWORD lpMaximumComponentLength,
   1.444 +								   LPDWORD lpFileSystemFlags,LPWSTR,DWORD)
   1.445 +	{
   1.446 +	__LOCK_HOST;
   1.447 +
   1.448 +	// lpfileSystemNameBuffer always NULL so no need to convert
   1.449 +	if (UnicodeHost)
   1.450 +		return ::GetVolumeInformationW(lpRootPathName,lpVolumeNameBuffer,nVolumeNameSize,lpVolumeSerialNumber,
   1.451 +										lpMaximumComponentLength,lpFileSystemFlags,NULL,0);
   1.452 +
   1.453 +	char volName[MAX_PATH];
   1.454 +	BOOL res=::GetVolumeInformationA(Buf8<MAX_PATH>(lpRootPathName),volName,MAX_PATH,lpVolumeSerialNumber,
   1.455 +									lpMaximumComponentLength,lpFileSystemFlags,NULL,0);
   1.456 +
   1.457 +	if(res && lpVolumeNameBuffer)
   1.458 +		ConvertToUnicode(volName,lpVolumeNameBuffer,nVolumeNameSize,FALSE);
   1.459 +	return res;
   1.460 +	}
   1.461 +
   1.462 +
   1.463 +/**
   1.464 +This function wraps the Win32 LoadLibrary API (see http://msdn2.microsoft.com/en-us/library/ms684175.aspx).
   1.465 +*/
   1.466 +EXPORT_C HMODULE Emulator::LoadLibrary(LPCWSTR lpLibFileName)
   1.467 +	{
   1.468 +	__LOCK_HOST;
   1.469 +
   1.470 +	if (UnicodeHost)
   1.471 +		return ::LoadLibraryW(lpLibFileName);
   1.472 +
   1.473 +	return ::LoadLibraryA(Buf8<MAX_PATH>(lpLibFileName));
   1.474 +	}
   1.475 +
   1.476 +
   1.477 +/**
   1.478 +This function wraps the Win32 FreeLibrary API (see http://msdn2.microsoft.com/en-us/library/ms683152.aspx).
   1.479 +*/
   1.480 +EXPORT_C BOOL Emulator::FreeLibrary(HMODULE hLibModule)
   1.481 +	{
   1.482 +	__LOCK_HOST;
   1.483 +	return ::FreeLibrary(hLibModule);
   1.484 +	}
   1.485 +
   1.486 +
   1.487 +
   1.488 +/**
   1.489 +This function wraps the Win32 MoveFile API (see http://msdn2.microsoft.com/en-us/library/aa365239.aspx).
   1.490 +*/
   1.491 +EXPORT_C BOOL Emulator::MoveFile(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName)
   1.492 +	{
   1.493 +	__LOCK_HOST;
   1.494 +
   1.495 +	if (UnicodeHost)
   1.496 +		return ::MoveFileW(lpExistingFileName,lpNewFileName);
   1.497 +
   1.498 +	return ::MoveFileA(Buf8<MAX_PATH>(lpExistingFileName),Buf8<MAX_PATH>(lpNewFileName));
   1.499 +	}
   1.500 +
   1.501 +
   1.502 +/**
   1.503 +This function wraps the Win32 CopyFile API (see http://msdn2.microsoft.com/en-us/library/aa363851.aspx).
   1.504 +*/
   1.505 +EXPORT_C BOOL Emulator::CopyFile(LPCWSTR lpExistingFileName,LPCWSTR lpNewFileName,BOOL aFailIfExists)
   1.506 +	{
   1.507 +	__LOCK_HOST;
   1.508 +
   1.509 +	if (UnicodeHost)
   1.510 +		return ::CopyFileW(lpExistingFileName,lpNewFileName,aFailIfExists);
   1.511 +
   1.512 +	return ::CopyFileA(Buf8<MAX_PATH>(lpExistingFileName),Buf8<MAX_PATH>(lpNewFileName),aFailIfExists);
   1.513 +	}
   1.514 +
   1.515 +
   1.516 +/**
   1.517 +This function wraps the Win32 OutputDebugString API (see http://msdn2.microsoft.com/en-us/library/aa363362.aspx).
   1.518 +*/
   1.519 +EXPORT_C VOID Emulator::OutputDebugString(LPCWSTR lpOutputString)
   1.520 +	{
   1.521 +	if (UnicodeHost)
   1.522 +		::OutputDebugStringW(lpOutputString);
   1.523 +	else
   1.524 +		::OutputDebugStringA(Buf8<1024>(lpOutputString));
   1.525 +	}
   1.526 +
   1.527 +
   1.528 +
   1.529 +/**
   1.530 +This function wraps the Win32 RemoveDirectory API (see http://msdn2.microsoft.com/en-us/library/aa365488.aspx).
   1.531 +*/
   1.532 +EXPORT_C BOOL Emulator::RemoveDirectory(LPCWSTR lpPathName)
   1.533 +	{
   1.534 +	__LOCK_HOST;
   1.535 +
   1.536 +	if (UnicodeHost)
   1.537 +		return ::RemoveDirectoryW(lpPathName);
   1.538 +
   1.539 +	return ::RemoveDirectoryA(Buf8<MAX_PATH>(lpPathName));
   1.540 +	}
   1.541 +
   1.542 +
   1.543 +/**
   1.544 +This function wraps the Win32 SetFileAttributes API (see http://msdn2.microsoft.com/en-us/library/aa365535.aspx).
   1.545 +*/
   1.546 +
   1.547 +EXPORT_C BOOL Emulator::SetFileAttributes(LPCWSTR lpFileName,DWORD dwFileAttributes)
   1.548 +	{
   1.549 +	__LOCK_HOST;
   1.550 +
   1.551 +	if (UnicodeHost)
   1.552 +		return ::SetFileAttributesW(lpFileName,dwFileAttributes);
   1.553 +
   1.554 +	return ::SetFileAttributesA(Buf8<MAX_PATH>(lpFileName),dwFileAttributes);
   1.555 +	}
   1.556 +
   1.557 +
   1.558 +
   1.559 +/**
   1.560 +This function wraps the Win32 SetVolumeLabel API (see http://msdn2.microsoft.com/en-us/library/aa365560.aspx).
   1.561 +*/
   1.562 +EXPORT_C BOOL Emulator::SetVolumeLabel(LPCWSTR lpRootPathName,LPCWSTR lpVolumeName)
   1.563 +	{
   1.564 +	__LOCK_HOST;
   1.565 +
   1.566 +	if (UnicodeHost)
   1.567 +		return ::SetVolumeLabelW(lpRootPathName,lpVolumeName);
   1.568 +
   1.569 +	return ::SetVolumeLabelA(Buf8<MAX_PATH>(lpRootPathName),Buf8<MAX_PATH>(lpVolumeName));
   1.570 +	}
   1.571 +
   1.572 +
   1.573 +/**
   1.574 +Maps an NT error to an Epoc32 error.
   1.575 +	
   1.576 +@return	 Last-error code of the calling thread.
   1.577 +*/
   1.578 +EXPORT_C TInt Emulator::LastError()
   1.579 +
   1.580 +// For other error codes look at MSDN "Numerical List of Error Codes"
   1.581 +	{
   1.582 +	switch (GetLastError())
   1.583 +		{
   1.584 +	case ERROR_SUCCESS:				return KErrNone;
   1.585 +	case ERROR_INVALID_DRIVE:		return KErrNotReady;
   1.586 +	case ERROR_INVALID_NAME:
   1.587 +	case ERROR_FILENAME_EXCED_RANGE:
   1.588 +	case ERROR_OPEN_FAILED:			return KErrBadName; 
   1.589 +	case ERROR_INVALID_HANDLE:		return KErrBadHandle;
   1.590 +	case ERROR_NOT_SUPPORTED:
   1.591 +	case ERROR_INVALID_FUNCTION:	return KErrNotSupported;
   1.592 +	case ERROR_SHARING_VIOLATION: 
   1.593 +	case ERROR_ACCESS_DENIED: 
   1.594 +	case ERROR_WRITE_PROTECT:		return KErrAccessDenied;
   1.595 +	case ERROR_LOCK_VIOLATION:		return KErrLocked;
   1.596 +	case ERROR_FILE_NOT_FOUND:
   1.597 +	case ERROR_MOD_NOT_FOUND:		return KErrNotFound;
   1.598 +	case ERROR_DIRECTORY: 
   1.599 +	case ERROR_BAD_PATHNAME:
   1.600 +	case ERROR_PATH_NOT_FOUND:		return KErrPathNotFound; 
   1.601 +	case ERROR_ALREADY_EXISTS:
   1.602 +	case ERROR_FILE_EXISTS:			return KErrAlreadyExists;
   1.603 +	case ERROR_NOT_READY:			return KErrNotReady; 
   1.604 +	case ERROR_UNRECOGNIZED_VOLUME:
   1.605 +	case ERROR_NOT_DOS_DISK:		return KErrUnknown;
   1.606 +	case ERROR_UNRECOGNIZED_MEDIA:
   1.607 +	case ERROR_BAD_EXE_FORMAT:		return KErrCorrupt;
   1.608 +	case ERROR_NO_MORE_FILES:		return KErrEof; 
   1.609 +	case ERROR_DIR_NOT_EMPTY:		return KErrInUse;
   1.610 +	case ERROR_INVALID_USER_BUFFER:
   1.611 +	case ERROR_NOT_ENOUGH_MEMORY:
   1.612 +	case ERROR_INSUFFICIENT_BUFFER:
   1.613 +	case ERROR_OUTOFMEMORY:			return KErrNoMemory;
   1.614 +	case ERROR_DISK_FULL:			return KErrDiskFull;
   1.615 +	case ERROR_INVALID_DATA:
   1.616 +	case ERROR_INVALID_PARAMETER:	return KErrArgument;
   1.617 +	case ERROR_OPERATION_ABORTED:	return KErrCancel;
   1.618 +
   1.619 +    default:						return KErrGeneral;
   1.620 +		}
   1.621 +	}
   1.622 +
   1.623 +/**
   1.624 +This function wraps the Win32 GetProcAddress API (see http://msdn2.microsoft.com/en-us/library/ms683212.aspx).
   1.625 +*/
   1.626 +FARPROC Emulator::GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
   1.627 +	{
   1.628 +	__LOCK_HOST;
   1.629 +	return ::GetProcAddress(hModule, lpProcName);
   1.630 +	}
   1.631 +
   1.632 +
   1.633 +
   1.634 +// image file support
   1.635 +
   1.636 +// loaded modules
   1.637 +
   1.638 +
   1.639 +/**
   1.640 +Gets the header format of the file system.
   1.641 +
   1.642 +@return		Returns the header format of the file system.	
   1.643 +*/
   1.644 +EXPORT_C const IMAGE_NT_HEADERS32* Emulator::TModule::NtHeader() const
   1.645 +	{
   1.646 +	if (!IsValid())
   1.647 +		return 0;
   1.648 +	const IMAGE_DOS_HEADER* dhead = (const IMAGE_DOS_HEADER*)Translate(0);
   1.649 +	if ( IMAGE_DOS_SIGNATURE != dhead->e_magic )
   1.650 +		return 0;
   1.651 +	if (dhead->e_lfarlc < sizeof(IMAGE_DOS_HEADER))
   1.652 +		return 0;
   1.653 +	const IMAGE_NT_HEADERS32* ntHead = (const IMAGE_NT_HEADERS32*)Translate(dhead->e_lfanew);
   1.654 +    if ( ntHead->Signature != IMAGE_NT_SIGNATURE )
   1.655 +		return 0;
   1.656 +	return ntHead;
   1.657 +	}
   1.658 +
   1.659 +
   1.660 +/**
   1.661 +Constructor which sets the handles of loaded module to the specified module.
   1.662 +
   1.663 +@param aModuleName		Holds the name of the module to be loaded.
   1.664 +*/
   1.665 +EXPORT_C Emulator::TModule::TModule(LPCSTR aModuleName)
   1.666 +	: iModule(GetModuleHandleA(aModuleName)), iBase(iModule)
   1.667 +	{
   1.668 +	if (!NtHeader())
   1.669 +		{
   1.670 +		iModule = 0;
   1.671 +		iBase = 0;
   1.672 +		}
   1.673 +	}
   1.674 +
   1.675 +
   1.676 +/**
   1.677 +Gets the pointer of the section header if the header name matches with the buffer aSection[].
   1.678 +		
   1.679 +@param aSection[]	A buffer of type BYTE.		
   1.680 +
   1.681 +@return 	Returns the pointer to section header of the file system.
   1.682 +*/
   1.683 +EXPORT_C const IMAGE_SECTION_HEADER* Emulator::TModule::SectionHeader(const BYTE aSection[]) const
   1.684 +	{
   1.685 +	const IMAGE_NT_HEADERS32* ntHead = NtHeader();
   1.686 +	if (!ntHead)
   1.687 +		return 0;
   1.688 +
   1.689 +	const IMAGE_SECTION_HEADER* imgHead = (const IMAGE_SECTION_HEADER*)((TUint8*)&ntHead->OptionalHeader + ntHead->FileHeader.SizeOfOptionalHeader);
   1.690 +	const IMAGE_SECTION_HEADER* end = imgHead + ntHead->FileHeader.NumberOfSections;
   1.691 +	for (; imgHead < end; ++imgHead)
   1.692 +		{
   1.693 +		if (memcmp(imgHead->Name, aSection, IMAGE_SIZEOF_SHORT_NAME)==0)
   1.694 +			return imgHead;
   1.695 +		}
   1.696 +	return 0;
   1.697 +	}
   1.698 +
   1.699 +
   1.700 +/**
   1.701 +Points to the first byte or first page of the loaded module or mapped file image.
   1.702 +		
   1.703 +@param aSection[]	A buffer of type BYTE.
   1.704 +		
   1.705 +@return TAny		Returns first byte of the loaded module or first page of the mapped file image.
   1.706 +*/
   1.707 +EXPORT_C const TAny* Emulator::TModule::Section(const BYTE aSection[]) const
   1.708 +	{
   1.709 +	const IMAGE_SECTION_HEADER* imgHead = SectionHeader(aSection);
   1.710 +	if (imgHead)
   1.711 +		return Translate(IsLoaded() ? imgHead->VirtualAddress : imgHead->PointerToRawData);
   1.712 +	return 0;
   1.713 +	}
   1.714 +
   1.715 +
   1.716 +/**
   1.717 +Go through the section headers looking for UID section.
   1.718 +	
   1.719 +@param aType	Contains a UID type.
   1.720 +*/
   1.721 +EXPORT_C void Emulator::TModule::GetUids(TUidType& aType) const
   1.722 +	{
   1.723 +	const TEmulatorImageHeader* hdr = (const TEmulatorImageHeader*)Section(KWin32SectionName_Symbian);
   1.724 +	if (hdr)
   1.725 +		aType = *(const TUidType*)&hdr->iUids[0];
   1.726 +	}
   1.727 +
   1.728 +
   1.729 +/**
   1.730 +Goes through section headers and gets the information of file system.
   1.731 +
   1.732 +@param aInfo	Contains the information of the file system.
   1.733 +*/
   1.734 +EXPORT_C void Emulator::TModule::GetInfo(TProcessCreateInfo& aInfo) const
   1.735 +	{
   1.736 +	aInfo.iExceptionDescriptor = 0;
   1.737 +	const IMAGE_NT_HEADERS32* ntHead = NtHeader();
   1.738 +	if (ntHead)
   1.739 +		{
   1.740 +		const TEmulatorImageHeader* hdr = (const TEmulatorImageHeader*)Section(KWin32SectionName_Symbian);
   1.741 +		if (hdr)
   1.742 +			{
   1.743 +			aInfo.iUids = *(const TUidType*)&hdr->iUids[0];
   1.744 +			TBool isExe = (hdr->iUids[0].iUid==KExecutableImageUidValue);
   1.745 +			TBool data_section_present = (Section(KWin32SectionName_EpocData)!=NULL);
   1.746 +			TBool data = hdr->iFlags & KEmulatorImageFlagAllowDllData;
   1.747 +			if (data_section_present && isExe)
   1.748 +				data = ETrue;
   1.749 +			aInfo.iBssSize=data?1:0;
   1.750 +			aInfo.iDataSize=0;
   1.751 +			aInfo.iTotalDataSize=aInfo.iBssSize;
   1.752 +			aInfo.iDepCount = 0;
   1.753 +			aInfo.iHeapSizeMin = ntHead->OptionalHeader.SizeOfHeapCommit;
   1.754 +			aInfo.iHeapSizeMax = ntHead->OptionalHeader.SizeOfHeapReserve;
   1.755 +			aInfo.iStackSize = 0x1000;
   1.756 +			aInfo.iPriority = hdr->iPriority;
   1.757 +			aInfo.iHandle = NULL;
   1.758 +			aInfo.iS = hdr->iS;
   1.759 +			aInfo.iModuleVersion = hdr->iModuleVersion;
   1.760 +			if (ntHead->FileHeader.Characteristics & IMAGE_FILE_DLL)
   1.761 +				aInfo.iAttr |= ECodeSegAttHDll;
   1.762 +			}
   1.763 +		}
   1.764 +	GetUids(aInfo.iUids);
   1.765 +	}
   1.766 +
   1.767 +
   1.768 +/**
   1.769 +Finds the import section from the data directory. This relies on the module being loaded.
   1.770 +		
   1.771 +@return 	Returns the imported executable.
   1.772 +*/
   1.773 +EXPORT_C const IMAGE_IMPORT_DESCRIPTOR* Emulator::TModule::Imports() const
   1.774 +	{
   1.775 +	if (!IsLoaded())
   1.776 +		return NULL;
   1.777 +	const IMAGE_NT_HEADERS32* ntHead = NtHeader();
   1.778 +	if (!ntHead)
   1.779 +		return NULL;
   1.780 +	DWORD va = ntHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
   1.781 +	if (!va)
   1.782 +		return NULL;
   1.783 +	return (const IMAGE_IMPORT_DESCRIPTOR*)Translate(va);
   1.784 +	}
   1.785 +
   1.786 +// modules in the file system
   1.787 +EXPORT_C TInt Emulator::RImageFile::Open(LPCTSTR aImageFile)
   1.788 +	{
   1.789 +	Buf8<MAX_PATH>   nameBuf(aImageFile);
   1.790 +	char *pName = (char *)strrchr(LPCSTR(nameBuf), '\\');
   1.791 +	pName ? ++pName : pName = (char *)LPCSTR(nameBuf);
   1.792 +
   1.793 +	__LOCK_HOST;
   1.794 +	iMapping = OpenFileMapping(FILE_MAP_READ, FALSE, (LPCTSTR)pName);
   1.795 +	if (!iMapping)
   1.796 +		{
   1.797 +		if (pName == (char *)LPCSTR(nameBuf))
   1.798 +			iModule = Emulator::GetModuleHandle(aImageFile);
   1.799 +		if (iModule)
   1.800 +			iBase = iModule;
   1.801 +		else
   1.802 +			{
   1.803 +			// need to map the file instead
   1.804 +			HANDLE file = Emulator::CreateFile(aImageFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
   1.805 +			if (file == INVALID_HANDLE_VALUE)
   1.806 +				return LastError();
   1.807 +			iMapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, pName);
   1.808 +			CloseHandle(file);
   1.809 +			}
   1.810 +		}
   1.811 +	if (!iModule)
   1.812 +		{
   1.813 +		if (!iMapping)
   1.814 +			return LastError();
   1.815 +
   1.816 +		iBase = MapViewOfFile(iMapping, FILE_MAP_READ, 0, 0, 0);
   1.817 +
   1.818 +		if (!iBase)
   1.819 +			{
   1.820 +			CloseHandle(iMapping);
   1.821 +			iMapping = 0;
   1.822 +			return LastError();
   1.823 +			}
   1.824 +		}
   1.825 +
   1.826 +	if (!NtHeader())
   1.827 +		{
   1.828 +		Close();
   1.829 +		return KErrNotSupported;
   1.830 +		}
   1.831 +	return KErrNone;
   1.832 +	}
   1.833 +
   1.834 +EXPORT_C void Emulator::RImageFile::Close()
   1.835 +	{
   1.836 +	if (iMapping)
   1.837 +		{
   1.838 +		UnmapViewOfFile(iBase);
   1.839 +		CloseHandle(iMapping);
   1.840 +		iMapping = 0;
   1.841 +		}
   1.842 +	iBase = 0;
   1.843 +	iModule = 0;
   1.844 +	}