emulator/emulatorbsp/specific/property.cpp
changeset 0 cec860690d41
child 14 cf4c5641c6dd
equal deleted inserted replaced
-1:000000000000 0:cec860690d41
       
     1 // Copyright (c) 1998-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 "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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // wins\specific\property.cpp
       
    15 // Emulator property management for emulator settings
       
    16 // 
       
    17 //
       
    18 
       
    19 #define _CRTIMP			// we want to use the static runtime library
       
    20 
       
    21 #define __INCLUDE_CAPABILITY_NAMES__
       
    22 #include "variant.h"
       
    23 #include <string.h>
       
    24 #include <stdlib.h>
       
    25 #include <emulator.h>
       
    26 
       
    27 #ifdef _DEBUG
       
    28 #define _DUMP_PROPERTY
       
    29 #endif
       
    30 
       
    31 const char* KDefaultMachineName = "epoc";
       
    32 const char* KDefaultTestMachineName = "defaulttest";
       
    33 
       
    34 // name of the environment variable to check for default path
       
    35 const char* KDefaultEpocRootName = "EPOCROOT";
       
    36 
       
    37 TInt ScreenId=0;
       
    38 
       
    39 // At the point this is created there is no kernel heap available
       
    40 // So all memory allocation is done from a custom allocator
       
    41 
       
    42 const TInt KMaxTokenLength = 255;
       
    43 
       
    44 class Allocator
       
    45 	{
       
    46 	enum {ETotalMemory=0x10000};	// 64K
       
    47 public:
       
    48 	Allocator();
       
    49 	TAny* Alloc(TInt aSize);
       
    50 	TAny* Realloc(TAny* aCell, TInt aSize);
       
    51 	void Free(TAny* aCell);
       
    52 private:
       
    53 	TUint iBuf[ETotalMemory];
       
    54 	TUint* iFree;
       
    55 	};
       
    56 
       
    57 Allocator::Allocator()
       
    58 	:iFree(iBuf)
       
    59 	{}
       
    60 
       
    61 TAny* Allocator::Alloc(TInt aSize)
       
    62 	{
       
    63 	aSize = (aSize + 7) >> 2;
       
    64 	if (iFree + aSize > iBuf + ETotalMemory)
       
    65 		return NULL;
       
    66 	TUint* p = iFree;
       
    67 	iFree += aSize;
       
    68 	*p++ = aSize;
       
    69 	return p;
       
    70 	}
       
    71 
       
    72 TAny* Allocator::Realloc(TAny* aCell, TInt aSize)
       
    73 	{
       
    74 	if (!aCell)
       
    75 		return Alloc(aSize);
       
    76 
       
    77 	TUint* p = (TUint*)aCell;
       
    78 	TInt size = *--p;
       
    79 	if (iFree == p + size)
       
    80 		{
       
    81 		aSize = (aSize + 7) >> 2;
       
    82 		if (p + aSize > iBuf + ETotalMemory)
       
    83 			return NULL;
       
    84 		iFree = p + aSize;
       
    85 		*p = aSize;
       
    86 		return aCell;
       
    87 		}
       
    88 
       
    89 	TAny* newp = Alloc(aSize);
       
    90 	if (newp)
       
    91 		{
       
    92 		memcpy(newp, aCell, size*sizeof(TUint));
       
    93 		Free(aCell);
       
    94 		}
       
    95 	return newp;
       
    96 	}
       
    97 
       
    98 void Allocator::Free(TAny* )
       
    99 	{
       
   100 	}
       
   101 
       
   102 Allocator TheAllocator;
       
   103 
       
   104 ///////
       
   105 
       
   106 char* Duplicate(const char* aString)
       
   107 	{
       
   108 	if (aString == NULL)
       
   109 		aString = "";
       
   110 
       
   111 	TInt size = strlen(aString) + 1;
       
   112 	char* p = (char*)TheAllocator.Alloc(size);
       
   113 	if (p)
       
   114 		memcpy(p, aString, size);
       
   115 	return p;
       
   116 	}
       
   117 
       
   118 // Properties class implementation
       
   119 
       
   120 Properties::Properties()
       
   121 	:iEntries(NULL),iCount(0),iSize(0)
       
   122 	{}
       
   123 
       
   124 const char* Properties::Insert(TInt aIndex, const char* aProperty, const char* aValue)
       
   125 	{
       
   126 	if (iCount == iSize)
       
   127 		{
       
   128 		TInt size = iSize == 0 ? 8 : iSize*2;
       
   129 		TAny* array = TheAllocator.Realloc(iEntries, size*sizeof(SEntry));
       
   130 		if (array == NULL)
       
   131 			return NULL;
       
   132 		iEntries = (SEntry*)array;
       
   133 		iSize = size;
       
   134 		}
       
   135 
       
   136 	char* prop = Duplicate(aProperty);
       
   137 	if (prop == NULL)
       
   138 		return NULL;
       
   139 	char* value = Duplicate(aValue);
       
   140 	if (value == NULL)
       
   141 		TheAllocator.Free(prop);
       
   142 	else
       
   143 		{
       
   144 		SEntry* e = &iEntries[aIndex];
       
   145 		memmove(e+1, e, (iCount-aIndex)*sizeof(SEntry));
       
   146 		e->iProperty = prop;
       
   147 		e->iValue = value;
       
   148 		++iCount;
       
   149 		}
       
   150 	return value;
       
   151 	}
       
   152 
       
   153 const char* Properties::Replace(const char* aProperty, const char* aValue)
       
   154 	{
       
   155 	TInt ix = Find(aProperty);
       
   156 	if (ix < 0)
       
   157 		return Insert(~ix, aProperty, aValue);
       
   158 	// replacing a property
       
   159 	SEntry& e = iEntries[ix];
       
   160 	char* value = Duplicate(aValue);
       
   161 	if (value != NULL)
       
   162 		{
       
   163 		TheAllocator.Free(e.iValue);
       
   164 		e.iValue = value;
       
   165 		}
       
   166 	return value;
       
   167 	}
       
   168 
       
   169 const char* Properties::Append(const char* aProperty, const char* aValue)
       
   170 	{
       
   171 	TInt ix = Find(aProperty);
       
   172 	if (ix < 0)
       
   173 		return Insert(~ix, aProperty, aValue);
       
   174 
       
   175 	// append a property
       
   176 	SEntry& e = iEntries[ix];
       
   177 	TInt size = strlen(e.iValue) + strlen(aValue) + 2;
       
   178 	char* value = (char*)TheAllocator.Realloc(e.iValue, size);
       
   179 	if (value != NULL)
       
   180 		{
       
   181 		strcat(value, ";");
       
   182 		strcat(value, aValue);
       
   183 		e.iValue = value;
       
   184 		}
       
   185 	return value;
       
   186 	}
       
   187 
       
   188 TInt Properties::GetString(const char* aProperty, const char*& aValue) const
       
   189 	{
       
   190 	TInt ix = Find(aProperty);
       
   191 	if (ix < 0)
       
   192 		return KErrNotFound;
       
   193 	aValue = iEntries[ix].iValue;
       
   194 	return KErrNone;
       
   195 	}
       
   196 
       
   197 TInt Properties::GetInt(const char* aProperty, TInt& aValue) const
       
   198 	{
       
   199 	TInt ix = Find(aProperty);
       
   200 	if (ix < 0)
       
   201 		return KErrNotFound;
       
   202 	char* value = iEntries[ix].iValue;
       
   203 	char* end;
       
   204 	TBool neg = *value=='-';
       
   205 	value += neg;
       
   206 	long val = strtoul(value, &end, 0);
       
   207 	if(neg)
       
   208 		{
       
   209 		if(val<0)
       
   210 			return KErrArgument;
       
   211 		val = -val;
       
   212 		}
       
   213 	if (*end != '\0')
       
   214 		return KErrArgument;
       
   215 	aValue = val;
       
   216 	return KErrNone;
       
   217 	}
       
   218 
       
   219 TInt Properties::GetBool(const char* aProperty, TBool& aValue, TBool aDefaultValue) const
       
   220 	{
       
   221 	TInt ix = Find(aProperty);
       
   222 	if (ix < 0)
       
   223 		{
       
   224 		aValue = aDefaultValue;
       
   225 		return KErrNone;
       
   226 		}
       
   227 	const char* value=iEntries[ix].iValue;
       
   228 	if (_stricmp(value, "on")==0 || _stricmp(value, "yes")==0 || _stricmp(value, "1")==0 || strlen(value)==0)
       
   229 		{
       
   230 		aValue = ETrue;
       
   231 		return KErrNone;
       
   232 		}
       
   233 	if (_stricmp(value, "off")==0 || _stricmp(value, "no")==0 || _stricmp(value, "0")==0 )
       
   234 		{
       
   235 		aValue = EFalse;
       
   236 		return KErrNone;
       
   237 		}
       
   238 
       
   239 	// Bool property has an illegal value!
       
   240 	return KErrArgument;
       
   241 	}
       
   242 
       
   243 TInt Properties::Find(const char* aProperty) const
       
   244 //
       
   245 // Lookup a property in the table
       
   246 // return index (>=0) if found, ~insertion-point (<0) if not
       
   247 //
       
   248 	{
       
   249 	TInt l = 0, r = iCount;
       
   250 	while (l < r)
       
   251 		{
       
   252 		TInt m = (l + r) >> 1;
       
   253 		const SEntry& e = iEntries[m];
       
   254 		TInt k = _stricmp(aProperty,e.iProperty);
       
   255 		if (k < 0)
       
   256 			r = m;
       
   257 		else if (k > 0)
       
   258 			l = m + 1;
       
   259 		else
       
   260 			return m;
       
   261 		}
       
   262 	return ~l;
       
   263 	}
       
   264 
       
   265 #ifdef _DUMP_PROPERTY
       
   266 void Properties::Dump() const
       
   267 	{
       
   268 	for (TInt i = 0; i < iCount; ++i)
       
   269 		{
       
   270 		const SEntry& e = iEntries[i];
       
   271 		char buf[512];
       
   272 		strcpy(buf, e.iProperty);
       
   273 		TInt len = strlen(e.iValue);
       
   274 		if (len)
       
   275 			{
       
   276 			strcat(buf, " = ");
       
   277 			if (len <= 256)
       
   278 				strcat(buf, e.iValue);
       
   279 			else
       
   280 				{
       
   281 				strncat(buf, e.iValue, 256);
       
   282 				strcat(buf, "...");
       
   283 				}
       
   284 			}
       
   285 		strcat(buf, "\r\n");
       
   286 		OutputDebugStringA(buf);
       
   287 		}
       
   288 	}
       
   289 #endif
       
   290 
       
   291 // Property related variant functions
       
   292 
       
   293 TInt Wins::EmulatorHal(TInt aFunction, TAny* a1, TAny* a2)
       
   294 	{
       
   295 	TInt r=KErrNone;
       
   296 	switch(aFunction)
       
   297 		{
       
   298 		case EEmulatorHalStringProperty:
       
   299 			return iProperties.GetString((const char*)a1,*(const char**)a2);
       
   300 		case EEmulatorHalIntProperty:
       
   301 			return iProperties.GetInt((const char*)a1,*(TInt*)a2);
       
   302 		case EEmulatorHalBoolProperty:
       
   303 			return iProperties.GetBool((const char*)a1,*(TBool*)a2);
       
   304 		case EEmulatorHalMapFilename:
       
   305 			return MapFilename(*(const TDesC*)a1,*(TDes*)a2);
       
   306 		case EEmulatorHalSetFlip:
       
   307 			{
       
   308 			if (iUi)
       
   309 				{
       
   310 				TInt screen = (TInt)a2;
       
   311 				if((TUint)screen < (TUint)iUi->NumberOfScreens())
       
   312 					return iUi->SetFlip(TEmulatorFlip(TInt(a1)),screen);
       
   313 				}
       
   314 			break;
       
   315 			}
       
   316 		case EEmulatorHalColorDepth:
       
   317 			{
       
   318 			TUint colorDepth = KDefaultColorDepth;
       
   319 			if(iUi)
       
   320 				{
       
   321 				if((TUint)a2 < (TUint)iUi->NumberOfScreens())
       
   322 					colorDepth = iUi->ColorDepth((TInt)a2);
       
   323 				}
       
   324 			*(TUint*)a1 = colorDepth;
       
   325 			return KErrNone;
       
   326 			}
       
   327 		case EEmulatorHalCPUSpeed:
       
   328 			if (a1)
       
   329 				return SetCpuSpeed(TUint(a2)/1000);
       
   330 			*(TInt*)a2 = iCpuSpeed ? iCpuSpeed * 1000 : 1;
       
   331 			return KErrNone;
       
   332 		case EEmulatorHalNumberOfScreens:
       
   333 			*(TInt*)a2 = iUi ? iUi->NumberOfScreens() : 1;
       
   334 			return KErrNone;
       
   335 		case EEmulatorHalSetDisplayChannel:
       
   336 			if (iUi && (TUint)a1 < (TUint)iUi->NumberOfScreens())
       
   337 				{
       
   338 				r = iUi->SetDisplayChannel((TInt)a1, static_cast<DDisplayChannel*>(a2));
       
   339 				}
       
   340 			else
       
   341 				{
       
   342 				r = KErrNotSupported;
       
   343 				}
       
   344 			break;
       
   345 		default:
       
   346 			r=KErrNotSupported;
       
   347 			break;
       
   348 		}
       
   349 	return r;
       
   350 	}
       
   351 
       
   352 const char* KExtensionListNormal = "btracex.ldd;hcr.dll;winsgui;elocd.ldd;medint.pdd;medlfs.pdd;medmmc.pdd;epbusmmc.dll;epbusv.dll";
       
   353 const char* KExtensionUsiiNand = "?medusiiw.pdd";
       
   354 const char* KExtensionUsiiNandLoader = "?medusiiws.pdd";
       
   355 const char* KExtensionUsiiNandTest = "?medusiiwt.pdd";
       
   356 
       
   357 
       
   358 
       
   359 
       
   360 const int KMaxEpocRootSize = 120;
       
   361 
       
   362 TInt Wins::InitProperties(TBool aRunExe)
       
   363 	{
       
   364 	if (iProperties.Replace("MachineName", KDefaultMachineName) == NULL)
       
   365 		return KErrNoMemory;
       
   366 
       
   367     char epocRoot[KMaxEpocRootSize];
       
   368 
       
   369     TInt total = GetEnvironmentVariableA( KDefaultEpocRootName, epocRoot, KMaxEpocRootSize);
       
   370 
       
   371     if (total != 0)
       
   372 		{
       
   373 	    if (iProperties.Replace("EpocRoot", epocRoot) == NULL)
       
   374     	    return KErrNoMemory;
       
   375 		}
       
   376 
       
   377 	if (iProperties.Append("Extension", KExtensionListNormal) == NULL)
       
   378 		return KErrNoMemory;
       
   379 
       
   380 	char overrideCDrive[MAX_PATH];
       
   381 	overrideCDrive[0] = '\0';
       
   382 	TInt r = ProcessCommandLine(aRunExe, overrideCDrive);
       
   383 	if (r != KErrNone)
       
   384 		return r;
       
   385 
       
   386 	r = SetupPaths();
       
   387 	if (r != KErrNone)
       
   388 		return r;
       
   389 
       
   390 	r = LoadProperties();
       
   391 	if (r != KErrNone)
       
   392 		return r;
       
   393 
       
   394 	//	get Unistore II Media Driver type from epoc.ini
       
   395 	const char* value = NULL;
       
   396 	
       
   397 
       
   398 	iProperties.GetString("NandDriverType", value);
       
   399 	if (value)
       
   400 		{
       
   401 		if (value && _stricmp("XSR",value)==0)
       
   402 			{
       
   403 			// epoc.ini "NandDriverType=XSR" for XSR/Unistore-II driver
       
   404 			if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL)
       
   405 				return KErrNoMemory;		
       
   406 			}
       
   407 		else if (value && _stricmp("XSRNandloader",value)==0)
       
   408 			{
       
   409 			// epoc.ini "NandDriverType=XSRNandloader" for XSR/Unistore-II nandloader driver
       
   410 			if (iProperties.Append("Extension", KExtensionUsiiNandLoader) == NULL)
       
   411 				return KErrNoMemory;		
       
   412 			}
       
   413 		else if (value && _stricmp("XSRTest",value)==0)
       
   414 			{
       
   415 			// epoc.ini "NandDriverType=XSRTest" for XSR/Unistore-II test driver
       
   416 			if (iProperties.Append("Extension", KExtensionUsiiNandTest) == NULL)
       
   417 				return KErrNoMemory;
       
   418 			}
       
   419 		else	
       
   420 			{
       
   421 			// If epoc.ini contains "NandDriverType=???" but ??? not equal to any
       
   422 			// of above XSR driver types then load production/release XSR
       
   423 			// driver
       
   424 			if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL)
       
   425 				return KErrNoMemory;
       
   426 
       
   427 			}
       
   428 		}
       
   429 	else
       
   430 		{
       
   431 		// Load the production/release XSR driver, if value is NULL
       
   432 		if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL)
       
   433 			return KErrNoMemory;
       
   434 
       
   435 		}
       
   436 	
       
   437 
       
   438 //	load additional configuration specific properties
       
   439 
       
   440 //	get the multi property "configuration"
       
   441 	value = NULL;
       
   442 	iProperties.GetString("configuration", value);
       
   443 	
       
   444 //	load each one of these
       
   445 //	check for any screen specific properties in the main epoc.ini
       
   446 //	if configuration property is set
       
   447 	if (value && !iConfigPropertySet)	//configuration
       
   448 		{
       
   449 		iConfigId = 0;
       
   450 		char configFileName[100];
       
   451 		do
       
   452 			{
       
   453 			//load each set of properties
       
   454 
       
   455 		   const char * pdest = strchr(value, ';');
       
   456 		   TInt result = pdest - value;
       
   457 		   if(pdest)
       
   458 			   {
       
   459 			   strncpy(configFileName, value, result);
       
   460 			   configFileName[result] = '\0';
       
   461 			   value = value + result + 1;
       
   462 			   }
       
   463 		   else
       
   464 			   {
       
   465 			   strcpy(configFileName, value);
       
   466 			   value += strlen(value);
       
   467 			   }
       
   468 
       
   469 			r = LoadConfigSpecificProperties(configFileName);
       
   470 			if (r == KErrNone)
       
   471 				iConfigId++;
       
   472 			}
       
   473 		while(*value);
       
   474 		}
       
   475 
       
   476 	char scr[30];
       
   477 	//if iConfigId is zero, there is only 1 configuration
       
   478 	wsprintfA(scr, "ConfigCount %d", iConfigId ? iConfigId : 1);
       
   479 	r = AddProperty(scr, scr+strlen(scr));
       
   480 	if (r != KErrNone)
       
   481 		return r;
       
   482 
       
   483 	r = SetupMediaPath();
       
   484 	if (r != KErrNone)
       
   485 		return r;
       
   486 
       
   487 	if (overrideCDrive[0] != '\0')
       
   488 		SetupDrive('c', overrideCDrive);
       
   489 
       
   490 	if (iProperties.Append("Extension", "exstart") == NULL)
       
   491 		return KErrNoMemory;
       
   492 
       
   493 #ifdef _DUMP_PROPERTY
       
   494 	iProperties.Dump();
       
   495 #endif
       
   496 
       
   497 	return KErrNone;
       
   498 	}
       
   499 
       
   500 char* skipws(char* aPtr)
       
   501 	{
       
   502 	while (isspace(*aPtr))
       
   503 		++aPtr;
       
   504 	return aPtr;
       
   505 	}
       
   506 
       
   507 char* skiptok(char* aPtr)
       
   508 	{
       
   509 	if (*aPtr == '\"')
       
   510 		{
       
   511 		++aPtr;
       
   512 		while (*aPtr && *aPtr++ != '\"')
       
   513 			{}
       
   514 		}
       
   515 	else
       
   516 		{
       
   517 		while (*aPtr && !isspace(*aPtr))
       
   518 			++aPtr;
       
   519 		}
       
   520 	return aPtr;
       
   521 	}
       
   522 
       
   523 #ifdef _DEBUG
       
   524 struct TDebugTrace
       
   525 	{
       
   526 	const char* iName;
       
   527 	TInt iMask;
       
   528 	};
       
   529 
       
   530 // Only the first 32 trace bits can be defined using these values
       
   531 // "ALWAYS" in this context means all of the first 32 bits not all 256 bits
       
   532 const TDebugTrace KTraceValues[] =
       
   533 	{
       
   534 	{"ALWAYS", KALWAYS},
       
   535 	{"BOOT", 1<<KBOOT},
       
   536 	{"DEVICE", 1<<KDEVICE},
       
   537 	{"DFC", 1<<KDFC},
       
   538 	{"DLL", 1<<KDLL},
       
   539 	{"EVENT", 1<<KEVENT},      
       
   540 	{"EXEC", 1<<KEXEC},
       
   541 	{"DEBUGGER", 1<<KDEBUGGER},
       
   542 	{"EXTENSION", 1<<KEXTENSION},
       
   543 	{"FAIL", 1<<KFAIL},
       
   544 	{"HARDWARE", 1<<KHARDWARE},
       
   545 	{"IPC", 1<<KIPC},
       
   546 	{"LOCDRV", 1<<KLOCDRV},
       
   547 	{"MEMTRACE", 1<<KMEMTRACE},
       
   548 	{"MMU", 1<<KMMU},
       
   549 	{"NKERN", 1<<KNKERN},
       
   550 	{"OBJECT", 1<<KOBJECT},
       
   551 	{"PANIC", 1<<KPANIC},
       
   552 	{"PBUS1", 1<<KPBUS1},
       
   553 	{"PBUS2", 1<<KPBUS2},
       
   554 	{"PBUSDRV", 1<<KPBUSDRV},
       
   555 	{"POWER", 1<<KPOWER},      
       
   556 	{"PROC", 1<<KPROC},
       
   557 	{"SCHED", 1<<KSCHED},
       
   558 	{"SCHED2", 1<<KSCHED2},
       
   559 	{"SCRATCH", 1<<KSCRATCH},
       
   560 	{"SEMAPHORE", 1<<KSEMAPHORE},
       
   561 	{"SERVER", 1<<KSERVER},
       
   562 	{"THREAD", 1<<KTHREAD},
       
   563 	{"THREAD2", 1<<KTHREAD2},
       
   564 	{"TIMING", 1<<KTIMING},
       
   565 	{"DMA", 1<<KDMA},
       
   566 	{"MMU2", 1<<KMMU2}
       
   567 	};
       
   568 const TInt KMaxTraceName = 9;
       
   569 const TInt KCountTraceValues = sizeof(KTraceValues)/sizeof(TDebugTrace);
       
   570 
       
   571 static const TDebugTrace* TraceType(const char* aTrace, TInt aLen)
       
   572 	{
       
   573 	if (aLen > KMaxTraceName)
       
   574 		return 0;
       
   575 
       
   576 	char name[KMaxTraceName + 1];
       
   577 	strncpy(name, aTrace, aLen);
       
   578 	name[aLen] = '\0';
       
   579 
       
   580 	for (TInt i=KCountTraceValues; --i>=0;)
       
   581 		{
       
   582 		if (_stricmp(name, KTraceValues[i].iName)==0)
       
   583 			return &KTraceValues[i];
       
   584 		}
       
   585 	return 0;
       
   586 	}
       
   587 #endif
       
   588 
       
   589 TInt Wins::DebugMask()
       
   590 	{
       
   591 	TInt mask = KDefaultDebugMask;
       
   592 	if (iProperties.GetInt("DebugMask", mask) != KErrArgument)
       
   593 		return mask;
       
   594 #ifdef _DEBUG
       
   595 	// allow text ones
       
   596 	const char* e;
       
   597 	if (iProperties.GetString("DebugMask", e) != KErrNone)
       
   598 		return mask;
       
   599 
       
   600 	for (;;)
       
   601 		{
       
   602 		char* p = skipws((char*)e);
       
   603 		if (*p == 0)
       
   604 			break;
       
   605 		e = skiptok(p);
       
   606 		TBool add = ETrue;
       
   607 		if (*p == '+')
       
   608 			++p;
       
   609 		else if (*p == '-')
       
   610 			{
       
   611 			add = EFalse;
       
   612 			++p;
       
   613 			}
       
   614 		const TDebugTrace* type = TraceType(p, e - p);
       
   615 		if (type)
       
   616 			{
       
   617 			if (add)
       
   618 				mask |= type->iMask;
       
   619 			else
       
   620 				mask &= ~type->iMask;
       
   621 			}
       
   622 		}
       
   623 #endif
       
   624 	return mask;
       
   625 	}
       
   626 
       
   627 TUint32 Wins::KernelConfigFlags()
       
   628 	{
       
   629 	TUint32 flags = 0;
       
   630 	TBool b;
       
   631 
       
   632 	b=0;
       
   633 	iProperties.GetBool("PlatSecEnforcement",b,EFalse);
       
   634 	if(b) flags |= EKernelConfigPlatSecEnforcement;
       
   635 	Wins::EarlyLogging("PlatSecEnforcement ",b?"ON":"OFF");
       
   636 
       
   637 	b=0;
       
   638 	iProperties.GetBool("PlatSecDiagnostics",b,EFalse);
       
   639 	if(b) flags |= EKernelConfigPlatSecDiagnostics;
       
   640 	Wins::EarlyLogging("PlatSecDiagnostics ",b?"ON":"OFF");
       
   641 
       
   642 	b=0;
       
   643 	iProperties.GetBool("PlatSecProcessIsolation",b,EFalse);
       
   644 	if(b) flags |= EKernelConfigPlatSecProcessIsolation;
       
   645 	Wins::EarlyLogging("PlatSecProcessIsolation ",b?"ON":"OFF");
       
   646 
       
   647 	b=0;
       
   648 	iProperties.GetBool("PlatSecEnforceSysBin",b,EFalse);
       
   649 	if(b) flags |= EKernelConfigPlatSecEnforceSysBin;
       
   650 	Wins::EarlyLogging("PlatSecEnforceSysBin ",b?"ON":"OFF");
       
   651 
       
   652 	b=0;
       
   653 	iProperties.GetBool("CrazyScheduling",b,EFalse);
       
   654 	if(b) flags |= EKernelConfigCrazyScheduling;
       
   655 	Wins::EarlyLogging("CrazyScheduling ",b?"ON":"OFF");
       
   656 
       
   657 	return flags;
       
   658 	}
       
   659 
       
   660 void Wins::DisabledCapabilities(SCapabilitySet& aCapabilities)
       
   661 	{
       
   662 	const char* text;
       
   663 	if(iProperties.GetString("PlatSecDisabledCaps", text)!=KErrNone)
       
   664 		text = "NONE";
       
   665 	Wins::EarlyLogging("PlatSecDisabledCaps ",text);
       
   666 	ParseCapabilitiesArg(aCapabilities,text);
       
   667 	}
       
   668 
       
   669 #define PARSE_CAPABILITIES_ERROR(aMessage) Wins::EarlyLogging(aMessage,0)
       
   670 #define PARSE_CAPABILITIES_ERROR2(aMessage,aArg) Wins::EarlyLogging(aMessage,aArg)
       
   671 #define strnicmp _strnicmp
       
   672 
       
   673 TInt Wins::ParseCapabilitiesArg(SCapabilitySet& aCapabilities, const char *aText)
       
   674 //
       
   675 // This is a cun'n'paste copy of the function in TOOLS\E32TOOLS\HOST\H_UTIL.CPP
       
   676 // Keep both of these versions up to date with each other
       
   677 //
       
   678 	{
       
   679 	memset(&aCapabilities,0,sizeof(aCapabilities));
       
   680 	char c;
       
   681 	while((c=*aText)!=0)
       
   682 		{
       
   683 		if(c<=' ')
       
   684 			{
       
   685 			++aText;
       
   686 			continue;
       
   687 			}
       
   688 		int invert=0;
       
   689 		if(c=='+')
       
   690 			{
       
   691 			++aText;
       
   692 			c=*aText;
       
   693 			}
       
   694 		if(c=='-')
       
   695 			{
       
   696 			invert=1;
       
   697 			++aText;
       
   698 			}
       
   699 		const char* name = aText;
       
   700 		while((c=*aText)>' ')
       
   701 			{
       
   702 			if(c=='-' || c=='+')
       
   703 				break;
       
   704 			++aText;
       
   705 			}
       
   706 		TInt n = aText-name;
       
   707 		TInt i;
       
   708 
       
   709 		if(n==3 && strnicmp("all",name,n)==0)
       
   710 			{
       
   711 			if(invert)
       
   712 				{
       
   713 				PARSE_CAPABILITIES_ERROR("Capability '-ALL' not allowed");
       
   714 				return KErrArgument;
       
   715 				}
       
   716 			for(i=0; i<ECapability_Limit; i++)
       
   717 				{
       
   718 				if(CapabilityNames[i])
       
   719 					aCapabilities[i>>5] |= (1<<(i&31));
       
   720 				}
       
   721 			continue;
       
   722 			}
       
   723 
       
   724 		if(n==4 && strnicmp("none",name,n)==0)
       
   725 			{
       
   726 			if(invert)
       
   727 				{
       
   728 				PARSE_CAPABILITIES_ERROR("Capability '-NONE' not allowed");
       
   729 				return KErrArgument;
       
   730 				}
       
   731 			memset(&aCapabilities,0,sizeof(aCapabilities));
       
   732 			continue;
       
   733 			}
       
   734 
       
   735 		for(i=0; i<ECapability_Limit; i++)
       
   736 			{
       
   737 			const char* cap = CapabilityNames[i];
       
   738 			if(!cap)
       
   739 				continue;
       
   740 			if((int)strlen(cap)!=n)
       
   741 				continue;
       
   742 			if(strnicmp(cap,name,n)!=0)
       
   743 				continue;
       
   744 			break;
       
   745 			}
       
   746 		if(i>=ECapability_Limit)
       
   747 			{
       
   748 			char badName[32];
       
   749 			if(n>=sizeof(badName)) n=sizeof(badName)-1;
       
   750 			memcpy(badName,name,n);
       
   751 			badName[n]=0;
       
   752 			PARSE_CAPABILITIES_ERROR2("Unrecognised capability name: ",badName);
       
   753 			return KErrArgument;
       
   754 			}
       
   755 		if(invert)
       
   756 			aCapabilities[i>>5] &= ~(1<<(i&31));
       
   757 		else
       
   758 			aCapabilities[i>>5] |= (1<<(i&31));
       
   759 		}
       
   760 	return KErrNone;
       
   761 	}
       
   762 
       
   763 TInt Wins::AddProperty(char* aProperty, const char* aEol)
       
   764 	{
       
   765 	const char* tok = aProperty;
       
   766 	int c;
       
   767 	do
       
   768 		{
       
   769 		if (aProperty == aEol)
       
   770 			{
       
   771 			// boolean property
       
   772 			if (_stricmp(tok, "_NewScreen_") == 0)
       
   773  				{
       
   774  				++ScreenId;
       
   775  				return KErrNone;
       
   776  				}
       
   777 			else
       
   778 				{
       
   779 				char newtok[KMaxTokenLength];
       
   780 				if (ConfigSpecificProperty(tok))
       
   781 					{
       
   782 					wsprintfA(newtok, "Configuration[%d]", iConfigId);
       
   783 					strcat(newtok, tok);
       
   784 					tok = newtok;
       
   785 					}
       
   786 				}
       
   787 			return iProperties.Replace(tok, NULL) == NULL ? KErrNoMemory : KErrNone;
       
   788 			}
       
   789 		c=*aProperty++;
       
   790 		} while (isalnum(c) || c=='_');
       
   791 	aProperty[-1]='\0';	// terminate property name
       
   792 	while (isspace(c))
       
   793 		c=*aProperty++;
       
   794 	TBool append=ETrue;
       
   795 	if (c=='=')
       
   796 		{
       
   797 		append=EFalse;
       
   798 		c=*aProperty++;
       
   799 		}
       
   800 	else if (c=='+' && *aProperty=='=')
       
   801 		{
       
   802 		++aProperty;
       
   803 		c=*aProperty++;
       
   804 		}
       
   805 	while (isspace(c))
       
   806 		c=*aProperty++;
       
   807 	--aProperty;	// point back to value
       
   808 
       
   809 	if (_strnicmp(tok, "_epoc_drive_", 12) == 0)
       
   810 		return SetupDrive(tok[12], aProperty);
       
   811 	else
       
   812 		{
       
   813 		char newtok[KMaxTokenLength];
       
   814 		if (ConfigSpecificProperty(tok))
       
   815 			{
       
   816 			if (ScreenSpecificProperty(tok))
       
   817 				{
       
   818 				wsprintfA(newtok, "Configuration[%d][%d]", iConfigId, ScreenId);
       
   819 				}
       
   820 			else
       
   821 				{
       
   822 				wsprintfA(newtok, "Configuration[%d]", iConfigId);
       
   823 				}
       
   824 			strcat(newtok, tok);
       
   825 			tok = newtok;
       
   826 			}
       
   827 		if (append)
       
   828 			return iProperties.Append(tok, aProperty) == NULL ? KErrNoMemory : KErrNone;
       
   829 		else
       
   830 			return iProperties.Replace(tok, aProperty) == NULL ? KErrNoMemory : KErrNone;
       
   831 		}
       
   832 	}
       
   833 
       
   834 TInt Wins::ProcessCommandLine(TBool aRunExe, char* aCDrive)
       
   835 	{
       
   836 	if (aRunExe)
       
   837 		{
       
   838 		char exe[MAX_PATH];
       
   839 		DWORD len=GetModuleFileNameA(NULL, exe, MAX_PATH);
       
   840 		if (len == 0)
       
   841 			return KErrGeneral;
       
   842 		exe[len] = '\0';
       
   843 		const char* base = strrchr(exe, '\\') + 1;
       
   844 		if (iProperties.Replace("AutoRun", base) == NULL)
       
   845 			return KErrNoMemory;
       
   846 		}
       
   847 
       
   848 	char* cmd = skipws(skiptok(GetCommandLineA()));
       
   849 	if (strstr(cmd, "--") != NULL)
       
   850 		{
       
   851 		for (;;)
       
   852 			{
       
   853 			cmd = strchr(cmd, '-') + 1;
       
   854 			TInt opt = *cmd++;
       
   855 			if (opt == '-')
       
   856 				break;
       
   857 			char* end = skiptok(cmd);
       
   858 			*end = '\0';
       
   859 			switch (tolower(opt))
       
   860 				{
       
   861 			    case 'd':
       
   862 				    {
       
   863 				    TInt r = AddProperty(cmd, end);
       
   864 				    if (r != KErrNone)
       
   865 				    	return r;
       
   866 				    }
       
   867 				    break;
       
   868 			    case 'm':
       
   869 			    	// specify base name for .INI file
       
   870 				    if (iProperties.Replace("MachineName", cmd) == NULL)
       
   871 				    	return KErrNoMemory;
       
   872 				    break;
       
   873 			    case 'l':
       
   874 			    	// specify language
       
   875 			    	if (iProperties.Replace("TheMachineLanguageIndex", cmd) == NULL)
       
   876 			    		return KErrNoMemory;
       
   877 			    	break;
       
   878 		    	case 'c':
       
   879 		    		// specify path for emulated C drive
       
   880 			    	{
       
   881 			    	DWORD len=GetFullPathNameA(cmd, MAX_PATH, aCDrive, NULL);
       
   882 			    	if (len==0 || len >= MAX_PATH)
       
   883 			    		aCDrive[0] = '\0';
       
   884 			    	}
       
   885 			        break;
       
   886 			    case 't':
       
   887 			    	// specify the temp path as the emulated C drive
       
   888 			    	{
       
   889 			    	DWORD len=GetTempPathA(MAX_PATH, aCDrive);
       
   890 			    	if (len==0 || len >= MAX_PATH)
       
   891 			    		aCDrive[0] = '\0';
       
   892 			    	}
       
   893 			    	break;
       
   894 				}
       
   895 			cmd = end+1;
       
   896 			}
       
   897 		cmd = skipws(cmd);
       
   898 		}
       
   899 
       
   900 	if (aRunExe && iProperties.Replace("CommandLine", cmd) == NULL)
       
   901 		return KErrNoMemory;
       
   902 
       
   903 	return KErrNone;
       
   904 	}
       
   905 
       
   906 TInt Wins::LoadConfigSpecificProperties(const char * aFile)
       
   907 	{
       
   908 	const char* path;
       
   909 	TInt r = iProperties.GetString("EmulatorDataPath", path);
       
   910 	if (r != KErrNone)
       
   911 		return r;
       
   912 
       
   913 	char file[KMaxFileName + 1];
       
   914 	strcpy(file, path);
       
   915 	strcat(file, aFile);
       
   916 
       
   917 	char* iniData;
       
   918 	r = ReadIniFile(file, iniData);
       
   919 	if (r == KErrNone)
       
   920 		{
       
   921 		r = ReadProperties(iniData);
       
   922 		VirtualFree(iniData, 0, MEM_RELEASE);
       
   923 		}
       
   924 	else if (r == KErrNotFound)
       
   925 		r = KErrNotFound;
       
   926 
       
   927 	return r;
       
   928 
       
   929 	}
       
   930 
       
   931 
       
   932 
       
   933 TInt Wins::LoadProperties()
       
   934 	{
       
   935 	const char* path;
       
   936 	TInt r = iProperties.GetString("EmulatorDataPath", path);
       
   937 	if (r != KErrNone)
       
   938 		return r;
       
   939 	const char* name;
       
   940 	r = iProperties.GetString("MachineName", name);
       
   941 	if (r != KErrNone)
       
   942 		return r;
       
   943 retry:
       
   944 	char file[KMaxFileName + 1];
       
   945 	strcpy(file, path);
       
   946 	strcat(file, name);
       
   947 	strcat(file, ".ini");
       
   948 
       
   949 	char* iniData;
       
   950 	r = ReadIniFile(file, iniData);
       
   951 	if (r == KErrNone)
       
   952 		{
       
   953 		r = ReadProperties(iniData);
       
   954 		VirtualFree(iniData, 0, MEM_RELEASE);
       
   955 		}
       
   956 	else if (r == KErrNotFound)
       
   957 		{
       
   958 		if(_stricmp(name,KDefaultMachineName)==0)
       
   959 			{
       
   960 			// try test ini file
       
   961 			name = KDefaultTestMachineName;
       
   962 			goto retry;
       
   963 			}
       
   964 		r = KErrNone;		// no ini file - oh well
       
   965 		}
       
   966 
       
   967 	return r;
       
   968 	}
       
   969 
       
   970 TInt Wins::ReadProperties(char* aData)
       
   971 	{
       
   972 	ScreenId = 0;
       
   973 	while (*aData)
       
   974 		{
       
   975 		char* beg = aData;
       
   976 		char* eol = strchr(beg, '\n');
       
   977 		aData = eol+1;
       
   978 		if (eol == beg)
       
   979 			continue;
       
   980 		if (eol[-1] == '\r' && --eol == beg)
       
   981 			continue;
       
   982 		*eol = '\0';		// terminate line
       
   983 
       
   984 		while (isspace(*beg))
       
   985 			++beg;
       
   986 		char* comment = strchr(beg, '#');
       
   987 		if (comment)
       
   988 			eol = comment;
       
   989 		while (eol > beg && isspace(eol[-1]))
       
   990 			--eol;
       
   991 		if (beg == eol)
       
   992 			continue;
       
   993 		*eol = '\0';		// terminate line
       
   994 
       
   995 		TInt r = AddProperty(beg, eol);
       
   996 		if (r != KErrNone)
       
   997 			return r;
       
   998 		}
       
   999 	char sc[5];
       
  1000  	wsprintfA(sc, "%d", ScreenId+1);
       
  1001 	TInt screens;
       
  1002 	if(iProperties.GetInt("[screens]", screens) == KErrNone && screens > ScreenId)
       
  1003 		return KErrNone;
       
  1004  	else
       
  1005 		return iProperties.Replace("[screens]", sc)  == NULL ? KErrNoMemory : KErrNone;
       
  1006 	}
       
  1007 
       
  1008 TInt Wins::ReadIniFile(const char* aFileName, char*& aContents)
       
  1009 	{
       
  1010 	TInt r = KErrNone;
       
  1011 	HANDLE file=CreateFileA(aFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
       
  1012 	if (!file || file==INVALID_HANDLE_VALUE)
       
  1013 		r = KErrNotFound;	// More than likely !
       
  1014 	else
       
  1015 		{
       
  1016 		TInt size=GetFileSize(file, NULL);
       
  1017 		if (size==INVALID_FILE_SIZE)
       
  1018 			r = KErrGeneral;
       
  1019 		else
       
  1020 			{
       
  1021 			// fileSize+3 to ensure zero-termination of file and trailing CRLF
       
  1022 			// VirtualAlloc initializes memory to zero
       
  1023 			TAny* data = VirtualAlloc(NULL, size+3, MEM_COMMIT, PAGE_READWRITE);
       
  1024 			if (!data)
       
  1025 				r = KErrNoMemory;
       
  1026 			else
       
  1027 				{
       
  1028 				DWORD bytesRead;
       
  1029 				if (!ReadFile(file, data, size, &bytesRead, NULL))
       
  1030 					{
       
  1031 					VirtualFree(data, 0, MEM_RELEASE);
       
  1032 					r = KErrGeneral;
       
  1033 					}
       
  1034 				else
       
  1035 					{
       
  1036 					aContents = (LPSTR)data;
       
  1037 					strcpy(aContents + size,"\r\n");
       
  1038 					}
       
  1039 				}
       
  1040 			}
       
  1041 		CloseHandle(file);
       
  1042 		}
       
  1043 	return r;
       
  1044 	}
       
  1045 
       
  1046 
       
  1047 TInt Wins::SetupPaths()
       
  1048 //
       
  1049 // set up the Emulator paths
       
  1050 //
       
  1051 	{
       
  1052 	// the Emulator path
       
  1053 	CHAR path[KMaxFileName + 1];
       
  1054 	DWORD len=GetModuleFileNameA(NULL, path, KMaxFileName);
       
  1055 	if (len == 0)
       
  1056 		return(KErrGeneral);
       
  1057 	path[len] = '\0';
       
  1058 	_strlwr(path);
       
  1059 	*(strrchr(path, '\\') + 1) = '\0';
       
  1060 	const char* emulatorPath = iProperties.Replace("EmulatorPath", path);
       
  1061 	if (!emulatorPath)
       
  1062 		return KErrNoMemory;
       
  1063 
       
  1064 	CHAR drive[KMaxFileName + 1];
       
  1065 
       
  1066 	// the Emulator data path
       
  1067 	strcat(path, "data\\");
       
  1068 	DWORD att = GetFileAttributesA(path);
       
  1069 	if (att != -1 && (att&FILE_ATTRIBUTE_DIRECTORY))
       
  1070 		{
       
  1071 		// if Data directory exists in the emulator path, do things the new way
       
  1072 		strcpy(drive, emulatorPath);
       
  1073 		strcat(drive,"c\\");
       
  1074 		}
       
  1075 	else
       
  1076 		{
       
  1077 		// the old way
       
  1078 #if defined(__VC32__)
       
  1079 		char* p = strstr(path, "\\epoc32\\release\\wins\\");
       
  1080 #elif defined(__CW32__)
       
  1081 		char* p = strstr(path, "\\epoc32\\release\\winscw\\");
       
  1082 #endif
       
  1083 		if (p == NULL)
       
  1084 			return KErrNotFound;
       
  1085 		strcpy(p, "\\epoc32\\");
       
  1086 		strcpy(drive, path);
       
  1087 		strcat(path, "data\\");
       
  1088 #if defined(__VC32__)
       
  1089 		strcat(drive,"wins\\c\\");
       
  1090 #elif defined(__CW32__)
       
  1091 		strcat(drive,"winscw\\c\\");
       
  1092 #endif
       
  1093 		}
       
  1094 	if (!iProperties.Replace("EmulatorDataPath", path))
       
  1095 		return KErrNoMemory;
       
  1096 
       
  1097 	// The Emulator Image path (for temporary EXE files)
       
  1098 	const char* eip;
       
  1099 	TInt r = iProperties.GetString("EmulatorImagePath", eip);
       
  1100 	if (r!=KErrNone)
       
  1101 		{
       
  1102 		len=GetTempPathA(KMaxFileName, path);
       
  1103 		strcat(path, "epoc\\");
       
  1104 		char* p = path + strlen(path);
       
  1105 		*p++ = emulatorPath[0];
       
  1106 		strcpy(p, emulatorPath+2);
       
  1107 		if (!iProperties.Replace("EmulatorImagePath", path))
       
  1108 			return KErrNoMemory;
       
  1109 		}
       
  1110 	else
       
  1111 		strcpy(path, eip);
       
  1112 	if (!Emulator::CreateAllDirectories(path))
       
  1113 		return Emulator::LastError();
       
  1114 
       
  1115 	// Win32 filesystem paths mapped to local WINS drives
       
  1116 	r = SetupDrive('c',drive);  // set up C here, can be overridden by system.ini settings
       
  1117 	if (r)
       
  1118 		return(r);
       
  1119 
       
  1120 	strcpy(drive, emulatorPath);
       
  1121 	strcat(drive,"z\\");
       
  1122 
       
  1123 	r=SetupDrive('z',drive);  // set up Z here, can be overridden by system.ini settings
       
  1124 	if (r)
       
  1125 		return(r);
       
  1126 
       
  1127 	return(KErrNone);
       
  1128 	}
       
  1129 
       
  1130 TInt Wins::SetupMediaPath()
       
  1131 //
       
  1132 // Set up the path for emulated media devices 'EmulatedMediaPath'
       
  1133 // The default is <datapath>media/
       
  1134 // The system temporary path can be set by value '%temp%'
       
  1135 //
       
  1136 	{
       
  1137 	CHAR path[KMaxFileName + 1];
       
  1138 	const char* mpath;
       
  1139 	if (iProperties.GetString("EmulatorMediaPath", mpath) == KErrNotFound)
       
  1140 		{
       
  1141 		const char* dpath;
       
  1142 		TInt r = iProperties.GetString("EmulatorDataPath", dpath);
       
  1143 		if (r != KErrNone)
       
  1144 			return r;
       
  1145 		strcpy(path, dpath);
       
  1146 		strcat(path, "media\\");
       
  1147 		return iProperties.Replace("EmulatorMediaPath", path) ? KErrNone : KErrNoMemory;
       
  1148 		}
       
  1149 
       
  1150 	if (_stricmp(mpath, "%temp%") == 0)
       
  1151 		{
       
  1152 		DWORD len=GetTempPathA(KMaxFileName, path);
       
  1153 		if (len > 0 && len < KMaxFileName)
       
  1154 			return iProperties.Replace("EmulatorMediaPath", path) ? KErrNone : KErrNoMemory;
       
  1155 		}
       
  1156 
       
  1157 	return KErrNone;
       
  1158 	}
       
  1159 
       
  1160 const char* Wins::EmulatorMediaPath()
       
  1161 	{
       
  1162 	const char* mpath = NULL;
       
  1163 	iProperties.GetString("EmulatorMediaPath", mpath);
       
  1164 	return mpath;
       
  1165 	}
       
  1166 
       
  1167 TInt Wins::SetupDrive(int aDrive, const char* aPath)
       
  1168 //
       
  1169 // set up emulated drives
       
  1170 //
       
  1171 	{
       
  1172 
       
  1173 	// Z drive can't end in anything but "Z\\", since we chop this off and use
       
  1174 	// the resulting directory to find filenames with no drive specified in
       
  1175 	// MapFileName() below.
       
  1176 	aDrive = tolower(aDrive);
       
  1177 	if (aDrive=='z')
       
  1178 		{
       
  1179 		const char* end = aPath + strlen(aPath);
       
  1180 		if (_stricmp(end-2,"\\z") != 0 && _stricmp(end-3,"\\z\\") != 0)
       
  1181 			return KErrArgument;
       
  1182 		}
       
  1183 
       
  1184 	char prop[] = "_epoc_drive_?";
       
  1185 	*strchr(prop, '?') = char(aDrive);
       
  1186 
       
  1187 
       
  1188     // If the path begins with the keyword %epocroot%, replace this with EPOCROOT
       
  1189     if (_strnicmp(aPath, "%epocroot%", 10) == 0)
       
  1190         {
       
  1191 		aPath += 10; // skip "%epocroot%"
       
  1192 
       
  1193         const char* eRoot;
       
  1194         TInt r = iProperties.GetString("EpocRoot", eRoot);
       
  1195         if (r != KErrNone)
       
  1196             return r;
       
  1197 
       
  1198 		int rootSize = strlen(eRoot);
       
  1199 		int pathSize = strlen(aPath);
       
  1200 		if(rootSize+pathSize>MAX_PATH)
       
  1201 			return KErrArgument;
       
  1202 
       
  1203         char fullPath[MAX_PATH+1];
       
  1204 		memcpy(fullPath,eRoot,rootSize);
       
  1205 		memcpy(fullPath+rootSize,aPath,pathSize+1); // +1 to get the terminating NULL char
       
  1206 
       
  1207         return iProperties.Replace(prop, fullPath) ? KErrNone : KErrNoMemory;
       
  1208 
       
  1209         }
       
  1210     else
       
  1211         // otherwise, aPath is fully qualified path name. Use that.
       
  1212         return iProperties.Replace(prop, aPath) ? KErrNone : KErrNoMemory;
       
  1213   
       
  1214 	}
       
  1215 
       
  1216 TInt Wins::MapDrive(int aDrive, TDes& aBuffer) const
       
  1217 //
       
  1218 // Map aDrive to a path given by environment variables or defaults
       
  1219 // Use this function only in WINS builds
       
  1220 //
       
  1221 	{
       
  1222 	char drive[KMaxFileName + 1];
       
  1223 	char prop[] = "_epoc_drive_?";
       
  1224 	*strchr(prop, '?') = char(tolower(aDrive));
       
  1225 
       
  1226 	TInt len;
       
  1227 	const char* val;
       
  1228 	if (iProperties.GetString(prop, val) == KErrNone)
       
  1229 		{
       
  1230 		len = strlen(val);
       
  1231 		if (len > KMaxFileName)
       
  1232 			return KErrArgument;
       
  1233 		strcpy(drive, val);
       
  1234 		}
       
  1235 	else
       
  1236 		{
       
  1237 		// not in properties, so check environment
       
  1238 		len = GetEnvironmentVariableA(prop, drive, KMaxFileName + 1);
       
  1239 		if (len > KMaxFileName)
       
  1240 			return KErrArgument;
       
  1241 		}
       
  1242 	while (len > 0 && isspace(drive[len-1]))
       
  1243 		--len;
       
  1244 	if (len == 0)
       
  1245 		return KErrNotFound;
       
  1246 	if (drive[len-1] != '\\') // add trailing backslash
       
  1247 		drive[len++] = '\\';
       
  1248 	if (drive[0] == '\\')
       
  1249 		{
       
  1250 		// put in the emulator drive
       
  1251 		TInt r = iProperties.GetString("EmulatorPath", val);
       
  1252 		if (r != KErrNone)
       
  1253 			return r;
       
  1254 
       
  1255 		memmove(drive + 2, drive, len);
       
  1256 		drive[0] = val[0];
       
  1257 		drive[1] = ':';
       
  1258 		len += 2;
       
  1259 		}
       
  1260 	else if (len < 3 || drive[1] != ':' || drive[2] != '\\')
       
  1261 		return KErrArgument;
       
  1262 #ifdef _UNICODE
       
  1263 	TUint16* aBufPtr = (TUint16*)aBuffer.Ptr();
       
  1264 	const TText* drv = (const TText*)drive;
       
  1265 	for(int index=0;index<len;index++)
       
  1266 		*aBufPtr++ = (TUint16)*drv++;
       
  1267 	aBuffer.SetLength(len<<1);
       
  1268 #else
       
  1269 	aBuffer.Copy(TPtrC8((const TText8*)drive,len));
       
  1270 #endif
       
  1271 	return KErrNone;
       
  1272 	}
       
  1273 
       
  1274 TInt Wins::MapFilename(const TDesC& aFilename, TDes& aBuffer) const
       
  1275 //
       
  1276 // Map aFileName to real windows directory - aFileName must be a full filepath
       
  1277 //
       
  1278 	{
       
  1279 
       
  1280 	// if the filename does not have a drive specified then don't imagine
       
  1281 	// it describes an Epoc filepath
       
  1282 	// Assume it's a subdirectory/file of the file containing the emulated Z drive
       
  1283 	TInt offset;
       
  1284 	if (aFilename.Length() < 4 || aFilename[2] != ':')
       
  1285 		{
       
  1286 		TInt r = MapDrive('z', aBuffer);
       
  1287 		if (r)
       
  1288 			return(r);
       
  1289 		aBuffer.SetLength(aBuffer.Length()-4);	// chop "Z\\"
       
  1290 		offset = aFilename[0] == '\\' ? 1 : 0; // remove the guaranteed backslash
       
  1291 		}
       
  1292 	else
       
  1293 		{
       
  1294 		TInt r = MapDrive(aFilename[0], aBuffer);
       
  1295 		if (r)
       
  1296 			return(r);
       
  1297 		if (aFilename.Length() >= 6 && aFilename[4] == '\\')
       
  1298 			offset = 3;
       
  1299 		else
       
  1300 			offset = 2;
       
  1301 		}
       
  1302 #ifdef _UNICODE
       
  1303 	offset = offset<<1;
       
  1304 	TUint8* ptrFilename = (TUint8*)aFilename.Ptr() + offset;
       
  1305 	TUint8* ptrBuffer = (TUint8*)aBuffer.Ptr()+aBuffer.Length();
       
  1306 	if (aBuffer.MaxLength()<aBuffer.Length()+aFilename.Length()-offset+1)
       
  1307 		return KErrBadName;
       
  1308 
       
  1309 	memcpy(ptrBuffer, ptrFilename, aFilename.Length()-offset);
       
  1310 	aBuffer.SetLength(aBuffer.Length()+aFilename.Length()-offset);
       
  1311 #else
       
  1312 	TPtrC name(aFilename.Mid(offset));
       
  1313 	if (aBuffer.MaxLength()<aBuffer.Length()+name.Length()+1)
       
  1314 		return KErrBadName;
       
  1315 	aBuffer.Append(name);
       
  1316 #endif
       
  1317 	return KErrNone;
       
  1318 	}
       
  1319 
       
  1320 
       
  1321 //table of the property names which can be used in multiple configurations
       
  1322 const char * KConfigSpecificProperties[] =
       
  1323 	{
       
  1324 	"ScreenWidth",
       
  1325 	"ScreenHeight",
       
  1326 	"PhysicalScreenWidth",
       
  1327 	"PhysicalScreenHeight",
       
  1328 	"ScreenOffsetX",
       
  1329 	"ScreenOffsetY",
       
  1330 	"LedSize",
       
  1331 	"LedArrangeVertically",
       
  1332 	"LedArrangeHorizontally",
       
  1333 	"LedOffsetX",
       
  1334 	"LedOffsetY",
       
  1335 	"LedGap",
       
  1336 	"PointerType",
       
  1337 	"ColorDepth",
       
  1338 	"KeyMap",
       
  1339 	"DrawVirtualKeys",
       
  1340 	"VirtualKeyColor",
       
  1341 	"VirtualKey",
       
  1342 	"MouseTarget",
       
  1343 	"FasciaBitmap",
       
  1344 	"DigitizerOffsetX",
       
  1345 	"DigitizerOffsetY",
       
  1346 	"DigitizerWidth",
       
  1347 	"DigitizerHeight",
       
  1348 	"DisableDigitizer",
       
  1349 	"DefineKeyName",
       
  1350 	"WindowTitle",
       
  1351 	"NoVersionInfo",
       
  1352 	"OnActivation",
       
  1353 	"EmulatorControl",
       
  1354 	"EmulatorControlHotKey",
       
  1355 	"CompositionBuffers",
       
  1356 	"RefreshRateHz",
       
  1357 	};
       
  1358 
       
  1359 const char * KScreenSpecificProperties[] =
       
  1360  	{
       
  1361  	"ScreenWidth",
       
  1362  	"ScreenHeight",
       
  1363  	"PhysicalScreenWidth",
       
  1364  	"PhysicalScreenHeight",
       
  1365  	"ScreenOffsetX",
       
  1366  	"ScreenOffsetY",
       
  1367  	"ColorDepth",
       
  1368 	"FasciaBitmap",
       
  1369 	"CompositionBuffers",
       
  1370 	"RefreshRateHz",
       
  1371  	};
       
  1372 
       
  1373 
       
  1374 TBool Wins::ConfigSpecificProperty(const char * aProperty)
       
  1375 	{
       
  1376 	TInt x;
       
  1377 	TInt count = sizeof(KConfigSpecificProperties) / sizeof(char *);
       
  1378 	for (x = 0; x < count; ++x)
       
  1379 		if (_stricmp(aProperty, KConfigSpecificProperties[x]) == 0)	return ETrue;
       
  1380 	return EFalse;
       
  1381 	}
       
  1382 
       
  1383 TBool Wins::ScreenSpecificProperty(const char * aProperty)
       
  1384 	{
       
  1385 	TInt x;
       
  1386 	TInt count = sizeof(KScreenSpecificProperties) / sizeof(char *);
       
  1387 	for (x = 0; x < count; ++x)
       
  1388 		if (_stricmp(aProperty, KScreenSpecificProperties[x]) == 0)	return ETrue;
       
  1389 	return EFalse;
       
  1390 	}