1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/sql/SRC/Server/SqlSrvMain.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,610 @@
1.4 +// Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <hal.h>
1.20 +#include "SqlSrvMain.h" //CSqlServer
1.21 +#include "SqlSrvStartup.h" //SqlSrvVersion()
1.22 +#include "SqlSrvSession.h" //CSqlSrvSession
1.23 +#include "SqlSrvDbSysSettings.h"//TSqlDbSysSettings
1.24 +#include "SqlSrvStatementUtil.h"
1.25 +#include "SqlSrvStatement.h"
1.26 +#include "sqlite3.h" //sqlite3_enable_shared_cache()
1.27 +#include "SqliteSymbian.h" //sqlite3SymbianLibInit()
1.28 +#include "SqlCompact.h"
1.29 +#include "SqlCompactConn.h"
1.30 +#include "SqlSrvResourceProfiler.h"
1.31 +#ifdef _DEBUG
1.32 +#include <stdio.h>
1.33 +#endif
1.34 +#include "OstTraceDefinitions.h"
1.35 +#ifdef OST_TRACE_COMPILER_IN_USE
1.36 +#include "SqlSrvMainTraces.h"
1.37 +#endif
1.38 +#include "SqlTraceDef.h"
1.39 +
1.40 +#ifndef SQLSRV_STARTUP_TEST
1.41 +static
1.42 +#endif
1.43 +CSqlServer* TheServer = NULL;//The single CSqlServer instance
1.44 +
1.45 +#ifdef _DEBUG
1.46 +#define __SQLDEBUG_EXPR(expr) expr
1.47 +#else
1.48 +#define __SQLDEBUG_EXPR(expr)
1.49 +#endif
1.50 +
1.51 +_LIT(KMatchAllDbFiles, "*");
1.52 +_LIT(KDefaultICollationDllName, "");
1.53 +
1.54 +//Constants for enabling/disabling the shared cache
1.55 +enum TSharedCacheState
1.56 + {
1.57 + EDisableSharedCache = 0,
1.58 + EEnableSharedCache = 1
1.59 + };
1.60 +
1.61 +#ifdef SYSLIBS_TEST
1.62 + //The "lookaside" optimisation is disabled if SYSLIBS_TEST macro is defined.
1.63 + //According to the SQLite authors recommendations, the OOM testing should be performed without this optimisation.
1.64 + const TInt KSqliteLookAsideCellSize = 0;
1.65 + const TInt KSqliteLookAsideCellCount = 0;
1.66 +#else
1.67 + //SQLite, "fixed heap cell size" constants
1.68 + //SQLite will preallocate KSqliteLookAsideCellSize * KSqliteLookAsideCellCount bytes from the heap and
1.69 + //use the allocated block for all allocation requests with size <= KSqliteLookAsideCellSize.
1.70 + //The malloc()/free() request time is constant, if the cell is retrieved/returned from/to the "fixed cell size" block.
1.71 + const TInt KSqliteLookAsideCellSize = 128;
1.72 + const TInt KSqliteLookAsideCellCount = 512;
1.73 +#endif
1.74 +
1.75 +//Local function, used for comparing TSqlSecurityPair objects.
1.76 +//The keys are expected to be UTF8 encoded, zero-terminated.
1.77 +//
1.78 +//The function will panic with panic code 7 in _DEBUG mode if the key part of aLeft or
1.79 +//aRight argument is NULL.
1.80 +static TInt Compare(const TSqlSecurityPair& aLeft, const TSqlSecurityPair& aRight)
1.81 + {
1.82 + __ASSERT_DEBUG(aLeft.iKey != NULL && aRight.iKey != NULL, __SQLPANIC2(ESqlPanicInternalError));
1.83 + return ::CompareNoCase8(TPtrC8(aLeft.iKey), TPtrC8(aRight.iKey));
1.84 + }
1.85 +
1.86 +/**
1.87 +Returns a reference to the sql server instance.
1.88 +
1.89 +@return A reference to the sql server instance.
1.90 +
1.91 +@panic SqlDb 2 If the sql server instance is NULL.
1.92 +
1.93 +@internalComponent
1.94 +*/
1.95 +CSqlServer& SqlServer(void)
1.96 + {
1.97 + __ASSERT_ALWAYS(TheServer != NULL, __SQLPANIC2(ESqlPanicInvalidObj));
1.98 + return *TheServer;
1.99 + }
1.100 +
1.101 +/**
1.102 +Creates new CSqlServer instance.
1.103 +The created instance will be pushed in the cleanup stack.
1.104 +
1.105 +@return A pointer to the created CSqlServer instance.
1.106 +
1.107 +@leave KErrNoMemory, an out of memory condition has occured;
1.108 +*/
1.109 +CSqlServer* CSqlServer::NewLC()
1.110 + {
1.111 + SQL_TRACE_INTERNALS(OstTrace0(TRACE_INTERNALS, CSQLSERVER_NEWLC_ENTRY, "Entry;0;CSqlServer::NewLC"));
1.112 + CSqlServer* self = new (ELeave) CSqlServer;
1.113 + CleanupStack::PushL(self);
1.114 + self->ConstructL();
1.115 + SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_NEWLC_EXIT, "Exit;0x%X;CSqlServer::NewLC", (TUint)self));
1.116 + return self;
1.117 + }
1.118 +
1.119 +/**
1.120 +Frees owned by CSqlServer memory and other resources.
1.121 +*/
1.122 +CSqlServer::~CSqlServer()
1.123 + {
1.124 + SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_CSQLSERVER2_ENTRY, "Entry;0x%x;CSqlServer::~CSqlServer", (TUint)this));
1.125 + delete iCompactor;
1.126 + delete iBurEventMonitor;
1.127 + iDriveSpaceCol.ResetAndDestroy();
1.128 + sqlite3_soft_heap_limit(0);//Set to 0 the soft heap limit
1.129 + iSecurityMap.Close();
1.130 + (void)sqlite3_enable_shared_cache(static_cast <TInt> (EDisableSharedCache));
1.131 + iFlatBuf.Close();
1.132 + User::Free(iBuf);
1.133 + delete iDbConfigFiles;
1.134 + sqlite3SymbianLibFinalize();
1.135 + TheServer = NULL;
1.136 + SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_CSQLSERVER2_EXIT, "Exit;0x%x;CSqlServer::~CSqlServer", (TUint)this));
1.137 + }
1.138 +
1.139 +/**
1.140 +@param aMinLen Requested minimal byte size of the flat buffer
1.141 +
1.142 +@return A reference to the server's general purpose flat bufer. The buffer cannot keep a state between calls.
1.143 +*/
1.144 +RSqlBufFlat& CSqlServer::GetFlatBufL(TInt aMinLen)
1.145 + {
1.146 + __ASSERT_DEBUG(aMinLen >= 0, __SQLPANIC(ESqlPanicBadArgument));
1.147 + __SQLLEAVE_IF_ERROR(iFlatBuf.ReAlloc(aMinLen));
1.148 + SQLPROFILER_REPORT_ALLOC(iFlatBuf.MaxSize());
1.149 + return iFlatBuf;
1.150 + }
1.151 +
1.152 +/**
1.153 +Returns a 8-bit descriptor's reference to the server's general purpose buffer.
1.154 +Note that the function may reallocate the buffer if the buffer length is smaller than the requested minimal length.
1.155 +
1.156 +@param aMinLen Requested minimal 8-bit character length of the buffer
1.157 +
1.158 +@return TDes8 reference to the server's general purpose bufer. The buffer cannot keep a state between calls.
1.159 +*/
1.160 +TDes8& CSqlServer::GetBuf8L(TInt aMinLen)
1.161 + {
1.162 + __ASSERT_DEBUG(aMinLen >= 0, __SQLPANIC(ESqlPanicBadArgument));
1.163 +#ifdef _DEBUG
1.164 + TInt maxBufLen = iBufPtr8.MaxLength();
1.165 + maxBufLen = maxBufLen;
1.166 +#endif
1.167 + if(iBufPtr8.MaxLength() < aMinLen)
1.168 + {
1.169 + __SQLLEAVE_IF_ERROR(ReAllocBuf(aMinLen));
1.170 + }
1.171 + SQLPROFILER_REPORT_ALLOC(iBufPtr8.MaxLength());
1.172 + return iBufPtr8;
1.173 + }
1.174 +
1.175 +/**
1.176 +Returns a 16-bit descriptor's reference to the server's general purpose buffer.
1.177 +Note that the function may reallocate the buffer if the buffer length is smaller than the requested minimal length.
1.178 +
1.179 +@param aMinLen Requested minimal 16-bit character length of the buffer
1.180 +
1.181 +@return TDes16 reference to the server's general purpose bufer. The buffer cannot keep a state between calls.
1.182 +*/
1.183 +TDes16& CSqlServer::GetBuf16L(TInt aMinLen)
1.184 + {
1.185 + __ASSERT_DEBUG(aMinLen >= 0, __SQLPANIC(ESqlPanicBadArgument));
1.186 +#ifdef _DEBUG
1.187 + TInt maxBufLen = iBufPtr16.MaxLength();
1.188 + maxBufLen = maxBufLen;
1.189 +#endif
1.190 + if(iBufPtr16.MaxLength() < aMinLen)
1.191 + {
1.192 + __SQLLEAVE_IF_ERROR(ReAllocBuf(aMinLen * sizeof(TUint16)));
1.193 + }
1.194 + SQLPROFILER_REPORT_ALLOC(iBufPtr16.MaxLength());
1.195 + return iBufPtr16;
1.196 + }
1.197 +
1.198 +/**
1.199 +If iFlatBuf or iBuf allocated memory is more than KBufLimit bytes,
1.200 +then that buffer will be reallocated down to KBufLimit size.
1.201 +*/
1.202 +void CSqlServer::MinimizeBuffers()
1.203 + {
1.204 + iFlatBuf.ResetAndMinimize();
1.205 +#ifdef _DEBUG
1.206 + const TInt KBufLimit = 64;
1.207 + const TUint8* oldBuf = iBuf;
1.208 +#else
1.209 + const TInt KBufLimit = 8 * 1024;
1.210 +#endif
1.211 + if(iBufPtr8.MaxSize() > KBufLimit)
1.212 + {
1.213 + (void)ReAllocBuf(KBufLimit);
1.214 + __ASSERT_DEBUG(oldBuf == iBuf, __SQLPANIC(ESqlPanicInternalError));
1.215 + }
1.216 + }
1.217 +
1.218 +/**
1.219 +Reallocates iBuf. iBuf content is not preserved.
1.220 +Sets iBufPtr8 and iBufPtr16 to point to iBuf.
1.221 +
1.222 +@param aNewBufSize The new buffer size in bytes
1.223 +
1.224 +@return KErrNoMemory, an out of memory condition has occurred;
1.225 + KErrNone, the operation has completed successfully;
1.226 +*/
1.227 +TInt CSqlServer::ReAllocBuf(TInt aNewBufSize)
1.228 + {
1.229 + __ASSERT_DEBUG(aNewBufSize >= 0, __SQLPANIC(ESqlPanicBadArgument));
1.230 +#ifdef _DEBUG
1.231 + const TInt KMinBufSize = 8;
1.232 +#else
1.233 + const TInt KMinBufSize = 2 * 1024;
1.234 +#endif
1.235 + const TInt KNewBufSize = Max(aNewBufSize, KMinBufSize);
1.236 + TUint8* newBuf = static_cast <TUint8*> (User::ReAlloc(iBuf, KNewBufSize));
1.237 + if(newBuf)
1.238 + {
1.239 + iBuf = newBuf;
1.240 + iBufPtr8.Set(iBuf, 0, KNewBufSize);
1.241 + iBufPtr16.Set(reinterpret_cast <TUint16*> (iBuf), 0, (TUint)KNewBufSize / sizeof(TUint16));
1.242 + return KErrNone;
1.243 + }
1.244 + else
1.245 + {//The reallocation has failed, iBuf - not changed
1.246 + iBufPtr8.Zero();
1.247 + iBufPtr16.Zero();
1.248 + return KErrNoMemory;
1.249 + }
1.250 + }
1.251 +
1.252 +/**
1.253 +Creates new CSqlSrvSession instance.
1.254 +If SQLSRV_STARTUP_TEST macro is defined, then the function returns NULL.
1.255 +The "real" implementation of the function is not used in this case because the used unit test will require
1.256 +a lot of cpp files to be included into the test build (t_sqlstartup).
1.257 +
1.258 +@return A pointer to the created CSqlSrvSession instance.
1.259 +
1.260 +@leave KErrNoMemory, an out of memory condition has occured;
1.261 + KErrNotSupported, the client side library version differs from the server version.
1.262 +
1.263 +@see CSqlSrvSession
1.264 +*/
1.265 +CSession2* CSqlServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
1.266 + {
1.267 +#ifdef SQLSRV_STARTUP_TEST
1.268 + aVersion.Name();//to prevent the compiler warning ("unused parameter").
1.269 + return NULL;
1.270 +#else
1.271 + if(!User::QueryVersionSupported(::SqlSrvVersion(), aVersion))
1.272 + {
1.273 + User::Leave(KErrNotSupported);
1.274 + }
1.275 + CSqlSrvSession* sess = CSqlSrvSession::NewL();
1.276 + return sess;
1.277 +#endif //SQLSRV_STARTUP_TEST
1.278 + }
1.279 +
1.280 +/**
1.281 +CSqlServer's active object priority.
1.282 +
1.283 +@internalComponent
1.284 +*/
1.285 +const TInt KSqlServerPriority = CActive::EPriorityStandard;
1.286 +
1.287 +/**
1.288 +Initializes CSqlServer data members with default values.
1.289 +*/
1.290 +CSqlServer::CSqlServer() :
1.291 + CServer2(KSqlServerPriority, ESharableSessions),
1.292 + iSecurityMap(TSqlSecurityLinearOrder(&Compare), TSqlSecurityDestructor()),
1.293 + iBufPtr8(0, 0),
1.294 + iBufPtr16(0, 0)
1.295 + {
1.296 + }
1.297 +
1.298 +/**
1.299 +Initializes CSqlServer instance:
1.300 + - starts the server;
1.301 + - opens sqlite library;
1.302 + - initializes the file session instance;
1.303 + - creates server's private directory on the system drive;
1.304 + - enables sqlite shared cache;
1.305 +
1.306 +@leave KErrNoMemory, an out of memory condition has occured;
1.307 + Note that the function may also leave with some other database specific
1.308 + errors categorised as ESqlDbError.
1.309 +*/
1.310 +void CSqlServer::ConstructL()
1.311 + {
1.312 +#ifndef SQLSRV_STARTUP_TEST
1.313 + //Start the server only in "normal" builds, not in the case where t_sqlstartup unit test tests directly
1.314 + //the SQL server startup code.
1.315 + StartL(KSqlSrvName);
1.316 +#endif
1.317 + SQLPROFILER_SERVER_START();
1.318 + //Configure the SQLite library
1.319 + TInt sqliteErr = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, KSqliteLookAsideCellSize, KSqliteLookAsideCellCount);
1.320 + __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(sqliteErr, KErrArgument));
1.321 + //Open SQLITE library - this must be the first call after StartL() (os_symbian.cpp, "TheAllocator" initialization rellated).
1.322 + __SQLLEAVE_IF_ERROR(sqlite3SymbianLibInit());
1.323 + //Create buffers
1.324 + __SQLLEAVE_IF_ERROR(iFlatBuf.SetCount(0));
1.325 + //Get collation dll name
1.326 + GetCollationDllNameL();
1.327 + //Get the system drive.
1.328 + TInt sysDrive = static_cast<TInt>(RFs::GetSystemDrive());
1.329 + //Get the server private data path.
1.330 + RFs& fs = sqlite3SymbianFs();
1.331 + TFileName serverPrivatePath;
1.332 + __SQLLEAVE_IF_ERROR(fs.PrivatePath(serverPrivatePath));
1.333 + DeleteTempFilesL(sysDrive, serverPrivatePath);
1.334 + //Load config file parameter values (if config file exists) and initialize iFileData.
1.335 + TParse parse;
1.336 + __SQLLEAVE_IF_ERROR(parse.Set(KSqlSrvDefaultConfigFile, &serverPrivatePath, NULL));
1.337 + //Store the names of any existing database config files in memory
1.338 + CacheDbConfigFileNamesL(fs, serverPrivatePath);
1.339 + //Initialise the file data object
1.340 + iFileData.InitL(fs, TDriveUnit(sysDrive).Name(), serverPrivatePath, parse.FullName(), iDbConfigFiles);
1.341 +
1.342 + //Set the soft heap limit (iFileData.ConfigParams() returns now a reference to the config file params, including the soft heap limit, if set)
1.343 + const TSqlSrvConfigParams& configParams = iFileData.ConfigParams();
1.344 + if(configParams.iSoftHeapLimitKb > 0)
1.345 + {
1.346 + __ASSERT_DEBUG(configParams.iSoftHeapLimitKb >= TSqlSrvConfigParams::KMinSoftHeapLimitKb &&
1.347 + configParams.iSoftHeapLimitKb <= TSqlSrvConfigParams::KMaxSoftHeapLimitKb, __SQLPANIC(ESqlPanicInternalError));
1.348 + sqlite3_soft_heap_limit(configParams.iSoftHeapLimitKb * 1024);
1.349 + }
1.350 + //Enable shared cache
1.351 + (void)sqlite3SymbianLastOsError();//clear last OS error
1.352 + TInt err = sqlite3_enable_shared_cache(static_cast <TInt> (EEnableSharedCache));
1.353 + __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError()));
1.354 + //Create an empty "drive space" collection
1.355 + iDriveSpaceCol.Create(fs);
1.356 + // Create the BUR instance
1.357 + iBurEventMonitor = CSqlBurEventMonitor::NewL(*this);
1.358 + //Compactor
1.359 + iCompactor = CSqlCompactor::NewL(&SqlCreateCompactConnL, KSqlCompactStepIntervalMs);
1.360 +#ifdef _DEBUG
1.361 + //The following statements exist to prevent the failure of the OOM testing in debug mode.
1.362 + //The standard C library allocates some memory at the startup and stores a pointer to the allocated memory
1.363 + //in the TLS. During normal API OOM testing the SQL server is not restarted, it never goes down.
1.364 + //Then the TLS and the allocated memory are not released. In which case the OOM testing will fail
1.365 + //(because the standard C library performs a lazy initialization and the allocation and TLS usage will be made
1.366 + //at the point of first use of some C function. This is out of the control of the test code).
1.367 + //In order to avoid that, during the SQL server startup here, before the OOM test goes and checks what
1.368 + //is the allocated memory at the beginning, a fake sprintf() call is made in order to force the mentioned above
1.369 + //allocation in the standard C library.
1.370 + //All explanations above are true, except one case when the SQl server startup code is tested directly.
1.371 + #ifndef SQLSRV_STARTUP_TEST
1.372 + const TInt KAnyNumber = 0xAA55;
1.373 + char tmp[32];
1.374 + sprintf(tmp, "%04X", KAnyNumber);
1.375 + const TInt KGreatSize = 1024;
1.376 + __SQLLEAVE_IF_ERROR(ReAllocBuf(KGreatSize));
1.377 + #endif //SQLSRV_STARTUP_TEST
1.378 +#endif //_DEBUG
1.379 + }
1.380 +
1.381 +/**
1.382 +Delete any temp files left the "temp" subdirectory in server's private directory.
1.383 +
1.384 +The SQLite is configured to use shared page cache. When the shared page cache is enabled,
1.385 +those temp files created by SQLite are deleted only when the database gets closed. However,
1.386 +if during power down event the client application does not close the database,
1.387 +the temp files will never get deleted.
1.388 +This is why the SQL server should deletes all temp files during its start-up.
1.389 +
1.390 +Note that all errors exept KErrNoMemory are ignored in the function body, becasuse
1.391 +the temp files deletion is not a critical operation to prevent the server start up.
1.392 +
1.393 +@param aDriveNumber A drive number.
1.394 +@param aServerPath A server's private path.
1.395 +
1.396 +*/
1.397 +void CSqlServer::DeleteTempFilesL(TInt aDriveNumber, const TDesC& aServerPath)const
1.398 + {
1.399 + _LIT(KTempFileDir, "temp");
1.400 + _LIT(KWildCard, "*.*");
1.401 + TDriveUnit drive(aDriveNumber);
1.402 + TDriveName driveName = drive.Name();
1.403 + TParse parse;
1.404 + (void)parse.Set(aServerPath, &driveName, 0);//this call can't fail
1.405 + (void)parse.AddDir(KTempFileDir);//this call can't fail
1.406 + TFileName tempfileDir(parse.FullName());
1.407 + (void)parse.Set(KWildCard, &tempfileDir, 0);//this call can't fail
1.408 + RFs& fs = sqlite3SymbianFs();
1.409 + CFileMan* fm = CFileMan::NewL(fs);
1.410 + (void)fm->Delete(parse.FullName());
1.411 + delete fm;
1.412 + }
1.413 +
1.414 +/**
1.415 +Retrieves in iCollationDllName current(default) collation dll name.
1.416 +see TExtendedLocale
1.417 +*/
1.418 +void CSqlServer::GetCollationDllNameL()
1.419 + {
1.420 + TExtendedLocale extdlocale;
1.421 + extdlocale.LoadSystemSettings();
1.422 + TFileName fname;
1.423 + TParse fileName;
1.424 + TInt err = extdlocale.GetLocaleDllName(ELocaleCollateSetting, fname);
1.425 + if(err!= KErrNone)
1.426 + {
1.427 + iCollationDllName = KDefaultICollationDllName;
1.428 + }
1.429 + else
1.430 + {
1.431 + //only get the file name + extension
1.432 + fileName.Set(fname, NULL, NULL);
1.433 + iCollationDllName = fileName.NameAndExt();
1.434 + }
1.435 + SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLSERVER_GETCOLLATIONDLLNAMEL, "0x%x;CSqlServer::GetCollationDllNameL;iCollationDllName=%S;err=%d", (TUint)this, __SQLPRNSTR(iCollationDllName), err));
1.436 + }
1.437 +/**
1.438 +Finds and caches the name of each database configuration file
1.439 +that exists in the server's private data cage on the Z: drive
1.440 +*/
1.441 +void CSqlServer::CacheDbConfigFileNamesL(RFs& aFs, const TDesC& aServerPrivatePath)
1.442 + {
1.443 + //Create an in-memory array holding the names of the database config files, if any exist
1.444 + TParse parseDbConfig;
1.445 + __SQLLEAVE_IF_ERROR(parseDbConfig.Set(KSqlSrvDbConfigFileFormat, &aServerPrivatePath, NULL));
1.446 + TFileName configFilePath(parseDbConfig.FullName()); // get 'drive:\private path\cfg*' search string
1.447 + CDir* entryList = 0; // memory will be allocated for this in GetDir()
1.448 + TInt err = aFs.GetDir(configFilePath, KEntryAttNormal, ESortByName, entryList);
1.449 + if(err == KErrNone)
1.450 + {
1.451 + __ASSERT_DEBUG(entryList != NULL, __SQLPANIC(ESqlPanicInternalError));
1.452 + CleanupStack::PushL(entryList);
1.453 + if(entryList->Count() > 0)
1.454 + {
1.455 + iDbConfigFiles = CDbConfigFiles::NewL(*entryList);
1.456 + }
1.457 + CleanupStack::PopAndDestroy(entryList);
1.458 + }
1.459 + else
1.460 + {
1.461 + SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLSERVER_CACHEDDBCONFIGFILENAMESL, "0x%X;CSqlServer::CacheDbConfigFileNamesL;GetDir() failed with error code %d", (TUint)this, err));
1.462 + __ASSERT_DEBUG(!entryList, __SQLPANIC(ESqlPanicInternalError));
1.463 + }
1.464 + }
1.465 +
1.466 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.467 +//////////////////////////////////////// MSqlPolicyInspector implementation ///////////////////////////////
1.468 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.469 +
1.470 +/**
1.471 +Implements MSqlPolicyInspector::Check() method.
1.472 +
1.473 +@see MSqlPolicyInspector
1.474 +@see MSqlPolicyInspector::Check()
1.475 +*/
1.476 +TBool CSqlServer::Check(const TSecurityPolicy& aPolicy) const
1.477 + {
1.478 +#ifdef SQLSRV_STARTUP_TEST
1.479 + aPolicy.Package();//to prevent compiler warning
1.480 + return ETrue;
1.481 +#else
1.482 + return aPolicy.CheckPolicy(CServer2::Message());
1.483 +#endif
1.484 + }
1.485 +
1.486 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.487 +//////////////////////////////////////// MSqlSrvBurInterface implementation //////////////////////////////
1.488 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.489 +
1.490 +/**
1.491 +Implements MSqlSrvBurInterface::Fs().
1.492 +
1.493 +@return A reference to the file session instance.
1.494 +*/
1.495 +RFs& CSqlServer::Fs()
1.496 + {
1.497 + return iFileData.Fs();
1.498 + }
1.499 +
1.500 +/**
1.501 +Implements MSqlSrvBurInterface::GetBackupListL().
1.502 +Retrieves in aFileNameList parameter a list of secure database names (full database names, including path)
1.503 +which security UID matches aUid parameter.
1.504 +No databases will be included into the list, if the drive is read-only.
1.505 +
1.506 +@param aUid Database security UID.
1.507 +@param aDrive The drive where the database search will be performed, in the SQL server private data cage.
1.508 +@param aFileNameList An output parameter.
1.509 + Each array entry represents the full name of a database in SQL server private data cage
1.510 + on the specified drive (aDrive), which uid matches the aUid parameter.
1.511 +
1.512 +@leave KErrNoMemory, an out of memory condition has occured;
1.513 + Note that the function may leave also with some other database specific or OS specific
1.514 + error codes.
1.515 +*/
1.516 +void CSqlServer::GetBackUpListL(TSecureId aUid, TDriveNumber aDrive, RArray<HBufC*>& aFileNameList)
1.517 + {
1.518 + SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL_ENTRY, "Entry;0x%x;CSqlServer::GetBackUpListL;aDrive=%d;aUid=0x%X", (TUint)this, (TInt)aDrive, (TUint)aUid.iId));
1.519 + __ASSERT_DEBUG(aFileNameList.Count() == 0, __SQLPANIC(ESqlPanicBadArgument));
1.520 + RFs& fs = iFileData.Fs();
1.521 + //No files in the list if aDrive is a read-only drive
1.522 + TDriveInfo driveInfo;
1.523 + __SQLLEAVE_IF_ERROR(fs.Drive(driveInfo, aDrive));
1.524 + if(driveInfo.iDriveAtt & KDriveAttRom)
1.525 + {
1.526 + return;
1.527 + }
1.528 + //Compose the search path
1.529 + TDriveUnit driveUnit(aDrive);
1.530 + TDriveName driveName = driveUnit.Name();
1.531 + TFileName path;
1.532 + path.Copy(driveName);
1.533 + path.Append(iFileData.PrivatePath());
1.534 + //Include the aUid and the "*" mask
1.535 + TUidName uidName = (static_cast <TUid> (aUid)).Name();
1.536 + TBuf<KMaxUidName + sizeof(KMatchAllDbFiles)> fileNameMask(uidName);
1.537 + fileNameMask.Append(KMatchAllDbFiles);
1.538 + TParse parse;
1.539 + __SQLLEAVE_IF_ERROR(parse.Set(path, &fileNameMask, NULL));
1.540 + //Do the search
1.541 + TPtrC fullPath(parse.FullName());
1.542 + SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL_FULLPATH, "Exit;0x%x;CSqlServer::GetBackUpListL;fullPath=%S", (TUint)this, __SQLPRNSTR(fullPath)));
1.543 + CDir* fileNameCol = NULL;
1.544 + TInt err = fs.GetDir(fullPath, KEntryAttNormal, ESortNone, fileNameCol);
1.545 + if(err == KErrNotFound)
1.546 + {
1.547 + __ASSERT_DEBUG(!fileNameCol, __SQLPANIC(ESqlPanicInternalError));
1.548 + SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL_EXIT1, "Exit;0x%x;CSqlServer::GetBackUpListL;no files found", (TUint)this));
1.549 + return;
1.550 + }
1.551 + __SQLLEAVE_IF_ERROR(err);
1.552 + __ASSERT_DEBUG(fileNameCol != NULL, __SQLPANIC(ESqlPanicInternalError));
1.553 + CleanupStack::PushL(fileNameCol);
1.554 + TInt fileCount = fileNameCol->Count();
1.555 + __SQLLEAVE_IF_ERROR(aFileNameList.Reserve(fileCount));
1.556 + //Append the full database file paths to the file names list.
1.557 + for(TInt i=0;i<fileCount;++i)
1.558 + {
1.559 + const ::TEntry& entry = (*fileNameCol)[i];
1.560 + __ASSERT_DEBUG(!entry.IsDir(), __SQLPANIC(ESqlPanicInternalError));//RFs::GetDir() search attributes exclude directories (see the GetDir() call above).
1.561 + __SQLLEAVE_IF_ERROR(parse.Set(path, &entry.iName, NULL));
1.562 + TPtrC fname(parse.FullName());
1.563 + SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL, "0x%x;CSqlServer::GetBackUpListL;fname=%S", (TUint)this, __SQLPRNSTR(fname)));
1.564 + HBufC* fnameBuf = fname.AllocL();
1.565 + __SQLDEBUG_EXPR(err = )aFileNameList.Append(fnameBuf);
1.566 + __ASSERT_DEBUG(err == KErrNone, __SQLPANIC(ESqlPanicInternalError));
1.567 + }
1.568 + CleanupStack::PopAndDestroy(fileNameCol);
1.569 + SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL_EXIT2, "Exit;0x%x;CSqlServer::GetBackUpListL;file count=%d", (TUint)this, fileCount));
1.570 + }
1.571 +
1.572 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.573 +//////////////////////////////////////// SQL server startup //////////////////////////////////////////////
1.574 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.575 +
1.576 +#ifndef SQLSRV_STARTUP_TEST
1.577 +
1.578 +//Run the SQL server
1.579 +static void RunServerL()
1.580 + {
1.581 + // naming the server thread after the server helps to debug panics
1.582 + User::LeaveIfError(User::RenameThread(KSqlSrvName));
1.583 +
1.584 + // create and install the active scheduler we need
1.585 + CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
1.586 + CleanupStack::PushL(scheduler);
1.587 + CActiveScheduler::Install(scheduler);
1.588 + TheServer = CSqlServer::NewLC();
1.589 + RProcess::Rendezvous(KErrNone);
1.590 + CActiveScheduler::Start();
1.591 +
1.592 + CleanupStack::PopAndDestroy(2, scheduler);//CSqlServer, scheduler
1.593 + }
1.594 +
1.595 +// SQL server process entry point
1.596 +TInt E32Main()
1.597 + {
1.598 + __UHEAP_MARK;
1.599 +
1.600 + CTrapCleanup* cleanup = CTrapCleanup::New();
1.601 + TInt err = KErrNoMemory;
1.602 + if(cleanup)
1.603 + {
1.604 + TRAP(err, ::RunServerL());
1.605 + delete cleanup;
1.606 + }
1.607 +
1.608 + __UHEAP_MARKEND;
1.609 +
1.610 + return err;
1.611 + }
1.612 +
1.613 +#endif //SQLSRV_STARTUP_TEST