First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // wins\specific\property.cpp
15 // Emulator property management for emulator settings
19 #define _CRTIMP // we want to use the static runtime library
21 #define __INCLUDE_CAPABILITY_NAMES__
28 #define _DUMP_PROPERTY
31 const char* KDefaultMachineName = "epoc";
32 const char* KDefaultTestMachineName = "defaulttest";
34 // name of the environment variable to check for default path
35 const char* KDefaultEpocRootName = "EPOCROOT";
39 // At the point this is created there is no kernel heap available
40 // So all memory allocation is done from a custom allocator
42 const TInt KMaxTokenLength = 255;
46 enum {ETotalMemory=0x10000}; // 64K
49 TAny* Alloc(TInt aSize);
50 TAny* Realloc(TAny* aCell, TInt aSize);
51 void Free(TAny* aCell);
53 TUint iBuf[ETotalMemory];
57 Allocator::Allocator()
61 TAny* Allocator::Alloc(TInt aSize)
63 aSize = (aSize + 7) >> 2;
64 if (iFree + aSize > iBuf + ETotalMemory)
72 TAny* Allocator::Realloc(TAny* aCell, TInt aSize)
77 TUint* p = (TUint*)aCell;
79 if (iFree == p + size)
81 aSize = (aSize + 7) >> 2;
82 if (p + aSize > iBuf + ETotalMemory)
89 TAny* newp = Alloc(aSize);
92 memcpy(newp, aCell, size*sizeof(TUint));
98 void Allocator::Free(TAny* )
102 Allocator TheAllocator;
106 char* Duplicate(const char* aString)
111 TInt size = strlen(aString) + 1;
112 char* p = (char*)TheAllocator.Alloc(size);
114 memcpy(p, aString, size);
118 // Properties class implementation
120 Properties::Properties()
121 :iEntries(NULL),iCount(0),iSize(0)
124 const char* Properties::Insert(TInt aIndex, const char* aProperty, const char* aValue)
128 TInt size = iSize == 0 ? 8 : iSize*2;
129 TAny* array = TheAllocator.Realloc(iEntries, size*sizeof(SEntry));
132 iEntries = (SEntry*)array;
136 char* prop = Duplicate(aProperty);
139 char* value = Duplicate(aValue);
141 TheAllocator.Free(prop);
144 SEntry* e = &iEntries[aIndex];
145 memmove(e+1, e, (iCount-aIndex)*sizeof(SEntry));
153 const char* Properties::Replace(const char* aProperty, const char* aValue)
155 TInt ix = Find(aProperty);
157 return Insert(~ix, aProperty, aValue);
158 // replacing a property
159 SEntry& e = iEntries[ix];
160 char* value = Duplicate(aValue);
163 TheAllocator.Free(e.iValue);
169 const char* Properties::Append(const char* aProperty, const char* aValue)
171 TInt ix = Find(aProperty);
173 return Insert(~ix, aProperty, aValue);
176 SEntry& e = iEntries[ix];
177 TInt size = strlen(e.iValue) + strlen(aValue) + 2;
178 char* value = (char*)TheAllocator.Realloc(e.iValue, size);
182 strcat(value, aValue);
188 TInt Properties::GetString(const char* aProperty, const char*& aValue) const
190 TInt ix = Find(aProperty);
193 aValue = iEntries[ix].iValue;
197 TInt Properties::GetInt(const char* aProperty, TInt& aValue) const
199 TInt ix = Find(aProperty);
202 char* value = iEntries[ix].iValue;
204 TBool neg = *value=='-';
206 long val = strtoul(value, &end, 0);
219 TInt Properties::GetBool(const char* aProperty, TBool& aValue, TBool aDefaultValue) const
221 TInt ix = Find(aProperty);
224 aValue = aDefaultValue;
227 const char* value=iEntries[ix].iValue;
228 if (_stricmp(value, "on")==0 || _stricmp(value, "yes")==0 || _stricmp(value, "1")==0 || strlen(value)==0)
233 if (_stricmp(value, "off")==0 || _stricmp(value, "no")==0 || _stricmp(value, "0")==0 )
239 // Bool property has an illegal value!
243 TInt Properties::Find(const char* aProperty) const
245 // Lookup a property in the table
246 // return index (>=0) if found, ~insertion-point (<0) if not
249 TInt l = 0, r = iCount;
252 TInt m = (l + r) >> 1;
253 const SEntry& e = iEntries[m];
254 TInt k = _stricmp(aProperty,e.iProperty);
265 #ifdef _DUMP_PROPERTY
266 void Properties::Dump() const
268 for (TInt i = 0; i < iCount; ++i)
270 const SEntry& e = iEntries[i];
272 strcpy(buf, e.iProperty);
273 TInt len = strlen(e.iValue);
278 strcat(buf, e.iValue);
281 strncat(buf, e.iValue, 256);
286 OutputDebugStringA(buf);
291 // Property related variant functions
293 TInt Wins::EmulatorHal(TInt aFunction, TAny* a1, TAny* a2)
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:
310 TInt screen = (TInt)a2;
311 if((TUint)screen < (TUint)iUi->NumberOfScreens())
312 return iUi->SetFlip(TEmulatorFlip(TInt(a1)),screen);
316 case EEmulatorHalColorDepth:
318 TUint colorDepth = KDefaultColorDepth;
321 if((TUint)a2 < (TUint)iUi->NumberOfScreens())
322 colorDepth = iUi->ColorDepth((TInt)a2);
324 *(TUint*)a1 = colorDepth;
327 case EEmulatorHalCPUSpeed:
329 return SetCpuSpeed(TUint(a2)/1000);
330 *(TInt*)a2 = iCpuSpeed ? iCpuSpeed * 1000 : 1;
332 case EEmulatorHalNumberOfScreens:
333 *(TInt*)a2 = iUi ? iUi->NumberOfScreens() : 1;
335 case EEmulatorHalSetDisplayChannel:
336 if (iUi && (TUint)a1 < (TUint)iUi->NumberOfScreens())
338 r = iUi->SetDisplayChannel((TInt)a1, static_cast<DDisplayChannel*>(a2));
342 r = KErrNotSupported;
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";
360 const int KMaxEpocRootSize = 120;
362 TInt Wins::InitProperties(TBool aRunExe)
364 if (iProperties.Replace("MachineName", KDefaultMachineName) == NULL)
367 char epocRoot[KMaxEpocRootSize];
369 TInt total = GetEnvironmentVariableA( KDefaultEpocRootName, epocRoot, KMaxEpocRootSize);
373 if (iProperties.Replace("EpocRoot", epocRoot) == NULL)
377 if (iProperties.Append("Extension", KExtensionListNormal) == NULL)
380 char overrideCDrive[MAX_PATH];
381 overrideCDrive[0] = '\0';
382 TInt r = ProcessCommandLine(aRunExe, overrideCDrive);
390 r = LoadProperties();
394 // get Unistore II Media Driver type from epoc.ini
395 const char* value = NULL;
398 iProperties.GetString("NandDriverType", value);
401 if (value && _stricmp("XSR",value)==0)
403 // epoc.ini "NandDriverType=XSR" for XSR/Unistore-II driver
404 if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL)
407 else if (value && _stricmp("XSRNandloader",value)==0)
409 // epoc.ini "NandDriverType=XSRNandloader" for XSR/Unistore-II nandloader driver
410 if (iProperties.Append("Extension", KExtensionUsiiNandLoader) == NULL)
413 else if (value && _stricmp("XSRTest",value)==0)
415 // epoc.ini "NandDriverType=XSRTest" for XSR/Unistore-II test driver
416 if (iProperties.Append("Extension", KExtensionUsiiNandTest) == NULL)
421 // If epoc.ini contains "NandDriverType=???" but ??? not equal to any
422 // of above XSR driver types then load production/release XSR
424 if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL)
431 // Load the production/release XSR driver, if value is NULL
432 if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL)
438 // load additional configuration specific properties
440 // get the multi property "configuration"
442 iProperties.GetString("configuration", value);
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
450 char configFileName[100];
453 //load each set of properties
455 const char * pdest = strchr(value, ';');
456 TInt result = pdest - value;
459 strncpy(configFileName, value, result);
460 configFileName[result] = '\0';
461 value = value + result + 1;
465 strcpy(configFileName, value);
466 value += strlen(value);
469 r = LoadConfigSpecificProperties(configFileName);
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));
483 r = SetupMediaPath();
487 if (overrideCDrive[0] != '\0')
488 SetupDrive('c', overrideCDrive);
490 if (iProperties.Append("Extension", "exstart") == NULL)
493 #ifdef _DUMP_PROPERTY
500 char* skipws(char* aPtr)
502 while (isspace(*aPtr))
507 char* skiptok(char* aPtr)
512 while (*aPtr && *aPtr++ != '\"')
517 while (*aPtr && !isspace(*aPtr))
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[] =
536 {"DEVICE", 1<<KDEVICE},
539 {"EVENT", 1<<KEVENT},
541 {"DEBUGGER", 1<<KDEBUGGER},
542 {"EXTENSION", 1<<KEXTENSION},
544 {"HARDWARE", 1<<KHARDWARE},
546 {"LOCDRV", 1<<KLOCDRV},
547 {"MEMTRACE", 1<<KMEMTRACE},
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},
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},
568 const TInt KMaxTraceName = 9;
569 const TInt KCountTraceValues = sizeof(KTraceValues)/sizeof(TDebugTrace);
571 static const TDebugTrace* TraceType(const char* aTrace, TInt aLen)
573 if (aLen > KMaxTraceName)
576 char name[KMaxTraceName + 1];
577 strncpy(name, aTrace, aLen);
580 for (TInt i=KCountTraceValues; --i>=0;)
582 if (_stricmp(name, KTraceValues[i].iName)==0)
583 return &KTraceValues[i];
589 TInt Wins::DebugMask()
591 TInt mask = KDefaultDebugMask;
592 if (iProperties.GetInt("DebugMask", mask) != KErrArgument)
597 if (iProperties.GetString("DebugMask", e) != KErrNone)
602 char* p = skipws((char*)e);
614 const TDebugTrace* type = TraceType(p, e - p);
620 mask &= ~type->iMask;
627 TUint32 Wins::KernelConfigFlags()
633 iProperties.GetBool("PlatSecEnforcement",b,EFalse);
634 if(b) flags |= EKernelConfigPlatSecEnforcement;
635 Wins::EarlyLogging("PlatSecEnforcement ",b?"ON":"OFF");
638 iProperties.GetBool("PlatSecDiagnostics",b,EFalse);
639 if(b) flags |= EKernelConfigPlatSecDiagnostics;
640 Wins::EarlyLogging("PlatSecDiagnostics ",b?"ON":"OFF");
643 iProperties.GetBool("PlatSecProcessIsolation",b,EFalse);
644 if(b) flags |= EKernelConfigPlatSecProcessIsolation;
645 Wins::EarlyLogging("PlatSecProcessIsolation ",b?"ON":"OFF");
648 iProperties.GetBool("PlatSecEnforceSysBin",b,EFalse);
649 if(b) flags |= EKernelConfigPlatSecEnforceSysBin;
650 Wins::EarlyLogging("PlatSecEnforceSysBin ",b?"ON":"OFF");
653 iProperties.GetBool("CrazyScheduling",b,EFalse);
654 if(b) flags |= EKernelConfigCrazyScheduling;
655 Wins::EarlyLogging("CrazyScheduling ",b?"ON":"OFF");
660 void Wins::DisabledCapabilities(SCapabilitySet& aCapabilities)
663 if(iProperties.GetString("PlatSecDisabledCaps", text)!=KErrNone)
665 Wins::EarlyLogging("PlatSecDisabledCaps ",text);
666 ParseCapabilitiesArg(aCapabilities,text);
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
673 TInt Wins::ParseCapabilitiesArg(SCapabilitySet& aCapabilities, const char *aText)
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
679 memset(&aCapabilities,0,sizeof(aCapabilities));
699 const char* name = aText;
700 while((c=*aText)>' ')
709 if(n==3 && strnicmp("all",name,n)==0)
713 PARSE_CAPABILITIES_ERROR("Capability '-ALL' not allowed");
716 for(i=0; i<ECapability_Limit; i++)
718 if(CapabilityNames[i])
719 aCapabilities[i>>5] |= (1<<(i&31));
724 if(n==4 && strnicmp("none",name,n)==0)
728 PARSE_CAPABILITIES_ERROR("Capability '-NONE' not allowed");
731 memset(&aCapabilities,0,sizeof(aCapabilities));
735 for(i=0; i<ECapability_Limit; i++)
737 const char* cap = CapabilityNames[i];
740 if((int)strlen(cap)!=n)
742 if(strnicmp(cap,name,n)!=0)
746 if(i>=ECapability_Limit)
749 if(n>=sizeof(badName)) n=sizeof(badName)-1;
750 memcpy(badName,name,n);
752 PARSE_CAPABILITIES_ERROR2("Unrecognised capability name: ",badName);
756 aCapabilities[i>>5] &= ~(1<<(i&31));
758 aCapabilities[i>>5] |= (1<<(i&31));
763 TInt Wins::AddProperty(char* aProperty, const char* aEol)
765 const char* tok = aProperty;
769 if (aProperty == aEol)
772 if (_stricmp(tok, "_NewScreen_") == 0)
779 char newtok[KMaxTokenLength];
780 if (ConfigSpecificProperty(tok))
782 wsprintfA(newtok, "Configuration[%d]", iConfigId);
787 return iProperties.Replace(tok, NULL) == NULL ? KErrNoMemory : KErrNone;
790 } while (isalnum(c) || c=='_');
791 aProperty[-1]='\0'; // terminate property name
800 else if (c=='+' && *aProperty=='=')
807 --aProperty; // point back to value
809 if (_strnicmp(tok, "_epoc_drive_", 12) == 0)
810 return SetupDrive(tok[12], aProperty);
813 char newtok[KMaxTokenLength];
814 if (ConfigSpecificProperty(tok))
816 if (ScreenSpecificProperty(tok))
818 wsprintfA(newtok, "Configuration[%d][%d]", iConfigId, ScreenId);
822 wsprintfA(newtok, "Configuration[%d]", iConfigId);
828 return iProperties.Append(tok, aProperty) == NULL ? KErrNoMemory : KErrNone;
830 return iProperties.Replace(tok, aProperty) == NULL ? KErrNoMemory : KErrNone;
834 TInt Wins::ProcessCommandLine(TBool aRunExe, char* aCDrive)
839 DWORD len=GetModuleFileNameA(NULL, exe, MAX_PATH);
843 const char* base = strrchr(exe, '\\') + 1;
844 if (iProperties.Replace("AutoRun", base) == NULL)
848 char* cmd = skipws(skiptok(GetCommandLineA()));
849 if (strstr(cmd, "--") != NULL)
853 cmd = strchr(cmd, '-') + 1;
857 char* end = skiptok(cmd);
859 switch (tolower(opt))
863 TInt r = AddProperty(cmd, end);
869 // specify base name for .INI file
870 if (iProperties.Replace("MachineName", cmd) == NULL)
875 if (iProperties.Replace("TheMachineLanguageIndex", cmd) == NULL)
879 // specify path for emulated C drive
881 DWORD len=GetFullPathNameA(cmd, MAX_PATH, aCDrive, NULL);
882 if (len==0 || len >= MAX_PATH)
887 // specify the temp path as the emulated C drive
889 DWORD len=GetTempPathA(MAX_PATH, aCDrive);
890 if (len==0 || len >= MAX_PATH)
900 if (aRunExe && iProperties.Replace("CommandLine", cmd) == NULL)
906 TInt Wins::LoadConfigSpecificProperties(const char * aFile)
909 TInt r = iProperties.GetString("EmulatorDataPath", path);
913 char file[KMaxFileName + 1];
918 r = ReadIniFile(file, iniData);
921 r = ReadProperties(iniData);
922 VirtualFree(iniData, 0, MEM_RELEASE);
924 else if (r == KErrNotFound)
933 TInt Wins::LoadProperties()
936 TInt r = iProperties.GetString("EmulatorDataPath", path);
940 r = iProperties.GetString("MachineName", name);
944 char file[KMaxFileName + 1];
947 strcat(file, ".ini");
950 r = ReadIniFile(file, iniData);
953 r = ReadProperties(iniData);
954 VirtualFree(iniData, 0, MEM_RELEASE);
956 else if (r == KErrNotFound)
958 if(_stricmp(name,KDefaultMachineName)==0)
961 name = KDefaultTestMachineName;
964 r = KErrNone; // no ini file - oh well
970 TInt Wins::ReadProperties(char* aData)
976 char* eol = strchr(beg, '\n');
980 if (eol[-1] == '\r' && --eol == beg)
982 *eol = '\0'; // terminate line
984 while (isspace(*beg))
986 char* comment = strchr(beg, '#');
989 while (eol > beg && isspace(eol[-1]))
993 *eol = '\0'; // terminate line
995 TInt r = AddProperty(beg, eol);
1000 wsprintfA(sc, "%d", ScreenId+1);
1002 if(iProperties.GetInt("[screens]", screens) == KErrNone && screens > ScreenId)
1005 return iProperties.Replace("[screens]", sc) == NULL ? KErrNoMemory : KErrNone;
1008 TInt Wins::ReadIniFile(const char* aFileName, char*& aContents)
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 !
1016 TInt size=GetFileSize(file, NULL);
1017 if (size==INVALID_FILE_SIZE)
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);
1029 if (!ReadFile(file, data, size, &bytesRead, NULL))
1031 VirtualFree(data, 0, MEM_RELEASE);
1036 aContents = (LPSTR)data;
1037 strcpy(aContents + size,"\r\n");
1047 TInt Wins::SetupPaths()
1049 // set up the Emulator paths
1052 // the Emulator path
1053 CHAR path[KMaxFileName + 1];
1054 DWORD len=GetModuleFileNameA(NULL, path, KMaxFileName);
1056 return(KErrGeneral);
1059 *(strrchr(path, '\\') + 1) = '\0';
1060 const char* emulatorPath = iProperties.Replace("EmulatorPath", path);
1062 return KErrNoMemory;
1064 CHAR drive[KMaxFileName + 1];
1066 // the Emulator data path
1067 strcat(path, "data\\");
1068 DWORD att = GetFileAttributesA(path);
1069 if (att != -1 && (att&FILE_ATTRIBUTE_DIRECTORY))
1071 // if Data directory exists in the emulator path, do things the new way
1072 strcpy(drive, emulatorPath);
1073 strcat(drive,"c\\");
1078 #if defined(__VC32__)
1079 char* p = strstr(path, "\\epoc32\\release\\wins\\");
1080 #elif defined(__CW32__)
1081 char* p = strstr(path, "\\epoc32\\release\\winscw\\");
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\\");
1094 if (!iProperties.Replace("EmulatorDataPath", path))
1095 return KErrNoMemory;
1097 // The Emulator Image path (for temporary EXE files)
1099 TInt r = iProperties.GetString("EmulatorImagePath", eip);
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;
1112 if (!Emulator::CreateAllDirectories(path))
1113 return Emulator::LastError();
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
1120 strcpy(drive, emulatorPath);
1121 strcat(drive,"z\\");
1123 r=SetupDrive('z',drive); // set up Z here, can be overridden by system.ini settings
1130 TInt Wins::SetupMediaPath()
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%'
1137 CHAR path[KMaxFileName + 1];
1139 if (iProperties.GetString("EmulatorMediaPath", mpath) == KErrNotFound)
1142 TInt r = iProperties.GetString("EmulatorDataPath", dpath);
1145 strcpy(path, dpath);
1146 strcat(path, "media\\");
1147 return iProperties.Replace("EmulatorMediaPath", path) ? KErrNone : KErrNoMemory;
1150 if (_stricmp(mpath, "%temp%") == 0)
1152 DWORD len=GetTempPathA(KMaxFileName, path);
1153 if (len > 0 && len < KMaxFileName)
1154 return iProperties.Replace("EmulatorMediaPath", path) ? KErrNone : KErrNoMemory;
1160 const char* Wins::EmulatorMediaPath()
1162 const char* mpath = NULL;
1163 iProperties.GetString("EmulatorMediaPath", mpath);
1167 TInt Wins::SetupDrive(int aDrive, const char* aPath)
1169 // set up emulated drives
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);
1179 const char* end = aPath + strlen(aPath);
1180 if (_stricmp(end-2,"\\z") != 0 && _stricmp(end-3,"\\z\\") != 0)
1181 return KErrArgument;
1184 char prop[] = "_epoc_drive_?";
1185 *strchr(prop, '?') = char(aDrive);
1188 // If the path begins with the keyword %epocroot%, replace this with EPOCROOT
1189 if (_strnicmp(aPath, "%epocroot%", 10) == 0)
1191 aPath += 10; // skip "%epocroot%"
1194 TInt r = iProperties.GetString("EpocRoot", eRoot);
1198 int rootSize = strlen(eRoot);
1199 int pathSize = strlen(aPath);
1200 if(rootSize+pathSize>MAX_PATH)
1201 return KErrArgument;
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
1207 return iProperties.Replace(prop, fullPath) ? KErrNone : KErrNoMemory;
1211 // otherwise, aPath is fully qualified path name. Use that.
1212 return iProperties.Replace(prop, aPath) ? KErrNone : KErrNoMemory;
1216 TInt Wins::MapDrive(int aDrive, TDes& aBuffer) const
1218 // Map aDrive to a path given by environment variables or defaults
1219 // Use this function only in WINS builds
1222 char drive[KMaxFileName + 1];
1223 char prop[] = "_epoc_drive_?";
1224 *strchr(prop, '?') = char(tolower(aDrive));
1228 if (iProperties.GetString(prop, val) == KErrNone)
1231 if (len > KMaxFileName)
1232 return KErrArgument;
1237 // not in properties, so check environment
1238 len = GetEnvironmentVariableA(prop, drive, KMaxFileName + 1);
1239 if (len > KMaxFileName)
1240 return KErrArgument;
1242 while (len > 0 && isspace(drive[len-1]))
1245 return KErrNotFound;
1246 if (drive[len-1] != '\\') // add trailing backslash
1247 drive[len++] = '\\';
1248 if (drive[0] == '\\')
1250 // put in the emulator drive
1251 TInt r = iProperties.GetString("EmulatorPath", val);
1255 memmove(drive + 2, drive, len);
1260 else if (len < 3 || drive[1] != ':' || drive[2] != '\\')
1261 return KErrArgument;
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);
1269 aBuffer.Copy(TPtrC8((const TText8*)drive,len));
1274 TInt Wins::MapFilename(const TDesC& aFilename, TDes& aBuffer) const
1276 // Map aFileName to real windows directory - aFileName must be a full filepath
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
1284 if (aFilename.Length() < 4 || aFilename[2] != ':')
1286 TInt r = MapDrive('z', aBuffer);
1289 aBuffer.SetLength(aBuffer.Length()-4); // chop "Z\\"
1290 offset = aFilename[0] == '\\' ? 1 : 0; // remove the guaranteed backslash
1294 TInt r = MapDrive(aFilename[0], aBuffer);
1297 if (aFilename.Length() >= 6 && aFilename[4] == '\\')
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)
1309 memcpy(ptrBuffer, ptrFilename, aFilename.Length()-offset);
1310 aBuffer.SetLength(aBuffer.Length()+aFilename.Length()-offset);
1312 TPtrC name(aFilename.Mid(offset));
1313 if (aBuffer.MaxLength()<aBuffer.Length()+name.Length()+1)
1315 aBuffer.Append(name);
1321 //table of the property names which can be used in multiple configurations
1322 const char * KConfigSpecificProperties[] =
1326 "PhysicalScreenWidth",
1327 "PhysicalScreenHeight",
1331 "LedArrangeVertically",
1332 "LedArrangeHorizontally",
1354 "EmulatorControlHotKey",
1355 "CompositionBuffers",
1359 const char * KScreenSpecificProperties[] =
1363 "PhysicalScreenWidth",
1364 "PhysicalScreenHeight",
1369 "CompositionBuffers",
1374 TBool Wins::ConfigSpecificProperty(const char * aProperty)
1377 TInt count = sizeof(KConfigSpecificProperties) / sizeof(char *);
1378 for (x = 0; x < count; ++x)
1379 if (_stricmp(aProperty, KConfigSpecificProperties[x]) == 0) return ETrue;
1383 TBool Wins::ScreenSpecificProperty(const char * aProperty)
1386 TInt count = sizeof(KScreenSpecificProperties) / sizeof(char *);
1387 for (x = 0; x < count; ++x)
1388 if (_stricmp(aProperty, KScreenSpecificProperties[x]) == 0) return ETrue;