diff -r 000000000000 -r cec860690d41 emulator/emulatorbsp/specific/property.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emulator/emulatorbsp/specific/property.cpp Tue Feb 02 01:39:10 2010 +0200 @@ -0,0 +1,1390 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// wins\specific\property.cpp +// Emulator property management for emulator settings +// +// + +#define _CRTIMP // we want to use the static runtime library + +#define __INCLUDE_CAPABILITY_NAMES__ +#include "variant.h" +#include +#include +#include + +#ifdef _DEBUG +#define _DUMP_PROPERTY +#endif + +const char* KDefaultMachineName = "epoc"; +const char* KDefaultTestMachineName = "defaulttest"; + +// name of the environment variable to check for default path +const char* KDefaultEpocRootName = "EPOCROOT"; + +TInt ScreenId=0; + +// At the point this is created there is no kernel heap available +// So all memory allocation is done from a custom allocator + +const TInt KMaxTokenLength = 255; + +class Allocator + { + enum {ETotalMemory=0x10000}; // 64K +public: + Allocator(); + TAny* Alloc(TInt aSize); + TAny* Realloc(TAny* aCell, TInt aSize); + void Free(TAny* aCell); +private: + TUint iBuf[ETotalMemory]; + TUint* iFree; + }; + +Allocator::Allocator() + :iFree(iBuf) + {} + +TAny* Allocator::Alloc(TInt aSize) + { + aSize = (aSize + 7) >> 2; + if (iFree + aSize > iBuf + ETotalMemory) + return NULL; + TUint* p = iFree; + iFree += aSize; + *p++ = aSize; + return p; + } + +TAny* Allocator::Realloc(TAny* aCell, TInt aSize) + { + if (!aCell) + return Alloc(aSize); + + TUint* p = (TUint*)aCell; + TInt size = *--p; + if (iFree == p + size) + { + aSize = (aSize + 7) >> 2; + if (p + aSize > iBuf + ETotalMemory) + return NULL; + iFree = p + aSize; + *p = aSize; + return aCell; + } + + TAny* newp = Alloc(aSize); + if (newp) + { + memcpy(newp, aCell, size*sizeof(TUint)); + Free(aCell); + } + return newp; + } + +void Allocator::Free(TAny* ) + { + } + +Allocator TheAllocator; + +/////// + +char* Duplicate(const char* aString) + { + if (aString == NULL) + aString = ""; + + TInt size = strlen(aString) + 1; + char* p = (char*)TheAllocator.Alloc(size); + if (p) + memcpy(p, aString, size); + return p; + } + +// Properties class implementation + +Properties::Properties() + :iEntries(NULL),iCount(0),iSize(0) + {} + +const char* Properties::Insert(TInt aIndex, const char* aProperty, const char* aValue) + { + if (iCount == iSize) + { + TInt size = iSize == 0 ? 8 : iSize*2; + TAny* array = TheAllocator.Realloc(iEntries, size*sizeof(SEntry)); + if (array == NULL) + return NULL; + iEntries = (SEntry*)array; + iSize = size; + } + + char* prop = Duplicate(aProperty); + if (prop == NULL) + return NULL; + char* value = Duplicate(aValue); + if (value == NULL) + TheAllocator.Free(prop); + else + { + SEntry* e = &iEntries[aIndex]; + memmove(e+1, e, (iCount-aIndex)*sizeof(SEntry)); + e->iProperty = prop; + e->iValue = value; + ++iCount; + } + return value; + } + +const char* Properties::Replace(const char* aProperty, const char* aValue) + { + TInt ix = Find(aProperty); + if (ix < 0) + return Insert(~ix, aProperty, aValue); + // replacing a property + SEntry& e = iEntries[ix]; + char* value = Duplicate(aValue); + if (value != NULL) + { + TheAllocator.Free(e.iValue); + e.iValue = value; + } + return value; + } + +const char* Properties::Append(const char* aProperty, const char* aValue) + { + TInt ix = Find(aProperty); + if (ix < 0) + return Insert(~ix, aProperty, aValue); + + // append a property + SEntry& e = iEntries[ix]; + TInt size = strlen(e.iValue) + strlen(aValue) + 2; + char* value = (char*)TheAllocator.Realloc(e.iValue, size); + if (value != NULL) + { + strcat(value, ";"); + strcat(value, aValue); + e.iValue = value; + } + return value; + } + +TInt Properties::GetString(const char* aProperty, const char*& aValue) const + { + TInt ix = Find(aProperty); + if (ix < 0) + return KErrNotFound; + aValue = iEntries[ix].iValue; + return KErrNone; + } + +TInt Properties::GetInt(const char* aProperty, TInt& aValue) const + { + TInt ix = Find(aProperty); + if (ix < 0) + return KErrNotFound; + char* value = iEntries[ix].iValue; + char* end; + TBool neg = *value=='-'; + value += neg; + long val = strtoul(value, &end, 0); + if(neg) + { + if(val<0) + return KErrArgument; + val = -val; + } + if (*end != '\0') + return KErrArgument; + aValue = val; + return KErrNone; + } + +TInt Properties::GetBool(const char* aProperty, TBool& aValue, TBool aDefaultValue) const + { + TInt ix = Find(aProperty); + if (ix < 0) + { + aValue = aDefaultValue; + return KErrNone; + } + const char* value=iEntries[ix].iValue; + if (_stricmp(value, "on")==0 || _stricmp(value, "yes")==0 || _stricmp(value, "1")==0 || strlen(value)==0) + { + aValue = ETrue; + return KErrNone; + } + if (_stricmp(value, "off")==0 || _stricmp(value, "no")==0 || _stricmp(value, "0")==0 ) + { + aValue = EFalse; + return KErrNone; + } + + // Bool property has an illegal value! + return KErrArgument; + } + +TInt Properties::Find(const char* aProperty) const +// +// Lookup a property in the table +// return index (>=0) if found, ~insertion-point (<0) if not +// + { + TInt l = 0, r = iCount; + while (l < r) + { + TInt m = (l + r) >> 1; + const SEntry& e = iEntries[m]; + TInt k = _stricmp(aProperty,e.iProperty); + if (k < 0) + r = m; + else if (k > 0) + l = m + 1; + else + return m; + } + return ~l; + } + +#ifdef _DUMP_PROPERTY +void Properties::Dump() const + { + for (TInt i = 0; i < iCount; ++i) + { + const SEntry& e = iEntries[i]; + char buf[512]; + strcpy(buf, e.iProperty); + TInt len = strlen(e.iValue); + if (len) + { + strcat(buf, " = "); + if (len <= 256) + strcat(buf, e.iValue); + else + { + strncat(buf, e.iValue, 256); + strcat(buf, "..."); + } + } + strcat(buf, "\r\n"); + OutputDebugStringA(buf); + } + } +#endif + +// Property related variant functions + +TInt Wins::EmulatorHal(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EEmulatorHalStringProperty: + return iProperties.GetString((const char*)a1,*(const char**)a2); + case EEmulatorHalIntProperty: + return iProperties.GetInt((const char*)a1,*(TInt*)a2); + case EEmulatorHalBoolProperty: + return iProperties.GetBool((const char*)a1,*(TBool*)a2); + case EEmulatorHalMapFilename: + return MapFilename(*(const TDesC*)a1,*(TDes*)a2); + case EEmulatorHalSetFlip: + { + if (iUi) + { + TInt screen = (TInt)a2; + if((TUint)screen < (TUint)iUi->NumberOfScreens()) + return iUi->SetFlip(TEmulatorFlip(TInt(a1)),screen); + } + break; + } + case EEmulatorHalColorDepth: + { + TUint colorDepth = KDefaultColorDepth; + if(iUi) + { + if((TUint)a2 < (TUint)iUi->NumberOfScreens()) + colorDepth = iUi->ColorDepth((TInt)a2); + } + *(TUint*)a1 = colorDepth; + return KErrNone; + } + case EEmulatorHalCPUSpeed: + if (a1) + return SetCpuSpeed(TUint(a2)/1000); + *(TInt*)a2 = iCpuSpeed ? iCpuSpeed * 1000 : 1; + return KErrNone; + case EEmulatorHalNumberOfScreens: + *(TInt*)a2 = iUi ? iUi->NumberOfScreens() : 1; + return KErrNone; + case EEmulatorHalSetDisplayChannel: + if (iUi && (TUint)a1 < (TUint)iUi->NumberOfScreens()) + { + r = iUi->SetDisplayChannel((TInt)a1, static_cast(a2)); + } + else + { + r = KErrNotSupported; + } + break; + default: + r=KErrNotSupported; + break; + } + return r; + } + +const char* KExtensionListNormal = "btracex.ldd;hcr.dll;winsgui;elocd.ldd;medint.pdd;medlfs.pdd;medmmc.pdd;epbusmmc.dll;epbusv.dll"; +const char* KExtensionUsiiNand = "?medusiiw.pdd"; +const char* KExtensionUsiiNandLoader = "?medusiiws.pdd"; +const char* KExtensionUsiiNandTest = "?medusiiwt.pdd"; + + + + +const int KMaxEpocRootSize = 120; + +TInt Wins::InitProperties(TBool aRunExe) + { + if (iProperties.Replace("MachineName", KDefaultMachineName) == NULL) + return KErrNoMemory; + + char epocRoot[KMaxEpocRootSize]; + + TInt total = GetEnvironmentVariableA( KDefaultEpocRootName, epocRoot, KMaxEpocRootSize); + + if (total != 0) + { + if (iProperties.Replace("EpocRoot", epocRoot) == NULL) + return KErrNoMemory; + } + + if (iProperties.Append("Extension", KExtensionListNormal) == NULL) + return KErrNoMemory; + + char overrideCDrive[MAX_PATH]; + overrideCDrive[0] = '\0'; + TInt r = ProcessCommandLine(aRunExe, overrideCDrive); + if (r != KErrNone) + return r; + + r = SetupPaths(); + if (r != KErrNone) + return r; + + r = LoadProperties(); + if (r != KErrNone) + return r; + + // get Unistore II Media Driver type from epoc.ini + const char* value = NULL; + + + iProperties.GetString("NandDriverType", value); + if (value) + { + if (value && _stricmp("XSR",value)==0) + { + // epoc.ini "NandDriverType=XSR" for XSR/Unistore-II driver + if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL) + return KErrNoMemory; + } + else if (value && _stricmp("XSRNandloader",value)==0) + { + // epoc.ini "NandDriverType=XSRNandloader" for XSR/Unistore-II nandloader driver + if (iProperties.Append("Extension", KExtensionUsiiNandLoader) == NULL) + return KErrNoMemory; + } + else if (value && _stricmp("XSRTest",value)==0) + { + // epoc.ini "NandDriverType=XSRTest" for XSR/Unistore-II test driver + if (iProperties.Append("Extension", KExtensionUsiiNandTest) == NULL) + return KErrNoMemory; + } + else + { + // If epoc.ini contains "NandDriverType=???" but ??? not equal to any + // of above XSR driver types then load production/release XSR + // driver + if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL) + return KErrNoMemory; + + } + } + else + { + // Load the production/release XSR driver, if value is NULL + if (iProperties.Append("Extension", KExtensionUsiiNand) == NULL) + return KErrNoMemory; + + } + + +// load additional configuration specific properties + +// get the multi property "configuration" + value = NULL; + iProperties.GetString("configuration", value); + +// load each one of these +// check for any screen specific properties in the main epoc.ini +// if configuration property is set + if (value && !iConfigPropertySet) //configuration + { + iConfigId = 0; + char configFileName[100]; + do + { + //load each set of properties + + const char * pdest = strchr(value, ';'); + TInt result = pdest - value; + if(pdest) + { + strncpy(configFileName, value, result); + configFileName[result] = '\0'; + value = value + result + 1; + } + else + { + strcpy(configFileName, value); + value += strlen(value); + } + + r = LoadConfigSpecificProperties(configFileName); + if (r == KErrNone) + iConfigId++; + } + while(*value); + } + + char scr[30]; + //if iConfigId is zero, there is only 1 configuration + wsprintfA(scr, "ConfigCount %d", iConfigId ? iConfigId : 1); + r = AddProperty(scr, scr+strlen(scr)); + if (r != KErrNone) + return r; + + r = SetupMediaPath(); + if (r != KErrNone) + return r; + + if (overrideCDrive[0] != '\0') + SetupDrive('c', overrideCDrive); + + if (iProperties.Append("Extension", "exstart") == NULL) + return KErrNoMemory; + +#ifdef _DUMP_PROPERTY + iProperties.Dump(); +#endif + + return KErrNone; + } + +char* skipws(char* aPtr) + { + while (isspace(*aPtr)) + ++aPtr; + return aPtr; + } + +char* skiptok(char* aPtr) + { + if (*aPtr == '\"') + { + ++aPtr; + while (*aPtr && *aPtr++ != '\"') + {} + } + else + { + while (*aPtr && !isspace(*aPtr)) + ++aPtr; + } + return aPtr; + } + +#ifdef _DEBUG +struct TDebugTrace + { + const char* iName; + TInt iMask; + }; + +// Only the first 32 trace bits can be defined using these values +// "ALWAYS" in this context means all of the first 32 bits not all 256 bits +const TDebugTrace KTraceValues[] = + { + {"ALWAYS", KALWAYS}, + {"BOOT", 1< KMaxTraceName) + return 0; + + char name[KMaxTraceName + 1]; + strncpy(name, aTrace, aLen); + name[aLen] = '\0'; + + for (TInt i=KCountTraceValues; --i>=0;) + { + if (_stricmp(name, KTraceValues[i].iName)==0) + return &KTraceValues[i]; + } + return 0; + } +#endif + +TInt Wins::DebugMask() + { + TInt mask = KDefaultDebugMask; + if (iProperties.GetInt("DebugMask", mask) != KErrArgument) + return mask; +#ifdef _DEBUG + // allow text ones + const char* e; + if (iProperties.GetString("DebugMask", e) != KErrNone) + return mask; + + for (;;) + { + char* p = skipws((char*)e); + if (*p == 0) + break; + e = skiptok(p); + TBool add = ETrue; + if (*p == '+') + ++p; + else if (*p == '-') + { + add = EFalse; + ++p; + } + const TDebugTrace* type = TraceType(p, e - p); + if (type) + { + if (add) + mask |= type->iMask; + else + mask &= ~type->iMask; + } + } +#endif + return mask; + } + +TUint32 Wins::KernelConfigFlags() + { + TUint32 flags = 0; + TBool b; + + b=0; + iProperties.GetBool("PlatSecEnforcement",b,EFalse); + if(b) flags |= EKernelConfigPlatSecEnforcement; + Wins::EarlyLogging("PlatSecEnforcement ",b?"ON":"OFF"); + + b=0; + iProperties.GetBool("PlatSecDiagnostics",b,EFalse); + if(b) flags |= EKernelConfigPlatSecDiagnostics; + Wins::EarlyLogging("PlatSecDiagnostics ",b?"ON":"OFF"); + + b=0; + iProperties.GetBool("PlatSecProcessIsolation",b,EFalse); + if(b) flags |= EKernelConfigPlatSecProcessIsolation; + Wins::EarlyLogging("PlatSecProcessIsolation ",b?"ON":"OFF"); + + b=0; + iProperties.GetBool("PlatSecEnforceSysBin",b,EFalse); + if(b) flags |= EKernelConfigPlatSecEnforceSysBin; + Wins::EarlyLogging("PlatSecEnforceSysBin ",b?"ON":"OFF"); + + b=0; + iProperties.GetBool("CrazyScheduling",b,EFalse); + if(b) flags |= EKernelConfigCrazyScheduling; + Wins::EarlyLogging("CrazyScheduling ",b?"ON":"OFF"); + + return flags; + } + +void Wins::DisabledCapabilities(SCapabilitySet& aCapabilities) + { + const char* text; + if(iProperties.GetString("PlatSecDisabledCaps", text)!=KErrNone) + text = "NONE"; + Wins::EarlyLogging("PlatSecDisabledCaps ",text); + ParseCapabilitiesArg(aCapabilities,text); + } + +#define PARSE_CAPABILITIES_ERROR(aMessage) Wins::EarlyLogging(aMessage,0) +#define PARSE_CAPABILITIES_ERROR2(aMessage,aArg) Wins::EarlyLogging(aMessage,aArg) +#define strnicmp _strnicmp + +TInt Wins::ParseCapabilitiesArg(SCapabilitySet& aCapabilities, const char *aText) +// +// This is a cun'n'paste copy of the function in TOOLS\E32TOOLS\HOST\H_UTIL.CPP +// Keep both of these versions up to date with each other +// + { + memset(&aCapabilities,0,sizeof(aCapabilities)); + char c; + while((c=*aText)!=0) + { + if(c<=' ') + { + ++aText; + continue; + } + int invert=0; + if(c=='+') + { + ++aText; + c=*aText; + } + if(c=='-') + { + invert=1; + ++aText; + } + const char* name = aText; + while((c=*aText)>' ') + { + if(c=='-' || c=='+') + break; + ++aText; + } + TInt n = aText-name; + TInt i; + + if(n==3 && strnicmp("all",name,n)==0) + { + if(invert) + { + PARSE_CAPABILITIES_ERROR("Capability '-ALL' not allowed"); + return KErrArgument; + } + for(i=0; i>5] |= (1<<(i&31)); + } + continue; + } + + if(n==4 && strnicmp("none",name,n)==0) + { + if(invert) + { + PARSE_CAPABILITIES_ERROR("Capability '-NONE' not allowed"); + return KErrArgument; + } + memset(&aCapabilities,0,sizeof(aCapabilities)); + continue; + } + + for(i=0; i=ECapability_Limit) + { + char badName[32]; + if(n>=sizeof(badName)) n=sizeof(badName)-1; + memcpy(badName,name,n); + badName[n]=0; + PARSE_CAPABILITIES_ERROR2("Unrecognised capability name: ",badName); + return KErrArgument; + } + if(invert) + aCapabilities[i>>5] &= ~(1<<(i&31)); + else + aCapabilities[i>>5] |= (1<<(i&31)); + } + return KErrNone; + } + +TInt Wins::AddProperty(char* aProperty, const char* aEol) + { + const char* tok = aProperty; + int c; + do + { + if (aProperty == aEol) + { + // boolean property + if (_stricmp(tok, "_NewScreen_") == 0) + { + ++ScreenId; + return KErrNone; + } + else + { + char newtok[KMaxTokenLength]; + if (ConfigSpecificProperty(tok)) + { + wsprintfA(newtok, "Configuration[%d]", iConfigId); + strcat(newtok, tok); + tok = newtok; + } + } + return iProperties.Replace(tok, NULL) == NULL ? KErrNoMemory : KErrNone; + } + c=*aProperty++; + } while (isalnum(c) || c=='_'); + aProperty[-1]='\0'; // terminate property name + while (isspace(c)) + c=*aProperty++; + TBool append=ETrue; + if (c=='=') + { + append=EFalse; + c=*aProperty++; + } + else if (c=='+' && *aProperty=='=') + { + ++aProperty; + c=*aProperty++; + } + while (isspace(c)) + c=*aProperty++; + --aProperty; // point back to value + + if (_strnicmp(tok, "_epoc_drive_", 12) == 0) + return SetupDrive(tok[12], aProperty); + else + { + char newtok[KMaxTokenLength]; + if (ConfigSpecificProperty(tok)) + { + if (ScreenSpecificProperty(tok)) + { + wsprintfA(newtok, "Configuration[%d][%d]", iConfigId, ScreenId); + } + else + { + wsprintfA(newtok, "Configuration[%d]", iConfigId); + } + strcat(newtok, tok); + tok = newtok; + } + if (append) + return iProperties.Append(tok, aProperty) == NULL ? KErrNoMemory : KErrNone; + else + return iProperties.Replace(tok, aProperty) == NULL ? KErrNoMemory : KErrNone; + } + } + +TInt Wins::ProcessCommandLine(TBool aRunExe, char* aCDrive) + { + if (aRunExe) + { + char exe[MAX_PATH]; + DWORD len=GetModuleFileNameA(NULL, exe, MAX_PATH); + if (len == 0) + return KErrGeneral; + exe[len] = '\0'; + const char* base = strrchr(exe, '\\') + 1; + if (iProperties.Replace("AutoRun", base) == NULL) + return KErrNoMemory; + } + + char* cmd = skipws(skiptok(GetCommandLineA())); + if (strstr(cmd, "--") != NULL) + { + for (;;) + { + cmd = strchr(cmd, '-') + 1; + TInt opt = *cmd++; + if (opt == '-') + break; + char* end = skiptok(cmd); + *end = '\0'; + switch (tolower(opt)) + { + case 'd': + { + TInt r = AddProperty(cmd, end); + if (r != KErrNone) + return r; + } + break; + case 'm': + // specify base name for .INI file + if (iProperties.Replace("MachineName", cmd) == NULL) + return KErrNoMemory; + break; + case 'l': + // specify language + if (iProperties.Replace("TheMachineLanguageIndex", cmd) == NULL) + return KErrNoMemory; + break; + case 'c': + // specify path for emulated C drive + { + DWORD len=GetFullPathNameA(cmd, MAX_PATH, aCDrive, NULL); + if (len==0 || len >= MAX_PATH) + aCDrive[0] = '\0'; + } + break; + case 't': + // specify the temp path as the emulated C drive + { + DWORD len=GetTempPathA(MAX_PATH, aCDrive); + if (len==0 || len >= MAX_PATH) + aCDrive[0] = '\0'; + } + break; + } + cmd = end+1; + } + cmd = skipws(cmd); + } + + if (aRunExe && iProperties.Replace("CommandLine", cmd) == NULL) + return KErrNoMemory; + + return KErrNone; + } + +TInt Wins::LoadConfigSpecificProperties(const char * aFile) + { + const char* path; + TInt r = iProperties.GetString("EmulatorDataPath", path); + if (r != KErrNone) + return r; + + char file[KMaxFileName + 1]; + strcpy(file, path); + strcat(file, aFile); + + char* iniData; + r = ReadIniFile(file, iniData); + if (r == KErrNone) + { + r = ReadProperties(iniData); + VirtualFree(iniData, 0, MEM_RELEASE); + } + else if (r == KErrNotFound) + r = KErrNotFound; + + return r; + + } + + + +TInt Wins::LoadProperties() + { + const char* path; + TInt r = iProperties.GetString("EmulatorDataPath", path); + if (r != KErrNone) + return r; + const char* name; + r = iProperties.GetString("MachineName", name); + if (r != KErrNone) + return r; +retry: + char file[KMaxFileName + 1]; + strcpy(file, path); + strcat(file, name); + strcat(file, ".ini"); + + char* iniData; + r = ReadIniFile(file, iniData); + if (r == KErrNone) + { + r = ReadProperties(iniData); + VirtualFree(iniData, 0, MEM_RELEASE); + } + else if (r == KErrNotFound) + { + if(_stricmp(name,KDefaultMachineName)==0) + { + // try test ini file + name = KDefaultTestMachineName; + goto retry; + } + r = KErrNone; // no ini file - oh well + } + + return r; + } + +TInt Wins::ReadProperties(char* aData) + { + ScreenId = 0; + while (*aData) + { + char* beg = aData; + char* eol = strchr(beg, '\n'); + aData = eol+1; + if (eol == beg) + continue; + if (eol[-1] == '\r' && --eol == beg) + continue; + *eol = '\0'; // terminate line + + while (isspace(*beg)) + ++beg; + char* comment = strchr(beg, '#'); + if (comment) + eol = comment; + while (eol > beg && isspace(eol[-1])) + --eol; + if (beg == eol) + continue; + *eol = '\0'; // terminate line + + TInt r = AddProperty(beg, eol); + if (r != KErrNone) + return r; + } + char sc[5]; + wsprintfA(sc, "%d", ScreenId+1); + TInt screens; + if(iProperties.GetInt("[screens]", screens) == KErrNone && screens > ScreenId) + return KErrNone; + else + return iProperties.Replace("[screens]", sc) == NULL ? KErrNoMemory : KErrNone; + } + +TInt Wins::ReadIniFile(const char* aFileName, char*& aContents) + { + TInt r = KErrNone; + HANDLE file=CreateFileA(aFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (!file || file==INVALID_HANDLE_VALUE) + r = KErrNotFound; // More than likely ! + else + { + TInt size=GetFileSize(file, NULL); + if (size==INVALID_FILE_SIZE) + r = KErrGeneral; + else + { + // fileSize+3 to ensure zero-termination of file and trailing CRLF + // VirtualAlloc initializes memory to zero + TAny* data = VirtualAlloc(NULL, size+3, MEM_COMMIT, PAGE_READWRITE); + if (!data) + r = KErrNoMemory; + else + { + DWORD bytesRead; + if (!ReadFile(file, data, size, &bytesRead, NULL)) + { + VirtualFree(data, 0, MEM_RELEASE); + r = KErrGeneral; + } + else + { + aContents = (LPSTR)data; + strcpy(aContents + size,"\r\n"); + } + } + } + CloseHandle(file); + } + return r; + } + + +TInt Wins::SetupPaths() +// +// set up the Emulator paths +// + { + // the Emulator path + CHAR path[KMaxFileName + 1]; + DWORD len=GetModuleFileNameA(NULL, path, KMaxFileName); + if (len == 0) + return(KErrGeneral); + path[len] = '\0'; + _strlwr(path); + *(strrchr(path, '\\') + 1) = '\0'; + const char* emulatorPath = iProperties.Replace("EmulatorPath", path); + if (!emulatorPath) + return KErrNoMemory; + + CHAR drive[KMaxFileName + 1]; + + // the Emulator data path + strcat(path, "data\\"); + DWORD att = GetFileAttributesA(path); + if (att != -1 && (att&FILE_ATTRIBUTE_DIRECTORY)) + { + // if Data directory exists in the emulator path, do things the new way + strcpy(drive, emulatorPath); + strcat(drive,"c\\"); + } + else + { + // the old way +#if defined(__VC32__) + char* p = strstr(path, "\\epoc32\\release\\wins\\"); +#elif defined(__CW32__) + char* p = strstr(path, "\\epoc32\\release\\winscw\\"); +#endif + if (p == NULL) + return KErrNotFound; + strcpy(p, "\\epoc32\\"); + strcpy(drive, path); + strcat(path, "data\\"); +#if defined(__VC32__) + strcat(drive,"wins\\c\\"); +#elif defined(__CW32__) + strcat(drive,"winscw\\c\\"); +#endif + } + if (!iProperties.Replace("EmulatorDataPath", path)) + return KErrNoMemory; + + // The Emulator Image path (for temporary EXE files) + const char* eip; + TInt r = iProperties.GetString("EmulatorImagePath", eip); + if (r!=KErrNone) + { + len=GetTempPathA(KMaxFileName, path); + strcat(path, "epoc\\"); + char* p = path + strlen(path); + *p++ = emulatorPath[0]; + strcpy(p, emulatorPath+2); + if (!iProperties.Replace("EmulatorImagePath", path)) + return KErrNoMemory; + } + else + strcpy(path, eip); + if (!Emulator::CreateAllDirectories(path)) + return Emulator::LastError(); + + // Win32 filesystem paths mapped to local WINS drives + r = SetupDrive('c',drive); // set up C here, can be overridden by system.ini settings + if (r) + return(r); + + strcpy(drive, emulatorPath); + strcat(drive,"z\\"); + + r=SetupDrive('z',drive); // set up Z here, can be overridden by system.ini settings + if (r) + return(r); + + return(KErrNone); + } + +TInt Wins::SetupMediaPath() +// +// Set up the path for emulated media devices 'EmulatedMediaPath' +// The default is media/ +// The system temporary path can be set by value '%temp%' +// + { + CHAR path[KMaxFileName + 1]; + const char* mpath; + if (iProperties.GetString("EmulatorMediaPath", mpath) == KErrNotFound) + { + const char* dpath; + TInt r = iProperties.GetString("EmulatorDataPath", dpath); + if (r != KErrNone) + return r; + strcpy(path, dpath); + strcat(path, "media\\"); + return iProperties.Replace("EmulatorMediaPath", path) ? KErrNone : KErrNoMemory; + } + + if (_stricmp(mpath, "%temp%") == 0) + { + DWORD len=GetTempPathA(KMaxFileName, path); + if (len > 0 && len < KMaxFileName) + return iProperties.Replace("EmulatorMediaPath", path) ? KErrNone : KErrNoMemory; + } + + return KErrNone; + } + +const char* Wins::EmulatorMediaPath() + { + const char* mpath = NULL; + iProperties.GetString("EmulatorMediaPath", mpath); + return mpath; + } + +TInt Wins::SetupDrive(int aDrive, const char* aPath) +// +// set up emulated drives +// + { + + // Z drive can't end in anything but "Z\\", since we chop this off and use + // the resulting directory to find filenames with no drive specified in + // MapFileName() below. + aDrive = tolower(aDrive); + if (aDrive=='z') + { + const char* end = aPath + strlen(aPath); + if (_stricmp(end-2,"\\z") != 0 && _stricmp(end-3,"\\z\\") != 0) + return KErrArgument; + } + + char prop[] = "_epoc_drive_?"; + *strchr(prop, '?') = char(aDrive); + + + // If the path begins with the keyword %epocroot%, replace this with EPOCROOT + if (_strnicmp(aPath, "%epocroot%", 10) == 0) + { + aPath += 10; // skip "%epocroot%" + + const char* eRoot; + TInt r = iProperties.GetString("EpocRoot", eRoot); + if (r != KErrNone) + return r; + + int rootSize = strlen(eRoot); + int pathSize = strlen(aPath); + if(rootSize+pathSize>MAX_PATH) + return KErrArgument; + + char fullPath[MAX_PATH+1]; + memcpy(fullPath,eRoot,rootSize); + memcpy(fullPath+rootSize,aPath,pathSize+1); // +1 to get the terminating NULL char + + return iProperties.Replace(prop, fullPath) ? KErrNone : KErrNoMemory; + + } + else + // otherwise, aPath is fully qualified path name. Use that. + return iProperties.Replace(prop, aPath) ? KErrNone : KErrNoMemory; + + } + +TInt Wins::MapDrive(int aDrive, TDes& aBuffer) const +// +// Map aDrive to a path given by environment variables or defaults +// Use this function only in WINS builds +// + { + char drive[KMaxFileName + 1]; + char prop[] = "_epoc_drive_?"; + *strchr(prop, '?') = char(tolower(aDrive)); + + TInt len; + const char* val; + if (iProperties.GetString(prop, val) == KErrNone) + { + len = strlen(val); + if (len > KMaxFileName) + return KErrArgument; + strcpy(drive, val); + } + else + { + // not in properties, so check environment + len = GetEnvironmentVariableA(prop, drive, KMaxFileName + 1); + if (len > KMaxFileName) + return KErrArgument; + } + while (len > 0 && isspace(drive[len-1])) + --len; + if (len == 0) + return KErrNotFound; + if (drive[len-1] != '\\') // add trailing backslash + drive[len++] = '\\'; + if (drive[0] == '\\') + { + // put in the emulator drive + TInt r = iProperties.GetString("EmulatorPath", val); + if (r != KErrNone) + return r; + + memmove(drive + 2, drive, len); + drive[0] = val[0]; + drive[1] = ':'; + len += 2; + } + else if (len < 3 || drive[1] != ':' || drive[2] != '\\') + return KErrArgument; +#ifdef _UNICODE + TUint16* aBufPtr = (TUint16*)aBuffer.Ptr(); + const TText* drv = (const TText*)drive; + for(int index=0;index= 6 && aFilename[4] == '\\') + offset = 3; + else + offset = 2; + } +#ifdef _UNICODE + offset = offset<<1; + TUint8* ptrFilename = (TUint8*)aFilename.Ptr() + offset; + TUint8* ptrBuffer = (TUint8*)aBuffer.Ptr()+aBuffer.Length(); + if (aBuffer.MaxLength()