sl@0: // Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "SqlSrvMain.h" //CSqlServer sl@0: #include "SqlSrvStartup.h" //SqlSrvVersion() sl@0: #include "SqlSrvSession.h" //CSqlSrvSession sl@0: #include "SqlSrvDbSysSettings.h"//TSqlDbSysSettings sl@0: #include "SqlSrvStatementUtil.h" sl@0: #include "SqlSrvStatement.h" sl@0: #include "sqlite3.h" //sqlite3_enable_shared_cache() sl@0: #include "SqliteSymbian.h" //sqlite3SymbianLibInit() sl@0: #include "SqlCompact.h" sl@0: #include "SqlCompactConn.h" sl@0: #include "SqlSrvResourceProfiler.h" sl@0: #ifdef _DEBUG sl@0: #include sl@0: #endif sl@0: #include "OstTraceDefinitions.h" sl@0: #ifdef OST_TRACE_COMPILER_IN_USE sl@0: #include "SqlSrvMainTraces.h" sl@0: #endif sl@0: #include "SqlTraceDef.h" sl@0: sl@0: #ifndef SQLSRV_STARTUP_TEST sl@0: static sl@0: #endif sl@0: CSqlServer* TheServer = NULL;//The single CSqlServer instance sl@0: sl@0: #ifdef _DEBUG sl@0: #define __SQLDEBUG_EXPR(expr) expr sl@0: #else sl@0: #define __SQLDEBUG_EXPR(expr) sl@0: #endif sl@0: sl@0: _LIT(KMatchAllDbFiles, "*"); sl@0: _LIT(KDefaultICollationDllName, ""); sl@0: sl@0: //Constants for enabling/disabling the shared cache sl@0: enum TSharedCacheState sl@0: { sl@0: EDisableSharedCache = 0, sl@0: EEnableSharedCache = 1 sl@0: }; sl@0: sl@0: #ifdef SYSLIBS_TEST sl@0: //The "lookaside" optimisation is disabled if SYSLIBS_TEST macro is defined. sl@0: //According to the SQLite authors recommendations, the OOM testing should be performed without this optimisation. sl@0: const TInt KSqliteLookAsideCellSize = 0; sl@0: const TInt KSqliteLookAsideCellCount = 0; sl@0: #else sl@0: //SQLite, "fixed heap cell size" constants sl@0: //SQLite will preallocate KSqliteLookAsideCellSize * KSqliteLookAsideCellCount bytes from the heap and sl@0: //use the allocated block for all allocation requests with size <= KSqliteLookAsideCellSize. sl@0: //The malloc()/free() request time is constant, if the cell is retrieved/returned from/to the "fixed cell size" block. sl@0: const TInt KSqliteLookAsideCellSize = 128; sl@0: const TInt KSqliteLookAsideCellCount = 512; sl@0: #endif sl@0: sl@0: //Local function, used for comparing TSqlSecurityPair objects. sl@0: //The keys are expected to be UTF8 encoded, zero-terminated. sl@0: // sl@0: //The function will panic with panic code 7 in _DEBUG mode if the key part of aLeft or sl@0: //aRight argument is NULL. sl@0: static TInt Compare(const TSqlSecurityPair& aLeft, const TSqlSecurityPair& aRight) sl@0: { sl@0: __ASSERT_DEBUG(aLeft.iKey != NULL && aRight.iKey != NULL, __SQLPANIC2(ESqlPanicInternalError)); sl@0: return ::CompareNoCase8(TPtrC8(aLeft.iKey), TPtrC8(aRight.iKey)); sl@0: } sl@0: sl@0: /** sl@0: Returns a reference to the sql server instance. sl@0: sl@0: @return A reference to the sql server instance. sl@0: sl@0: @panic SqlDb 2 If the sql server instance is NULL. sl@0: sl@0: @internalComponent sl@0: */ sl@0: CSqlServer& SqlServer(void) sl@0: { sl@0: __ASSERT_ALWAYS(TheServer != NULL, __SQLPANIC2(ESqlPanicInvalidObj)); sl@0: return *TheServer; sl@0: } sl@0: sl@0: /** sl@0: Creates new CSqlServer instance. sl@0: The created instance will be pushed in the cleanup stack. sl@0: sl@0: @return A pointer to the created CSqlServer instance. sl@0: sl@0: @leave KErrNoMemory, an out of memory condition has occured; sl@0: */ sl@0: CSqlServer* CSqlServer::NewLC() sl@0: { sl@0: SQL_TRACE_INTERNALS(OstTrace0(TRACE_INTERNALS, CSQLSERVER_NEWLC_ENTRY, "Entry;0;CSqlServer::NewLC")); sl@0: CSqlServer* self = new (ELeave) CSqlServer; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_NEWLC_EXIT, "Exit;0x%X;CSqlServer::NewLC", (TUint)self)); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: Frees owned by CSqlServer memory and other resources. sl@0: */ sl@0: CSqlServer::~CSqlServer() sl@0: { sl@0: SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_CSQLSERVER2_ENTRY, "Entry;0x%x;CSqlServer::~CSqlServer", (TUint)this)); sl@0: delete iCompactor; sl@0: delete iBurEventMonitor; sl@0: iDriveSpaceCol.ResetAndDestroy(); sl@0: sqlite3_soft_heap_limit(0);//Set to 0 the soft heap limit sl@0: iSecurityMap.Close(); sl@0: (void)sqlite3_enable_shared_cache(static_cast (EDisableSharedCache)); sl@0: iFlatBuf.Close(); sl@0: User::Free(iBuf); sl@0: delete iDbConfigFiles; sl@0: sqlite3SymbianLibFinalize(); sl@0: TheServer = NULL; sl@0: SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_CSQLSERVER2_EXIT, "Exit;0x%x;CSqlServer::~CSqlServer", (TUint)this)); sl@0: } sl@0: sl@0: /** sl@0: @param aMinLen Requested minimal byte size of the flat buffer sl@0: sl@0: @return A reference to the server's general purpose flat bufer. The buffer cannot keep a state between calls. sl@0: */ sl@0: RSqlBufFlat& CSqlServer::GetFlatBufL(TInt aMinLen) sl@0: { sl@0: __ASSERT_DEBUG(aMinLen >= 0, __SQLPANIC(ESqlPanicBadArgument)); sl@0: __SQLLEAVE_IF_ERROR(iFlatBuf.ReAlloc(aMinLen)); sl@0: SQLPROFILER_REPORT_ALLOC(iFlatBuf.MaxSize()); sl@0: return iFlatBuf; sl@0: } sl@0: sl@0: /** sl@0: Returns a 8-bit descriptor's reference to the server's general purpose buffer. sl@0: Note that the function may reallocate the buffer if the buffer length is smaller than the requested minimal length. sl@0: sl@0: @param aMinLen Requested minimal 8-bit character length of the buffer sl@0: sl@0: @return TDes8 reference to the server's general purpose bufer. The buffer cannot keep a state between calls. sl@0: */ sl@0: TDes8& CSqlServer::GetBuf8L(TInt aMinLen) sl@0: { sl@0: __ASSERT_DEBUG(aMinLen >= 0, __SQLPANIC(ESqlPanicBadArgument)); sl@0: #ifdef _DEBUG sl@0: TInt maxBufLen = iBufPtr8.MaxLength(); sl@0: maxBufLen = maxBufLen; sl@0: #endif sl@0: if(iBufPtr8.MaxLength() < aMinLen) sl@0: { sl@0: __SQLLEAVE_IF_ERROR(ReAllocBuf(aMinLen)); sl@0: } sl@0: SQLPROFILER_REPORT_ALLOC(iBufPtr8.MaxLength()); sl@0: return iBufPtr8; sl@0: } sl@0: sl@0: /** sl@0: Returns a 16-bit descriptor's reference to the server's general purpose buffer. sl@0: Note that the function may reallocate the buffer if the buffer length is smaller than the requested minimal length. sl@0: sl@0: @param aMinLen Requested minimal 16-bit character length of the buffer sl@0: sl@0: @return TDes16 reference to the server's general purpose bufer. The buffer cannot keep a state between calls. sl@0: */ sl@0: TDes16& CSqlServer::GetBuf16L(TInt aMinLen) sl@0: { sl@0: __ASSERT_DEBUG(aMinLen >= 0, __SQLPANIC(ESqlPanicBadArgument)); sl@0: #ifdef _DEBUG sl@0: TInt maxBufLen = iBufPtr16.MaxLength(); sl@0: maxBufLen = maxBufLen; sl@0: #endif sl@0: if(iBufPtr16.MaxLength() < aMinLen) sl@0: { sl@0: __SQLLEAVE_IF_ERROR(ReAllocBuf(aMinLen * sizeof(TUint16))); sl@0: } sl@0: SQLPROFILER_REPORT_ALLOC(iBufPtr16.MaxLength()); sl@0: return iBufPtr16; sl@0: } sl@0: sl@0: /** sl@0: If iFlatBuf or iBuf allocated memory is more than KBufLimit bytes, sl@0: then that buffer will be reallocated down to KBufLimit size. sl@0: */ sl@0: void CSqlServer::MinimizeBuffers() sl@0: { sl@0: iFlatBuf.ResetAndMinimize(); sl@0: #ifdef _DEBUG sl@0: const TInt KBufLimit = 64; sl@0: const TUint8* oldBuf = iBuf; sl@0: #else sl@0: const TInt KBufLimit = 8 * 1024; sl@0: #endif sl@0: if(iBufPtr8.MaxSize() > KBufLimit) sl@0: { sl@0: (void)ReAllocBuf(KBufLimit); sl@0: __ASSERT_DEBUG(oldBuf == iBuf, __SQLPANIC(ESqlPanicInternalError)); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Reallocates iBuf. iBuf content is not preserved. sl@0: Sets iBufPtr8 and iBufPtr16 to point to iBuf. sl@0: sl@0: @param aNewBufSize The new buffer size in bytes sl@0: sl@0: @return KErrNoMemory, an out of memory condition has occurred; sl@0: KErrNone, the operation has completed successfully; sl@0: */ sl@0: TInt CSqlServer::ReAllocBuf(TInt aNewBufSize) sl@0: { sl@0: __ASSERT_DEBUG(aNewBufSize >= 0, __SQLPANIC(ESqlPanicBadArgument)); sl@0: #ifdef _DEBUG sl@0: const TInt KMinBufSize = 8; sl@0: #else sl@0: const TInt KMinBufSize = 2 * 1024; sl@0: #endif sl@0: const TInt KNewBufSize = Max(aNewBufSize, KMinBufSize); sl@0: TUint8* newBuf = static_cast (User::ReAlloc(iBuf, KNewBufSize)); sl@0: if(newBuf) sl@0: { sl@0: iBuf = newBuf; sl@0: iBufPtr8.Set(iBuf, 0, KNewBufSize); sl@0: iBufPtr16.Set(reinterpret_cast (iBuf), 0, (TUint)KNewBufSize / sizeof(TUint16)); sl@0: return KErrNone; sl@0: } sl@0: else sl@0: {//The reallocation has failed, iBuf - not changed sl@0: iBufPtr8.Zero(); sl@0: iBufPtr16.Zero(); sl@0: return KErrNoMemory; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Creates new CSqlSrvSession instance. sl@0: If SQLSRV_STARTUP_TEST macro is defined, then the function returns NULL. sl@0: The "real" implementation of the function is not used in this case because the used unit test will require sl@0: a lot of cpp files to be included into the test build (t_sqlstartup). sl@0: sl@0: @return A pointer to the created CSqlSrvSession instance. sl@0: sl@0: @leave KErrNoMemory, an out of memory condition has occured; sl@0: KErrNotSupported, the client side library version differs from the server version. sl@0: sl@0: @see CSqlSrvSession sl@0: */ sl@0: CSession2* CSqlServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const sl@0: { sl@0: #ifdef SQLSRV_STARTUP_TEST sl@0: aVersion.Name();//to prevent the compiler warning ("unused parameter"). sl@0: return NULL; sl@0: #else sl@0: if(!User::QueryVersionSupported(::SqlSrvVersion(), aVersion)) sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: CSqlSrvSession* sess = CSqlSrvSession::NewL(); sl@0: return sess; sl@0: #endif //SQLSRV_STARTUP_TEST sl@0: } sl@0: sl@0: /** sl@0: CSqlServer's active object priority. sl@0: sl@0: @internalComponent sl@0: */ sl@0: const TInt KSqlServerPriority = CActive::EPriorityStandard; sl@0: sl@0: /** sl@0: Initializes CSqlServer data members with default values. sl@0: */ sl@0: CSqlServer::CSqlServer() : sl@0: CServer2(KSqlServerPriority, ESharableSessions), sl@0: iSecurityMap(TSqlSecurityLinearOrder(&Compare), TSqlSecurityDestructor()), sl@0: iBufPtr8(0, 0), sl@0: iBufPtr16(0, 0) sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Initializes CSqlServer instance: sl@0: - starts the server; sl@0: - opens sqlite library; sl@0: - initializes the file session instance; sl@0: - creates server's private directory on the system drive; sl@0: - enables sqlite shared cache; sl@0: sl@0: @leave KErrNoMemory, an out of memory condition has occured; sl@0: Note that the function may also leave with some other database specific sl@0: errors categorised as ESqlDbError. sl@0: */ sl@0: void CSqlServer::ConstructL() sl@0: { sl@0: #ifndef SQLSRV_STARTUP_TEST sl@0: //Start the server only in "normal" builds, not in the case where t_sqlstartup unit test tests directly sl@0: //the SQL server startup code. sl@0: StartL(KSqlSrvName); sl@0: #endif sl@0: SQLPROFILER_SERVER_START(); sl@0: //Configure the SQLite library sl@0: TInt sqliteErr = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, KSqliteLookAsideCellSize, KSqliteLookAsideCellCount); sl@0: __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(sqliteErr, KErrArgument)); sl@0: //Open SQLITE library - this must be the first call after StartL() (os_symbian.cpp, "TheAllocator" initialization rellated). sl@0: __SQLLEAVE_IF_ERROR(sqlite3SymbianLibInit()); sl@0: //Create buffers sl@0: __SQLLEAVE_IF_ERROR(iFlatBuf.SetCount(0)); sl@0: //Get collation dll name sl@0: GetCollationDllNameL(); sl@0: //Get the system drive. sl@0: TInt sysDrive = static_cast(RFs::GetSystemDrive()); sl@0: //Get the server private data path. sl@0: RFs& fs = sqlite3SymbianFs(); sl@0: TFileName serverPrivatePath; sl@0: __SQLLEAVE_IF_ERROR(fs.PrivatePath(serverPrivatePath)); sl@0: DeleteTempFilesL(sysDrive, serverPrivatePath); sl@0: //Load config file parameter values (if config file exists) and initialize iFileData. sl@0: TParse parse; sl@0: __SQLLEAVE_IF_ERROR(parse.Set(KSqlSrvDefaultConfigFile, &serverPrivatePath, NULL)); sl@0: //Store the names of any existing database config files in memory sl@0: CacheDbConfigFileNamesL(fs, serverPrivatePath); sl@0: //Initialise the file data object sl@0: iFileData.InitL(fs, TDriveUnit(sysDrive).Name(), serverPrivatePath, parse.FullName(), iDbConfigFiles); sl@0: sl@0: //Set the soft heap limit (iFileData.ConfigParams() returns now a reference to the config file params, including the soft heap limit, if set) sl@0: const TSqlSrvConfigParams& configParams = iFileData.ConfigParams(); sl@0: if(configParams.iSoftHeapLimitKb > 0) sl@0: { sl@0: __ASSERT_DEBUG(configParams.iSoftHeapLimitKb >= TSqlSrvConfigParams::KMinSoftHeapLimitKb && sl@0: configParams.iSoftHeapLimitKb <= TSqlSrvConfigParams::KMaxSoftHeapLimitKb, __SQLPANIC(ESqlPanicInternalError)); sl@0: sqlite3_soft_heap_limit(configParams.iSoftHeapLimitKb * 1024); sl@0: } sl@0: //Enable shared cache sl@0: (void)sqlite3SymbianLastOsError();//clear last OS error sl@0: TInt err = sqlite3_enable_shared_cache(static_cast (EEnableSharedCache)); sl@0: __SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError())); sl@0: //Create an empty "drive space" collection sl@0: iDriveSpaceCol.Create(fs); sl@0: // Create the BUR instance sl@0: iBurEventMonitor = CSqlBurEventMonitor::NewL(*this); sl@0: //Compactor sl@0: iCompactor = CSqlCompactor::NewL(&SqlCreateCompactConnL, KSqlCompactStepIntervalMs); sl@0: #ifdef _DEBUG sl@0: //The following statements exist to prevent the failure of the OOM testing in debug mode. sl@0: //The standard C library allocates some memory at the startup and stores a pointer to the allocated memory sl@0: //in the TLS. During normal API OOM testing the SQL server is not restarted, it never goes down. sl@0: //Then the TLS and the allocated memory are not released. In which case the OOM testing will fail sl@0: //(because the standard C library performs a lazy initialization and the allocation and TLS usage will be made sl@0: //at the point of first use of some C function. This is out of the control of the test code). sl@0: //In order to avoid that, during the SQL server startup here, before the OOM test goes and checks what sl@0: //is the allocated memory at the beginning, a fake sprintf() call is made in order to force the mentioned above sl@0: //allocation in the standard C library. sl@0: //All explanations above are true, except one case when the SQl server startup code is tested directly. sl@0: #ifndef SQLSRV_STARTUP_TEST sl@0: const TInt KAnyNumber = 0xAA55; sl@0: char tmp[32]; sl@0: sprintf(tmp, "%04X", KAnyNumber); sl@0: const TInt KGreatSize = 1024; sl@0: __SQLLEAVE_IF_ERROR(ReAllocBuf(KGreatSize)); sl@0: #endif //SQLSRV_STARTUP_TEST sl@0: #endif //_DEBUG sl@0: } sl@0: sl@0: /** sl@0: Delete any temp files left the "temp" subdirectory in server's private directory. sl@0: sl@0: The SQLite is configured to use shared page cache. When the shared page cache is enabled, sl@0: those temp files created by SQLite are deleted only when the database gets closed. However, sl@0: if during power down event the client application does not close the database, sl@0: the temp files will never get deleted. sl@0: This is why the SQL server should deletes all temp files during its start-up. sl@0: sl@0: Note that all errors exept KErrNoMemory are ignored in the function body, becasuse sl@0: the temp files deletion is not a critical operation to prevent the server start up. sl@0: sl@0: @param aDriveNumber A drive number. sl@0: @param aServerPath A server's private path. sl@0: sl@0: */ sl@0: void CSqlServer::DeleteTempFilesL(TInt aDriveNumber, const TDesC& aServerPath)const sl@0: { sl@0: _LIT(KTempFileDir, "temp"); sl@0: _LIT(KWildCard, "*.*"); sl@0: TDriveUnit drive(aDriveNumber); sl@0: TDriveName driveName = drive.Name(); sl@0: TParse parse; sl@0: (void)parse.Set(aServerPath, &driveName, 0);//this call can't fail sl@0: (void)parse.AddDir(KTempFileDir);//this call can't fail sl@0: TFileName tempfileDir(parse.FullName()); sl@0: (void)parse.Set(KWildCard, &tempfileDir, 0);//this call can't fail sl@0: RFs& fs = sqlite3SymbianFs(); sl@0: CFileMan* fm = CFileMan::NewL(fs); sl@0: (void)fm->Delete(parse.FullName()); sl@0: delete fm; sl@0: } sl@0: sl@0: /** sl@0: Retrieves in iCollationDllName current(default) collation dll name. sl@0: see TExtendedLocale sl@0: */ sl@0: void CSqlServer::GetCollationDllNameL() sl@0: { sl@0: TExtendedLocale extdlocale; sl@0: extdlocale.LoadSystemSettings(); sl@0: TFileName fname; sl@0: TParse fileName; sl@0: TInt err = extdlocale.GetLocaleDllName(ELocaleCollateSetting, fname); sl@0: if(err!= KErrNone) sl@0: { sl@0: iCollationDllName = KDefaultICollationDllName; sl@0: } sl@0: else sl@0: { sl@0: //only get the file name + extension sl@0: fileName.Set(fname, NULL, NULL); sl@0: iCollationDllName = fileName.NameAndExt(); sl@0: } sl@0: SQL_TRACE_INTERNALS(OstTraceExt3(TRACE_INTERNALS, CSQLSERVER_GETCOLLATIONDLLNAMEL, "0x%x;CSqlServer::GetCollationDllNameL;iCollationDllName=%S;err=%d", (TUint)this, __SQLPRNSTR(iCollationDllName), err)); sl@0: } sl@0: /** sl@0: Finds and caches the name of each database configuration file sl@0: that exists in the server's private data cage on the Z: drive sl@0: */ sl@0: void CSqlServer::CacheDbConfigFileNamesL(RFs& aFs, const TDesC& aServerPrivatePath) sl@0: { sl@0: //Create an in-memory array holding the names of the database config files, if any exist sl@0: TParse parseDbConfig; sl@0: __SQLLEAVE_IF_ERROR(parseDbConfig.Set(KSqlSrvDbConfigFileFormat, &aServerPrivatePath, NULL)); sl@0: TFileName configFilePath(parseDbConfig.FullName()); // get 'drive:\private path\cfg*' search string sl@0: CDir* entryList = 0; // memory will be allocated for this in GetDir() sl@0: TInt err = aFs.GetDir(configFilePath, KEntryAttNormal, ESortByName, entryList); sl@0: if(err == KErrNone) sl@0: { sl@0: __ASSERT_DEBUG(entryList != NULL, __SQLPANIC(ESqlPanicInternalError)); sl@0: CleanupStack::PushL(entryList); sl@0: if(entryList->Count() > 0) sl@0: { sl@0: iDbConfigFiles = CDbConfigFiles::NewL(*entryList); sl@0: } sl@0: CleanupStack::PopAndDestroy(entryList); sl@0: } sl@0: else sl@0: { sl@0: SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLSERVER_CACHEDDBCONFIGFILENAMESL, "0x%X;CSqlServer::CacheDbConfigFileNamesL;GetDir() failed with error code %d", (TUint)this, err)); sl@0: __ASSERT_DEBUG(!entryList, __SQLPANIC(ESqlPanicInternalError)); sl@0: } sl@0: } sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: //////////////////////////////////////// MSqlPolicyInspector implementation /////////////////////////////// sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: Implements MSqlPolicyInspector::Check() method. sl@0: sl@0: @see MSqlPolicyInspector sl@0: @see MSqlPolicyInspector::Check() sl@0: */ sl@0: TBool CSqlServer::Check(const TSecurityPolicy& aPolicy) const sl@0: { sl@0: #ifdef SQLSRV_STARTUP_TEST sl@0: aPolicy.Package();//to prevent compiler warning sl@0: return ETrue; sl@0: #else sl@0: return aPolicy.CheckPolicy(CServer2::Message()); sl@0: #endif sl@0: } sl@0: sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: //////////////////////////////////////// MSqlSrvBurInterface implementation ////////////////////////////// sl@0: ////////////////////////////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: Implements MSqlSrvBurInterface::Fs(). sl@0: sl@0: @return A reference to the file session instance. sl@0: */ sl@0: RFs& CSqlServer::Fs() sl@0: { sl@0: return iFileData.Fs(); sl@0: } sl@0: sl@0: /** sl@0: Implements MSqlSrvBurInterface::GetBackupListL(). sl@0: Retrieves in aFileNameList parameter a list of secure database names (full database names, including path) sl@0: which security UID matches aUid parameter. sl@0: No databases will be included into the list, if the drive is read-only. sl@0: sl@0: @param aUid Database security UID. sl@0: @param aDrive The drive where the database search will be performed, in the SQL server private data cage. sl@0: @param aFileNameList An output parameter. sl@0: Each array entry represents the full name of a database in SQL server private data cage sl@0: on the specified drive (aDrive), which uid matches the aUid parameter. sl@0: sl@0: @leave KErrNoMemory, an out of memory condition has occured; sl@0: Note that the function may leave also with some other database specific or OS specific sl@0: error codes. sl@0: */ sl@0: void CSqlServer::GetBackUpListL(TSecureId aUid, TDriveNumber aDrive, RArray& aFileNameList) sl@0: { sl@0: 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)); sl@0: __ASSERT_DEBUG(aFileNameList.Count() == 0, __SQLPANIC(ESqlPanicBadArgument)); sl@0: RFs& fs = iFileData.Fs(); sl@0: //No files in the list if aDrive is a read-only drive sl@0: TDriveInfo driveInfo; sl@0: __SQLLEAVE_IF_ERROR(fs.Drive(driveInfo, aDrive)); sl@0: if(driveInfo.iDriveAtt & KDriveAttRom) sl@0: { sl@0: return; sl@0: } sl@0: //Compose the search path sl@0: TDriveUnit driveUnit(aDrive); sl@0: TDriveName driveName = driveUnit.Name(); sl@0: TFileName path; sl@0: path.Copy(driveName); sl@0: path.Append(iFileData.PrivatePath()); sl@0: //Include the aUid and the "*" mask sl@0: TUidName uidName = (static_cast (aUid)).Name(); sl@0: TBuf fileNameMask(uidName); sl@0: fileNameMask.Append(KMatchAllDbFiles); sl@0: TParse parse; sl@0: __SQLLEAVE_IF_ERROR(parse.Set(path, &fileNameMask, NULL)); sl@0: //Do the search sl@0: TPtrC fullPath(parse.FullName()); sl@0: SQL_TRACE_INTERNALS(OstTraceExt2(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL_FULLPATH, "Exit;0x%x;CSqlServer::GetBackUpListL;fullPath=%S", (TUint)this, __SQLPRNSTR(fullPath))); sl@0: CDir* fileNameCol = NULL; sl@0: TInt err = fs.GetDir(fullPath, KEntryAttNormal, ESortNone, fileNameCol); sl@0: if(err == KErrNotFound) sl@0: { sl@0: __ASSERT_DEBUG(!fileNameCol, __SQLPANIC(ESqlPanicInternalError)); sl@0: SQL_TRACE_INTERNALS(OstTrace1(TRACE_INTERNALS, CSQLSERVER_GETBACKUPLISTL_EXIT1, "Exit;0x%x;CSqlServer::GetBackUpListL;no files found", (TUint)this)); sl@0: return; sl@0: } sl@0: __SQLLEAVE_IF_ERROR(err); sl@0: __ASSERT_DEBUG(fileNameCol != NULL, __SQLPANIC(ESqlPanicInternalError)); sl@0: CleanupStack::PushL(fileNameCol); sl@0: TInt fileCount = fileNameCol->Count(); sl@0: __SQLLEAVE_IF_ERROR(aFileNameList.Reserve(fileCount)); sl@0: //Append the full database file paths to the file names list. sl@0: for(TInt i=0;i