os/persistentdata/persistentstorage/sql/OsLayer/os_symbian.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sql/OsLayer/os_symbian.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2772 @@
     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 +// The Symbian OS porting layer - single-threaded implementation.
    1.18 +// SQLite never accesses the file system and the OS services directly.
    1.19 +// SQLite uses for that sqlite3_vfs and sqlite3_file objects.
    1.20 +// sqlite3_vfs and sqlite3_file functionality is implemented in this file - 
    1.21 +// TVfs and TFileIo classes.
    1.22 +// This file is also used for the COsLayerData implementation. A single COslayerData
    1.23 +// object is used by the OS porting layer for managing some global data.
    1.24 +// 
    1.25 +//
    1.26 +
    1.27 +/**
    1.28 + @file
    1.29 + @see TVfs
    1.30 + @see TFileIo
    1.31 +*/
    1.32 +
    1.33 +#ifdef  SQLITE_OS_SYMBIAN
    1.34 +
    1.35 +//#define _SQLPROFILER // Enable profiling //The same macro has to be enabled in SqlAssert.h file
    1.36 +
    1.37 +extern "C" 
    1.38 +{
    1.39 +#include "sqliteInt.h"
    1.40 +#include "os.h"
    1.41 +}
    1.42 +#include "os_common.h"
    1.43 +#include "SqliteSymbian.h"
    1.44 +#include "FileBuf64.h"
    1.45 +#include <e32math.h>
    1.46 +#ifdef _SQLPROFILER
    1.47 +#include <hal.h>
    1.48 +#include "../INC/SqlResourceProfiler.h"
    1.49 +#endif
    1.50 +#include "SqliteUtil.h"
    1.51 +#include "OstTraceDefinitions.h"
    1.52 +#ifdef OST_TRACE_COMPILER_IN_USE
    1.53 +#include "os_symbianTraces.h"
    1.54 +#endif
    1.55 +#include "SqliteTraceDef.h"
    1.56 +
    1.57 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.58 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.59 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.60 +
    1.61 +//The SQLite temp files willl be created in this subdir
    1.62 +_LIT(KTempFileDir, "temp");
    1.63 +
    1.64 +//Bit-mask constant. If xOpen()'s "aFlag" parameter contains one of these bits set, then the the file top be
    1.65 +//opened or created is a journal file.
    1.66 +const TUint KJournalFileTypeBitMask = SQLITE_OPEN_MAIN_JOURNAL | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL; 
    1.67 +
    1.68 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.69 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.70 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1.71 +#ifdef _SQLPROFILER
    1.72 +
    1.73 +    //Profiling counters, defined in SqlSrvResourceprofiler.cpp
    1.74 +    extern TInt TheSqlSrvProfilerFileRead;
    1.75 +    extern TInt TheSqlSrvProfilerFileWrite;
    1.76 +    extern TInt TheSqlSrvProfilerFileSync;
    1.77 +    extern TInt TheSqlSrvProfilerFileSetSize;
    1.78 +    
    1.79 +#   define  __COUNTER_INCR(counter) ++counter
    1.80 +
    1.81 +	//////////////////////////////////////////////////////////////////////////////
    1.82 +	////////////////////////// File I/O //////////////////////////////////////////
    1.83 +	//////////////////////////////////////////////////////////////////////////////
    1.84 +	
    1.85 +	/**
    1.86 +	This enum is used only in _SQLPROFILER mode for tracing the file system calls.
    1.87 +	@internalComponent
    1.88 +	@see FsCallBrkPt()
    1.89 +	*/
    1.90 +	enum TFsOpType
    1.91 +		{
    1.92 +		EFsOpFileCreate,
    1.93 +		EFsOpFileOpen,
    1.94 +		EFsOpFileClose,
    1.95 +		EFsOpFileDelete,
    1.96 +		EFsOpFileRead,
    1.97 +		EFsOpFileWrite,
    1.98 +		EFsOpFileSeek,
    1.99 +		EFsOpFileSize,
   1.100 +		EFsOpFileSetSize,
   1.101 +		EFsOpFileSync,
   1.102 +		EFsOpFileDrive,
   1.103 +		EFsOpFileAdopt,
   1.104 +		EFsOpFsClose,
   1.105 +		EFsOpFsConnect,
   1.106 +		EFsOpFsGetSystemDrive,
   1.107 +		EFsOpFsCreatePrivatePath,
   1.108 +		EFsOpFsPrivatePath,
   1.109 +		EFsOpFsVolumeIoParam,
   1.110 +		EFsOpFsEntry,
   1.111 +		EFsOpFsAtt,
   1.112 +		EFsOpFileCreateTemp,
   1.113 +		EFsOpFileAttach,
   1.114 +		//
   1.115 +		EFsOpLast
   1.116 +		};
   1.117 +
   1.118 +	TBool   TheFileIoProfileEnabled = EFalse;
   1.119 +	TUint32 TheFileOpCounter[EFsOpLast] = {0};
   1.120 +	TInt64	TheFileWriteAmount = 0;
   1.121 +	TInt64	TheFileReadAmount = 0;
   1.122 +			
   1.123 +	/**
   1.124 +	This function is used only in _SQLPROFILER mode as an appropriate place for:
   1.125 +	 	- setting breakpoints for tracing the file system calls;
   1.126 +	 	- collection information about the number of the file system calls;
   1.127 +	 	
   1.128 +	@param aFsOpType A TFsOpType enum item value, identifying the file system operation that will be executed;
   1.129 +	@param a1 If the operation is "file read" or "file write" - the amount of data read/written;
   1.130 +	
   1.131 +	@internalComponent
   1.132 +	
   1.133 +	@see TFsOpType
   1.134 +	*/
   1.135 +	void FsCallBrkPt(TInt aFsOpType, TInt a1)
   1.136 +		{
   1.137 +		__ASSERT_DEBUG(aFsOpType >= 0 && aFsOpType < EFsOpLast, User::Invariant());
   1.138 +		if(!TheFileIoProfileEnabled)
   1.139 +			{
   1.140 +			return;	
   1.141 +			}
   1.142 +		TFsOpType fsOpType = (TFsOpType)aFsOpType;
   1.143 +		++TheFileOpCounter[fsOpType];
   1.144 +		if(fsOpType == EFsOpFileWrite)
   1.145 +			{
   1.146 +			TheFileWriteAmount += a1;
   1.147 +			}
   1.148 +		else if(fsOpType == EFsOpFileRead)
   1.149 +			{
   1.150 +			TheFileReadAmount += a1;
   1.151 +			}
   1.152 +		}
   1.153 +		
   1.154 +#	define __FS_CALL(aFsOpType, a1) FsCallBrkPt(aFsOpType, a1)
   1.155 +
   1.156 +	//////////////////////////////////////////////////////////////////////////////
   1.157 +	////////////////////////// Heap Stats ////////////////////////////////////////
   1.158 +	//////////////////////////////////////////////////////////////////////////////
   1.159 +
   1.160 +	/**
   1.161 +	Memory operation type: alloc, realloc, free. Used during the profiling.
   1.162 +	
   1.163 +	@internalComponent
   1.164 +	*/
   1.165 +	enum TMemOpType
   1.166 +		{
   1.167 +		EMemOpAlloc,
   1.168 +		EMemOpRealloc,
   1.169 +		EMemOpFree,
   1.170 +		//
   1.171 +		EMemOpLast
   1.172 +		};
   1.173 +
   1.174 +	TBool   TheMemProfileEnabled = EFalse;//Mem operation call counters and time counters enabled/disabled
   1.175 +	TBool   TheMaxAllocProfileEnabled = EFalse;//Max mem allocation enabled/disabled
   1.176 +	TUint32 TheMemOpCounter[EMemOpLast] = {0};
   1.177 +	TInt64 	TheMemOpTicks[EMemOpLast] = {0};
   1.178 +	TInt64 	TheAllocated = 0;
   1.179 +	TInt64 	TheFreed = 0;
   1.180 +	TInt	TheAllocMax = 0;
   1.181 +		
   1.182 +	/**
   1.183 +	This class is used only in _SQLPROFILER mode as an appropriate place for:
   1.184 +	 	- setting breakpoints for tracing the memory allocation/deallocation calls;
   1.185 +	 	- collection information about the number of the memory allocation/deallocation calls and the time spent in the calls;
   1.186 +	 	
   1.187 +	The constructor's parameters are:	 	
   1.188 +	 - aOpType A TMemOpType enum item value, identifying the operation that will be executed;
   1.189 +	 - aAmt1 The allocated/deallocated size;
   1.190 +	 - aAmt2 Used only if a block of memory is reallocated in which case a2 is the old size of the block;
   1.191 +	
   1.192 +	@internalComponent
   1.193 +	
   1.194 +	@see TMemOpType
   1.195 +	*/
   1.196 +	class TMemCallCounter
   1.197 +		{
   1.198 +	public:			
   1.199 +		TMemCallCounter(TMemOpType aOpType, TInt aAmt1, TInt aAmt2) :
   1.200 +			iOpType(aOpType),
   1.201 +			iStartTicks(0)
   1.202 +			{
   1.203 +			if(TheMaxAllocProfileEnabled && (iOpType == EMemOpAlloc || iOpType == EMemOpRealloc) && aAmt1 > TheAllocMax)
   1.204 +				{
   1.205 +				TheAllocMax = aAmt1;	
   1.206 +				}
   1.207 +			if(TheMemProfileEnabled)
   1.208 +				{
   1.209 +				++TheMemOpCounter[iOpType];
   1.210 +				switch(iOpType)
   1.211 +					{
   1.212 +					case EMemOpAlloc:
   1.213 +						TheAllocated += aAmt1;
   1.214 +						break;
   1.215 +					case EMemOpRealloc:
   1.216 +						TheAllocated += aAmt1;
   1.217 +						TheFreed += aAmt2;
   1.218 +						break;
   1.219 +					case EMemOpFree:
   1.220 +						TheFreed += aAmt1;
   1.221 +						break;
   1.222 +					default:
   1.223 +						__ASSERT_DEBUG(0, User::Invariant());
   1.224 +						break;
   1.225 +					}
   1.226 +				iStartTicks = User::FastCounter();
   1.227 +				}
   1.228 +			}
   1.229 +		~TMemCallCounter()
   1.230 +			{
   1.231 +			if(TheMemProfileEnabled)
   1.232 +				{
   1.233 +				TInt64 diffTicks = (TInt64)User::FastCounter() - (TInt64)iStartTicks;
   1.234 +				if(diffTicks < 0)
   1.235 +					{
   1.236 +					diffTicks = KMaxTUint + diffTicks + 1;
   1.237 +					}
   1.238 +				TheMemOpTicks[iOpType] += diffTicks;
   1.239 +				}
   1.240 +			}
   1.241 +	private:
   1.242 +		TMemOpType	iOpType;
   1.243 +		TUint32 	iStartTicks;
   1.244 +		};
   1.245 +		
   1.246 +#	define __MEM_CALL(aMemOpType, a1, a2) TMemCallCounter memCallCounter(aMemOpType, a1, a2)
   1.247 +
   1.248 +	//////////////////////////////////////////////////////////////////////////////
   1.249 +	////////////////////////// OS layer calls ////////////////////////////////////
   1.250 +	//////////////////////////////////////////////////////////////////////////////
   1.251 +	
   1.252 +	//The OS porting layer call types
   1.253 +	enum TOsOpType
   1.254 +		{
   1.255 +		EOsFileClose,
   1.256 +		EOsFileRead,
   1.257 +		EOsFileWrite,
   1.258 +		EOsFileTruncate,
   1.259 +		EOsFileSync,
   1.260 +		EOsFileFileSize,
   1.261 +		EOsFileLock,
   1.262 +		EOsFileUnlock,
   1.263 +		EOsFileCheckReservedLock,
   1.264 +		EOsFileFileControl,
   1.265 +		EOsFileSectorSize,
   1.266 +		EOsFileDeviceCharacteristics,
   1.267 +		//
   1.268 +		EOsVfsOpen,
   1.269 +		EOsVfsDelete,
   1.270 +		EOsVfsAccess,
   1.271 +		EOsVfsFullPathName,
   1.272 +		EOsVfsRandomness,
   1.273 +		EOsVfsSleep,
   1.274 +		EOsVfsCurrentTime,
   1.275 +		EOsVfsGetLastError,
   1.276 +		//
   1.277 +		EOsOpLast
   1.278 +		};
   1.279 +	
   1.280 +	TBool   TheOsProfileEnabled = EFalse;
   1.281 +	TUint32 TheOsOpCounter[EOsOpLast] = {0};//Each entry is a counter - how many times specific OS porting layer function has been called
   1.282 +	
   1.283 +#	define __OS_CALL(aOsOpType, a1, a2) 		\
   1.284 +			do									\
   1.285 +				{								\
   1.286 +				if(TheOsProfileEnabled) 		\
   1.287 +					{							\
   1.288 +					++TheOsOpCounter[aOsOpType];\
   1.289 +					}							\
   1.290 +				}								\
   1.291 +			while(0)				
   1.292 +			
   1.293 +	//////////////////////////////////////////////////////////////////////////////
   1.294 +	////////////////////////// OS layer timings //////////////////////////////////
   1.295 +	//////////////////////////////////////////////////////////////////////////////
   1.296 +
   1.297 +	TBool  TheOsCallTimeProfileEnabled = EFalse;//If true, the OS porting layer call timings are enabled.
   1.298 +	TInt64 TheOsCallTicks[EOsOpLast];//Each entry represents the time in ticks spent in a specific OS porting layer function,
   1.299 +									 //disregarding the file type (main or journal)
   1.300 +	
   1.301 +	TBool  TheOsCallTimeDetailedProfileEnabled = EFalse;//If true, the OS porting layer call details are enabled and for each call an entry will be added to the log file (epocwind.out).
   1.302 +	TInt   TheOpCounter = 0;//Operations counter. Each OS porting layer function call increments the counter.
   1.303 +	
   1.304 +	//Used for storing the OS call details:
   1.305 +	// - iType        - on which file the call has been made: main database file - 'M', or journal file - 'J';
   1.306 +	// - iIdentifier  - two letters identifying the monitored OS porting layer function;
   1.307 +	// - iCallCounter - how many times the monitored OS porting layer function has been called;	
   1.308 +	// - iTicksTotal  - the total amount of time in ticks spent in the monitored OS porting layer function;	
   1.309 +	// - iBytesTotal  - the total amount of bytes passed to the monitored OS porting layer function (if it is read or write);
   1.310 +	struct TOsCallProfile
   1.311 +		{
   1.312 +		TOsCallProfile(char aType, const TDesC& aIdentifier) :
   1.313 +			iType(aType),
   1.314 +			iIdentifier(aIdentifier),
   1.315 +			iCallCounter(0),
   1.316 +			iTicksTotal(0),
   1.317 +			iBytesTotal(0)
   1.318 +			{
   1.319 +			}
   1.320 +		void Zero()
   1.321 +			{
   1.322 +			iCallCounter = 0;	
   1.323 +			iTicksTotal = 0;	
   1.324 +			iBytesTotal = 0;
   1.325 +			}
   1.326 +		char	iType;
   1.327 +		TBuf<32> iIdentifier;
   1.328 +		TInt	iCallCounter;
   1.329 +		TInt64	iTicksTotal;
   1.330 +		TInt64	iBytesTotal;
   1.331 +		};
   1.332 +
   1.333 +	//An array of TOsCallProfile entries, each entry keeps the profile of a specifc OS porting layer function, when
   1.334 +	//the function was used on the main database file
   1.335 +	TOsCallProfile TheOsCallMProfile[EOsOpLast] = 
   1.336 +		{
   1.337 +		TOsCallProfile('M', _L("Close")), TOsCallProfile('M', _L("Read")), TOsCallProfile('M', _L("Write")), TOsCallProfile('M', _L("Truncate")),
   1.338 +		TOsCallProfile('M', _L("Sync")), TOsCallProfile('M', _L("Size")), TOsCallProfile('M', _L("Lock")), TOsCallProfile('M', _L("Unlock")),
   1.339 +		TOsCallProfile('M', _L("CheckReservedLock")), TOsCallProfile('M', _L("FileControl")), TOsCallProfile('M', _L("SetSize")), TOsCallProfile('M', _L("DeviceCharacteristics")),
   1.340 +		TOsCallProfile('M', _L("Open")), TOsCallProfile('M', _L("Delete")), TOsCallProfile('M', _L("Access")), TOsCallProfile('M', _L("FullPath")),
   1.341 +		TOsCallProfile('M', _L("Randomness")), TOsCallProfile('M', _L("Sleep")), TOsCallProfile('M', _L("CurrentTime")), TOsCallProfile('M', _L("GetLastError"))
   1.342 +		};
   1.343 +
   1.344 +	//An array of TOsCallProfile entries, each entry keeps the profile of a specifc OS porting layer function, when
   1.345 +	//the function was used on the journal file
   1.346 +	TOsCallProfile TheOsCallJProfile[EOsOpLast] = 
   1.347 +		{
   1.348 +		TOsCallProfile('J', _L("Close")), TOsCallProfile('J', _L("Read")), TOsCallProfile('J', _L("Write")), TOsCallProfile('J', _L("Truncate")),
   1.349 +		TOsCallProfile('J', _L("Sync")), TOsCallProfile('J', _L("Size")), TOsCallProfile('J', _L("Lock")), TOsCallProfile('J', _L("Unlock")),
   1.350 +		TOsCallProfile('J', _L("CheckReservedLock")), TOsCallProfile('J', _L("FileControl")), TOsCallProfile('J', _L("SetSize")), TOsCallProfile('J', _L("DeviceCharacteristics")),
   1.351 +		TOsCallProfile('J', _L("Open")), TOsCallProfile('J', _L("Delete")), TOsCallProfile('J', _L("Access")), TOsCallProfile('J', _L("FullPath")),
   1.352 +		TOsCallProfile('J', _L("Randomness")), TOsCallProfile('J', _L("Sleep")), TOsCallProfile('J', _L("CurrentTime")), TOsCallProfile('J', _L("GetLastError"))
   1.353 +		};
   1.354 +	
   1.355 +	//The main class for the OS porting layer call profiles.
   1.356 +	class TOsCallCounter
   1.357 +		{
   1.358 +	public:
   1.359 +		//aOsCallTicksEntryRef - a reference to the related TheOsCallTicks[] entry;
   1.360 +		//aProfileRef          - a reference to the related TOsCallProfile object - TheOsCallMProfile[] or TheOsCallJProfile[] entry;
   1.361 +		//aOffset              - file offset in bytes;
   1.362 +		//aBytes               - amount of bytes to be read/written;
   1.363 +		//aOptional			   - might be NULL. Used to print out the name of the file being processed.
   1.364 +		TOsCallCounter(TInt64& aOsCallTicksEntryRef, TOsCallProfile& aOsCallProfileRef, TInt64 aOffset, TInt aBytes, 
   1.365 +				       const sqlite3_file* aHandle, const char* aOptional) :
   1.366 +			iOsCallTicksEntryRef(aOsCallTicksEntryRef),
   1.367 +			iOsCallProfileRef(aOsCallProfileRef),
   1.368 +			iOffset(aOffset),
   1.369 +			iBytes(aBytes),
   1.370 +			iHandle((TUint)aHandle),
   1.371 +			iOptional((const TUint8*)aOptional)
   1.372 +			{
   1.373 +			if(TheOsCallTimeProfileEnabled)
   1.374 +				{
   1.375 +				iStartTicks = User::FastCounter();
   1.376 +				}
   1.377 +			}
   1.378 +		~TOsCallCounter()
   1.379 +			{
   1.380 +			if(TheOsCallTimeProfileEnabled)
   1.381 +				{
   1.382 +				TInt64 diffTicks = (TInt64)User::FastCounter() - (TInt64)iStartTicks;
   1.383 +				if(diffTicks < 0)
   1.384 +					{
   1.385 +					diffTicks = KMaxTUint + diffTicks + 1;
   1.386 +					}
   1.387 +				iOsCallTicksEntryRef += diffTicks;
   1.388 +				if(TheOsCallTimeDetailedProfileEnabled)
   1.389 +					{
   1.390 +					++TheOpCounter;
   1.391 +					++iOsCallProfileRef.iCallCounter;
   1.392 +					iOsCallProfileRef.iTicksTotal += diffTicks;
   1.393 +					iOsCallProfileRef.iBytesTotal += iBytes;
   1.394 +					TFileName fname;
   1.395 +					if(iOptional)
   1.396 +						{
   1.397 +						TPtrC8 fn8(iOptional);
   1.398 +						fname.Copy(fn8);
   1.399 +						}
   1.400 +					//                                           0    1  2  3  4  5   6  7   8   9   10
   1.401 +					RDebug::Print(_L("[SQL-OS]¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬\"%X\"¬%c¬%S¬%d¬%d¬%ld¬%d¬%ld¬%ld¬%ld¬%S\n"),
   1.402 +															//[SQL-OS]
   1.403 +															//Handle
   1.404 +															//Time from start, microseconds
   1.405 +															//Subtype
   1.406 +															//IPC sequence counter
   1.407 +															//IPC call name
   1.408 +					    iHandle,							//sqlite3_file*
   1.409 +						iOsCallProfileRef.iType, 			//1 - main or journal file
   1.410 +						&iOsCallProfileRef.iIdentifier, 	//2 - operation type
   1.411 +						TheOpCounter, 						//3 - Operation counter
   1.412 +						iOsCallProfileRef.iCallCounter, 	//4 - This call type counter
   1.413 +						iOffset, 							//5 - File offset
   1.414 +						iBytes, 							//6 - Data, bytes
   1.415 +						diffTicks, 							//7 - Ticks
   1.416 +						iOsCallProfileRef.iBytesTotal, 		//8 - Data total, bytes
   1.417 +						iOsCallProfileRef.iTicksTotal,		//9 - Ticks total
   1.418 +						&fname);							//10- File name
   1.419 +					}
   1.420 +				}
   1.421 +			}
   1.422 +	private:
   1.423 +		TInt64&			iOsCallTicksEntryRef;
   1.424 +		TOsCallProfile&	iOsCallProfileRef;
   1.425 +		TInt64			iOffset;
   1.426 +		TInt			iBytes;			
   1.427 +		TUint32 		iStartTicks;
   1.428 +		TUint			iHandle;
   1.429 +		const TUint8*	iOptional;
   1.430 +		};
   1.431 +		
   1.432 +	inline TOsCallProfile& OsCallProfile(TBool aType, TInt aIndex)
   1.433 +		{
   1.434 +		return aType ? TheOsCallJProfile[aIndex] : TheOsCallMProfile[aIndex];
   1.435 +		}
   1.436 +		
   1.437 +#	define __OSTIME_COUNTER(aOsCallTicksRef, aOsCallProfileRef, aOffset, aBytes, aHandle, aOpt)	TOsCallCounter osCallCounter(aOsCallTicksRef, aOsCallProfileRef, aOffset, aBytes, aHandle, aOpt)
   1.438 +
   1.439 +#else //_SQLPROFILER
   1.440 +
   1.441 +#   define __COUNTER_INCR(counter) void(0)
   1.442 +	
   1.443 +#	define __FS_CALL(aFsOpType, a1) void(0)
   1.444 +
   1.445 +#	define __MEM_CALL(aMemOpType, a1, a2) void(0)
   1.446 +
   1.447 +#	define __OS_CALL(aOpType, a1, a2) void(0)
   1.448 +
   1.449 +#	define __OSTIME_COUNTER(aOsCallTicksRef, aOsCallProfileRef, aOffset, aBytes, aHandle, aOpt)	void(0)
   1.450 +
   1.451 +#endif//_SQLPROFILER
   1.452 +
   1.453 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.454 +/////////////////////       Profiling                          ////////////////////////////////////////////////////////////////
   1.455 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.456 +
   1.457 +#ifdef _SQLPROFILER
   1.458 +
   1.459 +const TInt KMicroSecIn1Sec = 1000000;
   1.460 +
   1.461 +TInt FastCounterFrequency()
   1.462 +	{
   1.463 +	TInt ticksPerSec = 0;
   1.464 +	TInt err = HAL::Get(HAL::EFastCounterFrequency, ticksPerSec);
   1.465 +	__ASSERT_ALWAYS(err == KErrNone, __SQLITEPANIC2(ESqliteOsPanicFastCounterFreq));
   1.466 +	return ticksPerSec;
   1.467 +	}
   1.468 +
   1.469 +TInt sqlite3SymbianProfilerStart(TInt aCounterType)
   1.470 +	{
   1.471 +	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aCounterType);
   1.472 +	switch(KCounterType)
   1.473 +		{
   1.474 +		case TSqlResourceProfiler::ESqlCounterFileIO:
   1.475 +			TheFileIoProfileEnabled = ETrue;
   1.476 +			break;
   1.477 +		case TSqlResourceProfiler::ESqlCounterOsCall:
   1.478 +			TheOsProfileEnabled = ETrue;
   1.479 +			break;
   1.480 +		case TSqlResourceProfiler::ESqlCounterOsCallTime:
   1.481 +			TheOsCallTimeProfileEnabled = ETrue;
   1.482 +			break;
   1.483 +		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
   1.484 +			TheOsCallTimeProfileEnabled = ETrue;
   1.485 +			TheOsCallTimeDetailedProfileEnabled = ETrue;
   1.486 +			break;
   1.487 +		case TSqlResourceProfiler::ESqlCounterMemory:
   1.488 +			TheMemProfileEnabled = ETrue;
   1.489 +			break;
   1.490 +		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
   1.491 +			TheMaxAllocProfileEnabled = ETrue;
   1.492 +			break;
   1.493 +		default:
   1.494 +			return KErrNotSupported;
   1.495 +		}
   1.496 +	return KErrNone;
   1.497 +	}
   1.498 +	
   1.499 +TInt sqlite3SymbianProfilerStop(TInt aCounterType)
   1.500 +	{
   1.501 +	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aCounterType);
   1.502 +	switch(KCounterType)
   1.503 +		{
   1.504 +		case TSqlResourceProfiler::ESqlCounterFileIO:
   1.505 +			TheFileIoProfileEnabled = EFalse;
   1.506 +			break;
   1.507 +		case TSqlResourceProfiler::ESqlCounterOsCall:
   1.508 +			TheOsProfileEnabled = EFalse;
   1.509 +			break;
   1.510 +		case TSqlResourceProfiler::ESqlCounterOsCallTime:
   1.511 +			TheOsCallTimeProfileEnabled = EFalse;
   1.512 +			break;
   1.513 +		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
   1.514 +			TheOsCallTimeDetailedProfileEnabled = EFalse;
   1.515 +			TheOsCallTimeProfileEnabled = EFalse;
   1.516 +			break;
   1.517 +		case TSqlResourceProfiler::ESqlCounterMemory:
   1.518 +			TheMemProfileEnabled = EFalse;
   1.519 +			break;
   1.520 +		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
   1.521 +			TheMaxAllocProfileEnabled = EFalse;
   1.522 +			break;
   1.523 +		default:
   1.524 +			return KErrNotSupported;
   1.525 +		}
   1.526 +	return KErrNone;
   1.527 +	}
   1.528 +	
   1.529 +TInt sqlite3SymbianProfilerReset(TInt aCounterType)
   1.530 +	{
   1.531 +	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aCounterType);
   1.532 +	switch(KCounterType)
   1.533 +		{
   1.534 +		case TSqlResourceProfiler::ESqlCounterFileIO:
   1.535 +			Mem::FillZ(TheFileOpCounter, sizeof(TheFileOpCounter));
   1.536 +			TheFileWriteAmount = TheFileReadAmount = 0;
   1.537 +			break;
   1.538 +		case TSqlResourceProfiler::ESqlCounterOsCall:
   1.539 +			Mem::FillZ(TheOsOpCounter, sizeof(TheOsOpCounter));
   1.540 +			break;
   1.541 +		case TSqlResourceProfiler::ESqlCounterOsCallTime:
   1.542 +		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
   1.543 +			TheOpCounter = 0;
   1.544 +			Mem::FillZ(TheOsCallTicks, sizeof(TheOsCallTicks));
   1.545 +			for(TInt i=0;i<EOsOpLast;++i)
   1.546 +				{
   1.547 +				TheOsCallMProfile[i].Zero();
   1.548 +				TheOsCallJProfile[i].Zero();
   1.549 +				}
   1.550 +			break;
   1.551 +		case TSqlResourceProfiler::ESqlCounterMemory:
   1.552 +			Mem::FillZ(TheMemOpCounter, sizeof(TheMemOpCounter));
   1.553 +			Mem::FillZ(TheMemOpTicks, sizeof(TheMemOpTicks));
   1.554 +			TheAllocated = TheFreed = 0;
   1.555 +			break;
   1.556 +		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
   1.557 +			TheAllocMax = 0;
   1.558 +			break;
   1.559 +		default:
   1.560 +			return KErrNotSupported;
   1.561 +		}
   1.562 +	return KErrNone;
   1.563 +	}
   1.564 +	
   1.565 +TInt sqlite3SymbianProfilerQuery(TInt aCounterType, TDes8& aResult)
   1.566 +	{
   1.567 +	const TSqlResourceProfiler::TSqlCounter KCounterType = static_cast <TSqlResourceProfiler::TSqlCounter> (aCounterType);
   1.568 +	switch(KCounterType)
   1.569 +		{
   1.570 +		case TSqlResourceProfiler::ESqlCounterFileIO:
   1.571 +			for(TInt i=0;i<EFsOpLast;++i)
   1.572 +				{
   1.573 +				aResult.AppendNum(TheFileOpCounter[i]);
   1.574 +				aResult.Append(TChar(';'));
   1.575 +				}
   1.576 +			aResult.AppendNum(TheFileWriteAmount);
   1.577 +			aResult.Append(TChar(';'));
   1.578 +			aResult.AppendNum(TheFileReadAmount);
   1.579 +			aResult.Append(TChar(';'));
   1.580 +			break;
   1.581 +		case TSqlResourceProfiler::ESqlCounterOsCall:
   1.582 +			for(TInt i=0;i<EOsOpLast;++i)
   1.583 +				{
   1.584 +				aResult.AppendNum(TheOsOpCounter[i]);
   1.585 +				aResult.Append(TChar(';'));
   1.586 +				}
   1.587 +			break;
   1.588 +		case TSqlResourceProfiler::ESqlCounterOsCallTime:
   1.589 +		case TSqlResourceProfiler::ESqlCounterOsCallDetails:
   1.590 +			{
   1.591 +			TInt ticksPerSec = FastCounterFrequency();
   1.592 +			for(TInt i=0;i<EOsOpLast;++i)
   1.593 +				{
   1.594 +				TInt64 osCallTimeUs = (TheOsCallTicks[i] * KMicroSecIn1Sec) / ticksPerSec;
   1.595 +				aResult.AppendNum(osCallTimeUs);
   1.596 +				aResult.Append(TChar(';'));
   1.597 +				}
   1.598 +			}
   1.599 +			break;
   1.600 +		case TSqlResourceProfiler::ESqlCounterMemory:
   1.601 +			aResult.AppendNum(TheMemOpCounter[EMemOpAlloc]);
   1.602 +			aResult.Append(TChar(';'));
   1.603 +			aResult.AppendNum(TheMemOpCounter[EMemOpRealloc]);
   1.604 +			aResult.Append(TChar(';'));
   1.605 +			aResult.AppendNum(TheMemOpCounter[EMemOpFree]);
   1.606 +			aResult.Append(TChar(';'));
   1.607 +			aResult.AppendNum(TheAllocated);
   1.608 +			aResult.Append(TChar(';'));
   1.609 +			aResult.AppendNum(TheFreed);
   1.610 +			aResult.Append(TChar(';'));
   1.611 +			{
   1.612 +			TInt ticksPerSec = FastCounterFrequency();
   1.613 +			TInt64 memOpCallTimeUs = (TheMemOpTicks[EMemOpAlloc] * KMicroSecIn1Sec) / ticksPerSec;
   1.614 +			aResult.AppendNum(memOpCallTimeUs);
   1.615 +			aResult.Append(TChar(';'));
   1.616 +			memOpCallTimeUs = (TheMemOpTicks[EMemOpRealloc] * KMicroSecIn1Sec) / ticksPerSec;
   1.617 +			aResult.AppendNum(memOpCallTimeUs);
   1.618 +			aResult.Append(TChar(';'));
   1.619 +			memOpCallTimeUs = (TheMemOpTicks[EMemOpFree] * KMicroSecIn1Sec) / ticksPerSec;
   1.620 +			aResult.AppendNum(memOpCallTimeUs);
   1.621 +			aResult.Append(TChar(';'));
   1.622 +			}
   1.623 +			break;
   1.624 +		case TSqlResourceProfiler::ESqlCounterMaxAlloc:
   1.625 +			aResult.AppendNum(TheAllocMax);
   1.626 +			aResult.Append(TChar(';'));
   1.627 +			break;
   1.628 +		default:
   1.629 +			return KErrNotSupported;
   1.630 +		}
   1.631 +	return KErrNone;
   1.632 +	}
   1.633 +	
   1.634 +#else//_SQLPROFILER	
   1.635 +
   1.636 +TInt sqlite3SymbianProfilerStart(TInt)
   1.637 +	{
   1.638 +	return KErrNotSupported;	
   1.639 +	}
   1.640 +
   1.641 +TInt sqlite3SymbianProfilerStop(TInt)
   1.642 +	{
   1.643 +	return KErrNotSupported;	
   1.644 +	}
   1.645 +
   1.646 +TInt sqlite3SymbianProfilerReset(TInt)
   1.647 +	{
   1.648 +	return KErrNotSupported;	
   1.649 +	}
   1.650 +
   1.651 +TInt sqlite3SymbianProfilerQuery(TInt, TDes8&)
   1.652 +	{
   1.653 +	return KErrNotSupported;	
   1.654 +	}
   1.655 +
   1.656 +#endif//_SQLPROFILER
   1.657 +
   1.658 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.659 +
   1.660 +/**
   1.661 +Os2SqliteErr() is called at the end of many of the interface functions of the OS porting layer (wherever it is appropriate - 
   1.662 +TFileIo and TVfs interfaces). The purpose of this function is to identify the "out of memory" and "disk is full" errors
   1.663 +reported by the used Symbian OS APIs (aOsErr parameter) and report them to SQLite as SQLITE_FULL and SQLITE_NOMEM errors.
   1.664 +The KErrEof error (TFileIo::Read() can return KErrEof) is reported to SQLite as SQLITE_IOERR_SHORT_READ. The rest of failures
   1.665 +are reported as the error specified in aDefaultErr parameter.
   1.666 + 
   1.667 +@param aOsErr      Symbian OS error
   1.668 +@param aDefaultErr The default SQLite error that should be used if the aOsErr parameter is not one of:
   1.669 +                     KErrNone, KErrEof, KErrNoMemory, KErrDiskFull
   1.670 +@return SQLITE_OK,               The OS porting layer function call has completed successfully, 
   1.671 +          SQLITE_IOERR_SHORT_READ, The amount of the data read is less than the requested amount,
   1.672 +          SQLITE_IOERR_NOMEM,      Out of memory,
   1.673 +          SQLITE_FULL,             The disk is full,
   1.674 +          aDefaultErr,             The rest of failures will be reported as aDefaultErr.
   1.675 +*/
   1.676 +static TInt Os2SqliteErr(TInt aOsErr, TInt aDefaultErr)
   1.677 +	{
   1.678 +	switch(aOsErr)
   1.679 +		{
   1.680 +		case KErrNone:
   1.681 +			return SQLITE_OK;	
   1.682 +		case KErrEof:
   1.683 +			return SQLITE_IOERR_SHORT_READ;
   1.684 +		case KErrNoMemory:
   1.685 +			return SQLITE_IOERR_NOMEM;
   1.686 +		case KErrDiskFull:
   1.687 +			return SQLITE_FULL;
   1.688 +		default:
   1.689 +#ifdef _DEBUG		
   1.690 +			RDebug::Print(_L("SQLite OS porting layer, Os2SqliteErr(), err=%d\n"), aOsErr);
   1.691 +			SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, OS2SQLITEERR, "OS;0;Os2SqliteErr;aOsErr=%d", aOsErr));
   1.692 +#endif			
   1.693 +			break;
   1.694 +		}
   1.695 +	return aDefaultErr;
   1.696 +	}
   1.697 +	
   1.698 +
   1.699 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.700 +/////////////////////       COsLayerData class declaration   //////////////////////////////////////////////////////////////////
   1.701 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.702 +
   1.703 +/**
   1.704 +COsLayerData singleton class manages a single SQLite OS layer copy of the following data: 
   1.705 +@code
   1.706 + - file session instance;
   1.707 + - process's private data path, where the temporary file will be stored (on the system drive);
   1.708 + - the last OS error code, every Symbian OS API call (file system calls, etc.) will set it;
   1.709 + - the stored OS error code, initialized with the last OS error code only if stored OS error code is KErrNone.
   1.710 +	Each StoredOsErrorCode() call will reset it to KErrNone;
   1.711 +	The reason of having two data members for storing the OS error codes is that if there is just one variable
   1.712 +	and it gets initialized with the error value reported by a failed OS API call, the next successful OS API
   1.713 +	call will reset it and the COsLayerData client will miss the last "real" OS API error.
   1.714 + - A pointer to the current RMessage2 object, if the current operation is "open a private secure database";
   1.715 + - A boolean flag - iReadOnly - used only for private secure databases, indicating whether the database is read-only or not;
   1.716 +@endcode
   1.717 +
   1.718 +@internalComponent
   1.719 +*/
   1.720 +NONSHARABLE_CLASS(COsLayerData)
   1.721 +	{
   1.722 +public:	
   1.723 +	static TInt Create();
   1.724 +	static inline void Destroy();
   1.725 +	static inline COsLayerData& Instance();
   1.726 +	
   1.727 +	inline TInt SetOsErrorCode(TInt aError);
   1.728 +	inline TInt StoredOsErrorCode();
   1.729 +	
   1.730 +	inline void StoreFhData(const RMessage2* aMsg, TBool aReadOnly);
   1.731 +	inline void RetrieveAndResetFhData(const RMessage2*& aMsg, TBool& aReadOnly);
   1.732 +	
   1.733 +private:
   1.734 +	inline COsLayerData();
   1.735 +	inline ~COsLayerData();
   1.736 +	TInt DoCreate();
   1.737 +	
   1.738 +public:
   1.739 +	RFs			iFs;		//File session instance.
   1.740 +	TFileName	iSysPrivDir;//"<system drive>:\" + process's private data path. Initialized in sqlite3SymbianFsOpen().
   1.741 +	TInt64		iSeed;
   1.742 +
   1.743 +private:	
   1.744 +	static COsLayerData* 	iOsLayerData;
   1.745 +	TInt					iStoredOsErrorCode;	//Contains the last OS error code.
   1.746 +	const RMessage2* 		iMessage;			//Fh data
   1.747 +	TBool					iReadOnly;			//Fh data
   1.748 +	};
   1.749 +
   1.750 +/**
   1.751 +This functon returns a reference to the current thread allocator object.
   1.752 +The static RAllocator& variable will be initialized once at the moment when the function is called for 
   1.753 +first time. 
   1.754 +*/
   1.755 +static RAllocator& Allocator()
   1.756 +    {
   1.757 +    static RAllocator& allocator = User::Allocator();
   1.758 +    return allocator;
   1.759 +    }
   1.760 +
   1.761 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.762 +///////////////////////////////////       TDbFile struct declaration      /////////////////////////////////////////////////////
   1.763 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.764 +
   1.765 +/**
   1.766 +TDbFile derives from the sqlite3_file structure, adding data members needed for processing the SQLite requests to the OS layer.
   1.767 +When SQLite needs an access to a file, SQLite allocates memory for a new TDbFile instance and passes a pointer to that 
   1.768 +instance to TVfs::Open(). TVfs::Open() creates/opens the file and initializes the TDbFile instance. 
   1.769 +SQLite uses the initialized TDbFile instance (actually SQLite knows and uses the sqlite3_file, the base structure) 
   1.770 +every time when needs to read or write from/to the file, using for that an appropriate TFileIo method.
   1.771 +
   1.772 +Note: currently RFileBuf64 object is used instead of RFile64. That improves the read/write file performance.
   1.773 +
   1.774 +No virtual methods here! sqlite3_file contains data members. If a virtual method is added, that will shift the offset of the
   1.775 +data members from the beginning of the sqlite3_file  object by 4 bytes. This is not what SQLite (C code) expects.
   1.776 +
   1.777 +@internalComponent
   1.778 +
   1.779 +@see TVfs
   1.780 +@see TFileIo
   1.781 +@see TVfs::Open()
   1.782 +*/
   1.783 +NONSHARABLE_STRUCT(TDbFile) : public sqlite3_file 
   1.784 +	{
   1.785 +	inline TDbFile();
   1.786 +	RFileBuf64	iFileBuf;
   1.787 +	TInt		iLockType;				//File lock type
   1.788 +	TBool		iReadOnly;				//True if the file is read-only
   1.789 +	TInt		iSectorSize;			//Media sector-size
   1.790 +	TInt		iDeviceCharacteristics;
   1.791 +	TSqlFreePageCallback iFreePageCallback;
   1.792 +	TBool       iIsFileCreated;          //If the file to be created is a temp file, 
   1.793 +                                       //it will not be created until the data is to be written to.
   1.794 +#ifdef _SQLPROFILER
   1.795 +	TBool		iIsJournal;
   1.796 +#endif	
   1.797 +	};
   1.798 +
   1.799 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.800 +///////////////////////////////////       TFileIo class declaration      //////////////////////////////////////////////////////
   1.801 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.802 +
   1.803 +/**
   1.804 +TFileIo class offers static methods for performing operations on a file.
   1.805 +Every TFileIo method has a pointer to a sqlite3_file instance (so, a TDbFile instance) as its first argument.
   1.806 +
   1.807 +SQLite never accesses the file system directly, only through function pointers, data members of the sqlite3_io_methods structure.
   1.808 +The OS porting layer defines a single instance of sqlite3_io_methods structure, TheFileIoApi, and uses the TFileIo to initialize the 
   1.809 +sqlite3_io_methods data members (function pointers).
   1.810 +Every time when SQLite creates/opens a file using TVfs::Open(), TVfs::Open() will pass back to SQLite a pointer to the single
   1.811 +initialized sqlite3_io_methods instance (TheFileIoApi) that will be used later by SQLite for accessing the file.
   1.812 +
   1.813 +@internalComponent
   1.814 +
   1.815 +@see TVfs
   1.816 +@see TVfs::Open()
   1.817 +@see TheFileIoApi
   1.818 +@see TDbFile
   1.819 +*/
   1.820 +NONSHARABLE_CLASS(TFileIo)
   1.821 +	{
   1.822 +public:	
   1.823 +	static int Close(sqlite3_file* aDbFile);
   1.824 +	static int Read(sqlite3_file* aDbFile, void* aBuf, int aAmt, sqlite3_int64 aOffset);
   1.825 +	static int Write(sqlite3_file* aDbFile, const void* aData, int aAmt, sqlite3_int64 aOffset);
   1.826 +	static int Truncate(sqlite3_file* aDbFile, sqlite3_int64 aLength);
   1.827 +	static int Sync(sqlite3_file* aDbFile, int aFlags);
   1.828 +	static int FileSize(sqlite3_file* aDbFile, sqlite3_int64* aSize);
   1.829 +	static int Lock(sqlite3_file* aDbFile, int aLockType);
   1.830 +	static int Unlock(sqlite3_file* aDbFile, int aLockType);
   1.831 +	static int CheckReservedLock(sqlite3_file* aDbFile, int *aResOut);
   1.832 +	static int FileControl(sqlite3_file* aDbFile, int aOp, void* aArg);
   1.833 +	static int SectorSize(sqlite3_file* aDbFile);
   1.834 +	static int DeviceCharacteristics(sqlite3_file* aDbFile);
   1.835 +private:
   1.836 +	static TInt DoCreateTempFile(TDbFile& aDbFile);
   1.837 +	};
   1.838 +
   1.839 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.840 +///////////////////////////////////       TVfs class declaration      /////////////////////////////////////////////////////////
   1.841 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.842 +
   1.843 +/**
   1.844 +TVfs ("VFS" - virtual file system) class offers methods for creating/openning a file, deleting a file,
   1.845 +a "sleep" method, a "time" method, a "rand" method, etc.
   1.846 +SQLite never accesses the OS API directly, only through the API offered by TVfs and TFileIo classes.
   1.847 +
   1.848 +@internalComponent
   1.849 +
   1.850 +@see TFileIo
   1.851 +@see TheVfsApi
   1.852 +@see COsLayerData
   1.853 +*/
   1.854 +NONSHARABLE_CLASS(TVfs)
   1.855 +	{
   1.856 +public:		
   1.857 +	static int Open(sqlite3_vfs* aVfs, const char* aFileName, sqlite3_file* aDbFile, int aFlags, int* aOutFlags);
   1.858 +	static int Delete(sqlite3_vfs* aVfs, const char* aFileName, int aSyncDir);	
   1.859 +	static int Access(sqlite3_vfs* aVfs, const char* aFileName, int aFlags, int* aResOut);
   1.860 +	static int FullPathName(sqlite3_vfs* aVfs, const char* aRelative, int aBufLen, char* aBuf);
   1.861 +	static int Randomness(sqlite3_vfs* aVfs, int aBufLen, char* aBuf);
   1.862 +	static int Sleep(sqlite3_vfs* aVfs, int aMicrosec);
   1.863 +	static int CurrentTime(sqlite3_vfs* aVfs, double* aNow);
   1.864 +	static int GetLastError(sqlite3_vfs *sVfs, int aBufLen, char* aBuf);
   1.865 +	static TInt DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize);
   1.866 +private:
   1.867 +	static TInt DoOpenFromHandle(TDbFile& aDbFile, const RMessage2& aMsg, TBool aReadOnly);
   1.868 +	static inline TInt DoGetVolumeIoParamInfo(RFs& aFs, TInt aDriveNo, TVolumeIOParamInfo& aVolumeInfo);
   1.869 +	static TInt DoGetDeviceCharacteristics(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   1.870 +	static TInt DoGetSectorSize(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo);
   1.871 +	static TInt DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode);
   1.872 +	};
   1.873 +
   1.874 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.875 +/////////////////////       Global variables, constants    ////////////////////////////////////////////////////////////////////
   1.876 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.877 +
   1.878 +// The following macro specifies the size of the RFileBuf64 file buffer in KB:
   1.879 +//    __SQLITE_OS_SYMBIAN_FILEBUF_KBSIZE__
   1.880 +// 
   1.881 +// If not set, a default value of 8 is used	
   1.882 +#if !defined(__SQLITE_OS_SYMBIAN_FILEBUF_KBSIZE__)
   1.883 +#define __SQLITE_OS_SYMBIAN_FILEBUF_KBSIZE__ 8
   1.884 +#endif	
   1.885 +const TInt KFileBufSize = __SQLITE_OS_SYMBIAN_FILEBUF_KBSIZE__ * 1024;	
   1.886 +
   1.887 +/**
   1.888 +Pointer to the single COsLayerData instance.
   1.889 +
   1.890 +@see COsLayerData
   1.891 +
   1.892 +@internalComponent
   1.893 +*/
   1.894 +COsLayerData* COsLayerData::iOsLayerData = NULL;
   1.895 +
   1.896 +/**
   1.897 +Single sqlite3_io_methods instance, which data members (function pointers) are initialized with the addresses of
   1.898 +TFileIo members. 
   1.899 +TheFileIoApi is used by SQLite for performing OS independent file I/O.
   1.900 +
   1.901 +@see TFileIo
   1.902 +@see TVfs
   1.903 +
   1.904 +@internalComponent
   1.905 +*/
   1.906 +static sqlite3_io_methods TheFileIoApi = 
   1.907 +	{
   1.908 +	1,						//Version
   1.909 +	&TFileIo::Close,
   1.910 +	&TFileIo::Read,
   1.911 +	&TFileIo::Write,
   1.912 +	&TFileIo::Truncate,
   1.913 +	&TFileIo::Sync,
   1.914 +	&TFileIo::FileSize,
   1.915 +	&TFileIo::Lock,
   1.916 +	&TFileIo::Unlock,
   1.917 +	&TFileIo::CheckReservedLock,
   1.918 +	&TFileIo::FileControl,
   1.919 +	&TFileIo::SectorSize,
   1.920 +	&TFileIo::DeviceCharacteristics
   1.921 +	};
   1.922 +
   1.923 +/**
   1.924 +Single sqlite3_vfs instance, which data members (function pointers) are initialized with the addresses of
   1.925 +TVfs members. TheVfsApi also keeps information regarding some other OS dependend characteristics like 
   1.926 +the TDbFile size and max file name length.
   1.927 +TheVfsApi is used by SQLite for accessing needed OS API.
   1.928 +
   1.929 +TheVfsApi can't be a constant definition. SQLite expects the "sqlite3_vfs" object to be a R/W one, because
   1.930 +SQLite may have and use a chain of sqlite3_vfs instances.
   1.931 +
   1.932 +@see TVfs
   1.933 +@see TTFileIo
   1.934 +@see TDbFile
   1.935 +
   1.936 +@internalComponent
   1.937 +*/
   1.938 +static sqlite3_vfs TheVfsApi = 
   1.939 +	{
   1.940 +	1,					//iVersion
   1.941 +	sizeof(TDbFile),	//szOsFile
   1.942 +	KMaxFileName,		//mxPathname
   1.943 +	0,					//pNext
   1.944 +	"SymbianSql",		//zName
   1.945 +	0,					//pAppData
   1.946 +	&TVfs::Open,
   1.947 +	&TVfs::Delete,
   1.948 +	&TVfs::Access,
   1.949 +	&TVfs::FullPathName,
   1.950 +	0,
   1.951 +	0,
   1.952 +	0,
   1.953 +	0,
   1.954 +	&TVfs::Randomness,
   1.955 +	&TVfs::Sleep,
   1.956 +	&TVfs::CurrentTime,
   1.957 +	&TVfs::GetLastError
   1.958 +	};
   1.959 +
   1.960 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.961 +/////////////////////       COsLayerData class definition    //////////////////////////////////////////////////////////////////
   1.962 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   1.963 +
   1.964 +/**
   1.965 +Creates a single COsLayerData instance.
   1.966 +
   1.967 +@return KErrNone,          The operation has completed succesfully;
   1.968 +	    KErrNoMemory,      Out of memory condition has occured;
   1.969 +                           Note that other system-wide error codes may also be returned.
   1.970 +                           
   1.971 +@panic Sqlite 16 In _DEBUG mode - the COsLayerData instance has been created already.
   1.972 +*/
   1.973 +/* static */ TInt COsLayerData::Create()
   1.974 +	{
   1.975 +	SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, COSLAYERDATA_CREATE_ENTRY, "OS-Entry;0;COsLayerData::Create"));
   1.976 +	__ASSERT_DEBUG(!COsLayerData::iOsLayerData, __SQLITEPANIC2(ESqliteOsPanicOsLayerDataExists));
   1.977 +	COsLayerData::iOsLayerData = new COsLayerData;
   1.978 +	if(!COsLayerData::iOsLayerData)
   1.979 +		{
   1.980 +		SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, COSLAYERDATA_CREATE_EXIT1, "OS-Exit;0;COsLayerData::Create;err=KErrNoMemory"));
   1.981 +		return KErrNoMemory;	
   1.982 +		}
   1.983 +	TInt err = COsLayerData::iOsLayerData->DoCreate();
   1.984 +	if(err != KErrNone)
   1.985 +		{
   1.986 +		delete COsLayerData::iOsLayerData;
   1.987 +		COsLayerData::iOsLayerData = NULL;
   1.988 +		SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, COSLAYERDATA_CREATE_EXIT2, "OS-Exit;0;COsLayerData::Create;err=%d", err));
   1.989 +		return err;
   1.990 +		}
   1.991 +	SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, COSLAYERDATA_CREATE_EXIT3, "OS-Exit;0;COsLayerData::Create;err=KErrNone"));
   1.992 +	return KErrNone;
   1.993 +	}
   1.994 +
   1.995 +/**
   1.996 +Destroys the COsLayerData instance.
   1.997 +*/
   1.998 +/* static */ inline void COsLayerData::Destroy()
   1.999 +	{
  1.1000 +	delete COsLayerData::iOsLayerData;
  1.1001 +	COsLayerData::iOsLayerData = NULL;
  1.1002 +	SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, COSLAYERDATA_DESTROY, "OS;0;COsLayerData::Destroy"));
  1.1003 +	}
  1.1004 +
  1.1005 +/**
  1.1006 +Returns a reference to the single COsLayerData instance.
  1.1007 +
  1.1008 +@panic Sqlite 1 In _DEBUG mode if the COsLayerData instance is NULL.
  1.1009 +*/
  1.1010 +/* static */ inline COsLayerData& COsLayerData::Instance()
  1.1011 +	{
  1.1012 +	__ASSERT_DEBUG(COsLayerData::iOsLayerData != NULL, __SQLITEPANIC2(ESqliteOsPanicNullOsLayerDataPtr));
  1.1013 +	return *COsLayerData::iOsLayerData;
  1.1014 +	}
  1.1015 +
  1.1016 +/**
  1.1017 +Sets the last OS error code data member. The stored OS error code data member will be set only if it is
  1.1018 +KErrNone. (If it is not KErrNone it means that its value has not been accessed yet)
  1.1019 +An exception from the rule described above is KErrDiskFull error which, if happens, will be set always, because
  1.1020 +this error has a special meaning for the database clients - special actions may have to be taken if the
  1.1021 +disk is full.
  1.1022 +
  1.1023 +@param aError The OS error code
  1.1024 +@return The OS error code
  1.1025 +*/
  1.1026 +inline TInt COsLayerData::SetOsErrorCode(TInt aError)
  1.1027 +	{
  1.1028 +	if(iStoredOsErrorCode == KErrNone || aError == KErrDiskFull)
  1.1029 +		{
  1.1030 +		iStoredOsErrorCode = aError;
  1.1031 +		}
  1.1032 +	return aError;
  1.1033 +	}
  1.1034 +
  1.1035 +/**
  1.1036 +Returns the last stored OS error code, which was stored by SetOsErrorCode() call.
  1.1037 +The function also resets the stored OS error code to KErrNone.
  1.1038 +
  1.1039 +@return The last stored OS error code
  1.1040 +*/
  1.1041 +inline TInt COsLayerData::StoredOsErrorCode()
  1.1042 +	{
  1.1043 +	TInt err = iStoredOsErrorCode;
  1.1044 +	iStoredOsErrorCode = KErrNone;
  1.1045 +	return err;
  1.1046 +	}
  1.1047 +
  1.1048 +/**
  1.1049 +Stores the RMessage2 object address, file and file session handles and the read-only flag for later use when SQLite issues a 
  1.1050 +request for open the database file (private secure database). 
  1.1051 +
  1.1052 +The aMsg argument of the function can be NULL, because this fucntion is also used to reset the stored "file handle" data.
  1.1053 +
  1.1054 +How this function is used:
  1.1055 +1) When the SQL server receives a request to establish a connection with private secure database, the SQL server
  1.1056 +   will add additional information to the private secure database file name, such as: 
  1.1057 +   	- the file handle (the private secure database is opened by the client side dll - sqldb.dll);
  1.1058 +   	- a pointer to the RMessage2 object used in this request;
  1.1059 +2) The passed additional information will be used for adopting the file handle by calling RFile64::AdoptFromClient().
  1.1060 +3) Before calling TVfs::Open() to establish a connection with the database, SQLite will call TVfs::FullPathName()
  1.1061 +   to retrieve the database file full path
  1.1062 +4) TVfs::FullPathName() will detect that the file name contains an additional information and will extraxt the information
  1.1063 +   calling COsLayerData::StoreFhData().
  1.1064 +5) After TVfs::FullPathName() SQLite calls TVfs::Open() where the extracted information will be used for adopting the file handle
  1.1065 +
  1.1066 +@param aMsg A pointer to the current RMessage2 object
  1.1067 +@param aReadOnly True if the private secure database is read-only
  1.1068 +*/
  1.1069 +inline void COsLayerData::StoreFhData(const RMessage2* aMsg, TBool aReadOnly)
  1.1070 +	{
  1.1071 +	iMessage = aMsg;
  1.1072 +	iReadOnly = aReadOnly;
  1.1073 +	}
  1.1074 +
  1.1075 +/**
  1.1076 +Retrieves the RMessage2 object, file and file session handles. The stored data will be reset.
  1.1077 +This function is used by TVfs::Open(), when a request for opening a secure private database is processed.
  1.1078 +
  1.1079 +@param aMsg Output parameter. A reference to a RMessage2 pointer, which will be initialized with the stored RMessage2 pointer.
  1.1080 +@param aReadOnly Output parameter. The store read-only flag value will be set there.
  1.1081 +
  1.1082 +@panic Sqlite 13 In _DEBUG mode - aMsg is NULL.
  1.1083 +*/
  1.1084 +inline void COsLayerData::RetrieveAndResetFhData(const RMessage2*& aMsg, TBool& aReadOnly)
  1.1085 +	{
  1.1086 +	__ASSERT_DEBUG(iMessage != NULL, __SQLITEPANIC(ESqliteOsPanicInvalidFhData));
  1.1087 +	aMsg = iMessage; 
  1.1088 +	aReadOnly = iReadOnly;
  1.1089 +	iMessage = NULL;
  1.1090 +	}
  1.1091 +
  1.1092 +/**
  1.1093 +Initializes the COsLayerData data members with their default values.
  1.1094 +*/
  1.1095 +inline COsLayerData::COsLayerData() :
  1.1096 +	iStoredOsErrorCode(KErrNone),
  1.1097 +	iMessage(0),
  1.1098 +	iReadOnly(EFalse)
  1.1099 +	{
  1.1100 +	TTime now;
  1.1101 +	now.UniversalTime();
  1.1102 +	iSeed = now.Int64();
  1.1103 +	}
  1.1104 +
  1.1105 +/**
  1.1106 +Destroys the COsLayerData instance.
  1.1107 +
  1.1108 +Note: No SQLite functions should be called inside the destructor, because SQLite is already shutdown-ed!
  1.1109 +*/
  1.1110 +inline COsLayerData::~COsLayerData()
  1.1111 +	{
  1.1112 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, COSLAYERDATA_COSLAYERDATA2, "OS;0;COsLayerData::~COsLayerData;iFs.Handle()=0x%X", (TUint)iFs.Handle()));
  1.1113 +	__FS_CALL(EFsOpFsClose, 0);
  1.1114 +	iFs.Close();	
  1.1115 +	}
  1.1116 +
  1.1117 +/**
  1.1118 +Creates a file session instance.	
  1.1119 +
  1.1120 +Creates the private path, where the temporary files will be stored (on the system drive).
  1.1121 +
  1.1122 +In a case of a failure COsLayerData::DoCreate() does not close the file session.
  1.1123 +This will be made in the calling function - COsLayerData::Create().
  1.1124 +
  1.1125 +Note: No SQLite functions should be called inside the DoCreate() implementation, because SQLite is not initialized yet!
  1.1126 +
  1.1127 +@return KErrNone,          The operation has completed succesfully;
  1.1128 +		KErrGeneral		   The registration of TheVfsApi has failed;
  1.1129 +	    KErrNoMemory,      Out of memory condition has occured;
  1.1130 +                           Note that other system-wide error codes may also be returned.
  1.1131 +
  1.1132 +@see TVfs
  1.1133 +@see TheVfsApi
  1.1134 +*/
  1.1135 +TInt COsLayerData::DoCreate()
  1.1136 +	{
  1.1137 +	__FS_CALL(EFsOpFsConnect, 0);
  1.1138 +	TInt err = iFs.Connect();
  1.1139 +	if(err != KErrNone)
  1.1140 +		{
  1.1141 +		return err;	
  1.1142 +		}
  1.1143 +	//Get the system drive
  1.1144 +	__FS_CALL(EFsOpFsGetSystemDrive, 0);
  1.1145 +	TInt sysDrive = static_cast<TInt>(RFs::GetSystemDrive());
  1.1146 +	__FS_CALL(EFsOpFsCreatePrivatePath, 0);
  1.1147 +	if((err = iFs.CreatePrivatePath(sysDrive)) != KErrNone && err != KErrAlreadyExists)
  1.1148 +		{
  1.1149 +		return err;	
  1.1150 +		}
  1.1151 +	TFileName privateDir;
  1.1152 +	__FS_CALL(EFsOpFsPrivatePath, 0);
  1.1153 +	if((err = iFs.PrivatePath(privateDir)) != KErrNone)
  1.1154 +		{
  1.1155 +		return err;	
  1.1156 +		}
  1.1157 +	TDriveUnit drive(sysDrive);
  1.1158 +	TDriveName driveName = drive.Name();
  1.1159 +	TParse parse;
  1.1160 +	(void)parse.Set(driveName, &privateDir, 0);//this call can't fail
  1.1161 +	iSysPrivDir.Copy(parse.DriveAndPath());
  1.1162 +	//Create the temp files directory
  1.1163 +	(void)parse.AddDir(KTempFileDir);//this call can't fail
  1.1164 +	err = iFs.MkDir(parse.DriveAndPath());
  1.1165 +    if(err != KErrNone && err != KErrAlreadyExists)
  1.1166 +    	{
  1.1167 +		return err;
  1.1168 +    	}
  1.1169 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, COSLAYERDATA_DOCREATE, "OS;0;COsLayerData::DoCreate;iFs.Handle()=0x%X;sysDrive=%d;iSysPrivDir=%S", (TUint)iFs.Handle(), sysDrive, __SQLITEPRNSTR(iSysPrivDir)));
  1.1170 +	return KErrNone;
  1.1171 +	}
  1.1172 +
  1.1173 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1174 +///////////////////////     Symbian OS specific functions (called by the SQL server)        ///////////////////////////////////
  1.1175 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1176 +
  1.1177 +/**
  1.1178 +Returns the last OS error which occured durring the operations with the database files.
  1.1179 +The per-thread variable, where the last OS error is hold, will be set to KErrNone.
  1.1180 +
  1.1181 +This function is part of Symbian OS specific SQLITE API.
  1.1182 +
  1.1183 +@return The last OS error.
  1.1184 +@internalComponent
  1.1185 +*/
  1.1186 +TInt sqlite3SymbianLastOsError(void)
  1.1187 +	{
  1.1188 +	return COsLayerData::Instance().StoredOsErrorCode();
  1.1189 +	}
  1.1190 +
  1.1191 +/**
  1.1192 +This function must be called once before any other SQLITE API call. 
  1.1193 +The function:
  1.1194 +@code
  1.1195 + - Initializes the OS poting layer;
  1.1196 + - Initializes the SQLite library;
  1.1197 +@endcode
  1.1198 +
  1.1199 +This function is part of the Symbian OS specific SQLITE API.
  1.1200 +
  1.1201 +@return Symbian OS specific error code, including KErrNoMemory.
  1.1202 +
  1.1203 +@internalComponent
  1.1204 +*/
  1.1205 +TInt sqlite3SymbianLibInit(void)
  1.1206 +	{
  1.1207 +	TInt osErr = COsLayerData::Create();
  1.1208 +	if(osErr != KErrNone)
  1.1209 +		{
  1.1210 +		return osErr;
  1.1211 +		}
  1.1212 +	osErr = KErrNone;
  1.1213 +	TInt sqliteErr = sqlite3_initialize();
  1.1214 +	if(sqliteErr != SQLITE_OK)
  1.1215 +		{
  1.1216 +		osErr = sqliteErr == SQLITE_NOMEM ? KErrNoMemory : KErrGeneral;
  1.1217 +		COsLayerData::Destroy();
  1.1218 +		}
  1.1219 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, SQLITE3SYMBIANLIBINIT, "OS;0;sqlite3SymbianLibInit;osErr=%d", osErr));
  1.1220 +	return osErr;
  1.1221 +	}
  1.1222 +
  1.1223 +/**
  1.1224 +This function must be called once after finishing working with sqlite.
  1.1225 +The function:
  1.1226 +@code
  1.1227 + - Shuts down the SQLite library;
  1.1228 + - Releases the allocated by the OS porting layer resources;
  1.1229 +@endcode
  1.1230 +
  1.1231 +This function is part of the Symbian OS specific SQLITE API.
  1.1232 +
  1.1233 +@internalComponent
  1.1234 +*/
  1.1235 +void sqlite3SymbianLibFinalize(void)
  1.1236 +	{
  1.1237 +	(void)sqlite3_shutdown();
  1.1238 +	COsLayerData::Destroy();
  1.1239 +	SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, SQLITE3SYMBIANLIBFINALIZE, "OS;0;sqlite3SymbianLibFinalize"));
  1.1240 +	}
  1.1241 +
  1.1242 +/**
  1.1243 +This function is part of Symbian OS specific SQLITE API.
  1.1244 +
  1.1245 +@return A reference to RFs instance used for sqlite file I/O operations.
  1.1246 +@internalComponent
  1.1247 +*/
  1.1248 +RFs& sqlite3SymbianFs(void)
  1.1249 +	{
  1.1250 +	return COsLayerData::Instance().iFs;
  1.1251 +	}
  1.1252 +
  1.1253 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1254 +//////////////////          UTF16<-->UTF8, conversion functions    ////////////////////////////////////////////////////////////
  1.1255 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1256 +
  1.1257 +/**
  1.1258 +The function converts aFileName to UTF16 encoded file name, and stores the UTF16 encoded file name
  1.1259 +to the place pointed by aFileNameDestBuf argument.
  1.1260 +If the UTF16 conversion of the file name failed because the file name is too long or NULL, 
  1.1261 +the function returns EFalse. 
  1.1262 +
  1.1263 +@param aFileName Expected to point to UTF8 encoded, zero terminated string.
  1.1264 +				 Max allowed aFileName length is KMaxFileName (excluding terminating 0 character).
  1.1265 +@param aFileNameDestBuf Output parameter. Will hold UTF16, non-zero-terminated string.
  1.1266 +						The max length must be at least KMaxFileName characters.
  1.1267 +                         
  1.1268 +@return True if the conversion has been completed successfully						 
  1.1269 +*/
  1.1270 +static TBool ConvertToUnicode(const char *aFileName, TDes& aFileNameDestBuf)
  1.1271 +	{
  1.1272 +	if(aFileName)
  1.1273 +		{
  1.1274 +		wchar_t* dest = reinterpret_cast <wchar_t*> (const_cast <TUint16*> (aFileNameDestBuf.Ptr()));
  1.1275 +		TInt len = mbstowcs(dest, aFileName, aFileNameDestBuf.MaxLength());
  1.1276 +		__ASSERT_DEBUG(len >= 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.1277 +		//If len == aFileNameDestBuf.MaxLength(), then the output buffer is too small.
  1.1278 +		if(len < aFileNameDestBuf.MaxLength())
  1.1279 +			{
  1.1280 +			aFileNameDestBuf.SetLength(len);
  1.1281 +			return ETrue;
  1.1282 +			}
  1.1283 +		}
  1.1284 +	return EFalse;
  1.1285 +	}
  1.1286 +
  1.1287 +/**
  1.1288 +The function converts aFileName to UTF8 encoded file name, and stores the UTF8 encoded file name
  1.1289 +to the place pointed by aFileNameDestBuf argument.
  1.1290 +If the UTF8 conversion of the file name failed because the file name is too long or NULL, 
  1.1291 +the function returns EFalse. 
  1.1292 +
  1.1293 +@param aFileName Expected to point to UTF16 encoded, zero terminated string.
  1.1294 +				 Max allowed aFileName length is KMaxFileName (excluding terminating 0 character).
  1.1295 +@param aFileNameDestBuf Output parameter. Will hold UTF8, non-zero-terminated string.
  1.1296 +						The max length must be at least KMaxFileName characters.
  1.1297 +                         
  1.1298 +@return True if the conversion has been completed successfully						 
  1.1299 +*/
  1.1300 +static TBool ConvertFromUnicode(const TDesC& aFileName, TDes8& aFileNameDestBuf)
  1.1301 +	{
  1.1302 +	char* dest = reinterpret_cast <char*> (const_cast <TUint8*> (aFileNameDestBuf.Ptr()));
  1.1303 +	const wchar_t* src = reinterpret_cast <const wchar_t*> (aFileName.Ptr());
  1.1304 +	TInt len = wcstombs(dest, src, aFileNameDestBuf.MaxLength());
  1.1305 +	__ASSERT_DEBUG(len >= 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.1306 +	//If len == aFileNameDestBuf.MaxLength(), then the output buffer is too small.
  1.1307 +	if(len < aFileNameDestBuf.MaxLength())
  1.1308 +		{
  1.1309 +		aFileNameDestBuf.SetLength(len);
  1.1310 +		return ETrue;
  1.1311 +		}
  1.1312 +	return EFalse;
  1.1313 +	}
  1.1314 +
  1.1315 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1316 +//////////////////          File name, containing handles, functions   ////////////////////////////////////////////////////////
  1.1317 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1318 +
  1.1319 +const char KFhSeparator = '|';	//The symbol, which when used in the file name means that the string does not contain a real file name but file handles
  1.1320 +const TInt KFhSessHandleIdx = 2;//The index of the file session handle in RMessage2 object
  1.1321 +const TInt KFhFileHandleIdx = 3;//The index of the file handle in RMessage2 object
  1.1322 +const TInt KFhMarkPos = 0;		//if the symbol in this position is KFhSeparator, then the string contains file handles
  1.1323 +const TInt KFhRoPos = 1;		//read-only flag position in the string
  1.1324 +const TInt KFhMsgAddrPos = 2;	//RMessage2 address position in the string
  1.1325 +const TInt KFhMsgAddrLen = 8;	//RMessage2 address length
  1.1326 +//const TInt KFhDrivePos = 1;	//Drive position in the string (after removing the read-only flag and RMessage2 object's address)
  1.1327 +
  1.1328 +/**
  1.1329 +File name string types:
  1.1330 +@code
  1.1331 +	- ENotFhStr 	- The string does not contain file handles;
  1.1332 +	- EFhStr		- The string contain file handles, but is not main db file;
  1.1333 +	- EFhMainDbStr	- The string contain file handles and is the main db file;
  1.1334 +@endcode
  1.1335 +
  1.1336 +Every file name passed to the OS porting layer's TVfs::Open() method falls into one of the following three categories:
  1.1337 +ENotFhStr - the file name does not contain handles, EFhStr - the file name contains handles but is not a name of a private
  1.1338 +secure database, EFhMainDbStr - the file name contains handles and is a name of a private secure database.
  1.1339 +
  1.1340 +@see TVfs::Open()
  1.1341 +@see FhStringProps()
  1.1342 +
  1.1343 +@internalComponent
  1.1344 +*/
  1.1345 +enum TFhStrType
  1.1346 +	{
  1.1347 +	ENotFhStr,						//The string does not contain file handles
  1.1348 +	EFhStr,							//The string contain file handles, but is not main db file
  1.1349 +	EFhMainDbStr					//The string contain file handles and is the main db file
  1.1350 +	};
  1.1351 +
  1.1352 +/**
  1.1353 +The TVfs::Open() implementation uses this function to determine the type of the file name, which can be 
  1.1354 +one of the TFhStrType enum item values.
  1.1355 +
  1.1356 +@param aFileName Zero-terminated, UTF8 encoded file name.
  1.1357 +@return The file name type, one of the TFhStrType enum item values.
  1.1358 +
  1.1359 +@see TVfs::Open()
  1.1360 +@see TFhStrType
  1.1361 +
  1.1362 +@internalComponent
  1.1363 +*/
  1.1364 +static TFhStrType FhStringProps(const char* aFileName)
  1.1365 +	{
  1.1366 +	char* first = strchr(aFileName, KFhSeparator);
  1.1367 +	if(!first)
  1.1368 +		{
  1.1369 +		return ENotFhStr;
  1.1370 +		}
  1.1371 +	char* last = strchr(first + 1, KFhSeparator);
  1.1372 +	if(!last)
  1.1373 +		{
  1.1374 +		return ENotFhStr;
  1.1375 +		}
  1.1376 +	return *(last + 1) == 0 ? EFhMainDbStr : EFhStr;
  1.1377 +	}
  1.1378 +
  1.1379 +/**
  1.1380 +Removes all invalid characters in aFileName.
  1.1381 +If the file name contains handles (so that's a private secure database related name), the additional
  1.1382 +information (handles, flags, object addresses) has to be excluded from the name in order to make it usable 
  1.1383 +by the file system. 
  1.1384 +
  1.1385 +The private file name format is (see FhExtractAndStore() comments):
  1.1386 +
  1.1387 +"|<R/O flag><RMessage2 pointer><drive><app SID><file_name><file_ext>|"
  1.1388 +
  1.1389 +Before opening or creating a file, SQLite will call TVfs::FullPathName() passing to the function the name of
  1.1390 +the file and expecting the full file name (including path) as an output from the function.
  1.1391 +After the TVfs::FullPathName() call, the full file name, returned to SQLite, will have the following format:
  1.1392 +
  1.1393 +"|<drive><path><file_name><file_ext>|"
  1.1394 +
  1.1395 +FhConvertToFileName() is called from TVfs::Open() and will remove the leading and trialing '|' characters from
  1.1396 +the file name.
  1.1397 +
  1.1398 +@param aFileName Input/Output parameter. The cleaned file name will be copied there.
  1.1399 +@param aPrivateDir The SQL server private data cage.
  1.1400 +
  1.1401 +@see TVfs::Open()
  1.1402 +@see TFhStrType
  1.1403 +@see FhStringProps()
  1.1404 +
  1.1405 +@internalComponent
  1.1406 +*/
  1.1407 +static void FhConvertToFileName(TDes& aFileName, const TDesC& aPrivateDir)
  1.1408 +	{
  1.1409 +	TInt firstPos = aFileName.Locate(TChar(KFhSeparator));
  1.1410 +	if(firstPos >= 0)
  1.1411 +		{
  1.1412 +		aFileName.Delete(firstPos, 1);
  1.1413 +		TInt lastPos = aFileName.LocateReverse(TChar(KFhSeparator));
  1.1414 +		if(lastPos >= 0)
  1.1415 +			{
  1.1416 +			aFileName.Delete(lastPos, 1);
  1.1417 +			TParse parse;
  1.1418 +			(void)parse.Set(aFileName, &aPrivateDir, 0);//the file name should be verified by the server
  1.1419 +			aFileName.Copy(parse.FullName());
  1.1420 +			}
  1.1421 +		}
  1.1422 +	}
  1.1423 +
  1.1424 +/**
  1.1425 +Extracts the read-only flag and RMessage address from aDbFileName and stores them in the single COsLayerData instance.
  1.1426 +
  1.1427 +@param aDbFileName Input/output parameter. The file name. 
  1.1428 +				   It will be reformatted and won't contain the already extracted data.
  1.1429 +				   The aDbFileName format is:
  1.1430 +@code
  1.1431 +      				|<R/O flag><RMessage2 pointer><drive><app SID><file_name><file_ext>|
  1.1432 +@endcode
  1.1433 +
  1.1434 +@see TVfs::Open()
  1.1435 +@see TFhStrType
  1.1436 +@see FhStringProps()
  1.1437 +
  1.1438 +@internalComponent
  1.1439 +
  1.1440 +@panic Sqlite 12 In _DEBUG mode - invalid position of the "|" character in the file name.
  1.1441 +@panic Sqlite 12 In _DEBUG mode - no RMessage2 pointer can be extracted from the file name.
  1.1442 +@panic Sqlite 12 In _DEBUG mode - the extracted RMessage2 pointer is NULL.
  1.1443 +*/
  1.1444 +static void FhExtractAndStore(TDes& aDbFileName)
  1.1445 +	{
  1.1446 +	TInt fhStartPos = aDbFileName.Locate(TChar(KFhSeparator));
  1.1447 +	__ASSERT_DEBUG(fhStartPos == KFhMarkPos, __SQLITEPANIC2(ESqliteOsPanicInvalidFhStr));
  1.1448 +	//If this file name string contains file handles
  1.1449 +	if(fhStartPos == KFhMarkPos)
  1.1450 +		{
  1.1451 +		//Extract from aDbFileName string RMessage2 object's address
  1.1452 +		TLex lex(aDbFileName.Mid(fhStartPos + KFhMsgAddrPos, KFhMsgAddrLen));
  1.1453 +		TUint32 addr;
  1.1454 +		TInt err = lex.Val(addr, EHex);
  1.1455 +		__ASSERT_DEBUG(err == KErrNone, __SQLITEPANIC2(ESqliteOsPanicInvalidFhStr));
  1.1456 +		if(err == KErrNone)
  1.1457 +			{
  1.1458 +			//Cast the address to RMessage2 pointer.
  1.1459 +			const RMessage2* msg = reinterpret_cast <const RMessage2*> (addr);
  1.1460 +			__ASSERT_DEBUG(msg != NULL, __SQLITEPANIC2(ESqliteOsPanicInvalidFhStr));
  1.1461 +			if(msg)
  1.1462 +				{
  1.1463 +				//Store the data from aDbFileName in the single COsLayerData instance.
  1.1464 +				TBool readOnly = aDbFileName[fhStartPos + KFhRoPos] > '0';
  1.1465 +				COsLayerData::Instance().StoreFhData(msg, readOnly);
  1.1466 +				//Remove: read-only flag and RMessage2 object's address
  1.1467 +				aDbFileName.Delete(fhStartPos + KFhRoPos, 1 + KFhMsgAddrLen);
  1.1468 +				}
  1.1469 +			}
  1.1470 +		}
  1.1471 +	}
  1.1472 +
  1.1473 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1474 +/////////////////////       TDbFile class definition    ///////////////////////////////////////////////////////////////////////
  1.1475 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1476 +
  1.1477 +/**
  1.1478 +Initializes TDbFile data members with their default values.
  1.1479 +*/
  1.1480 +inline TDbFile::TDbFile() :
  1.1481 +	iFileBuf(KFileBufSize),
  1.1482 +	iLockType(SQLITE_LOCK_NONE),
  1.1483 +	iReadOnly(EFalse),
  1.1484 +	iSectorSize(0),
  1.1485 +	iDeviceCharacteristics(-1),
  1.1486 +	iIsFileCreated(ETrue)
  1.1487 +	{
  1.1488 +#ifdef _SQLPROFILER
  1.1489 +	iIsJournal = EFalse;
  1.1490 +#endif
  1.1491 +	pMethods = 0;
  1.1492 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TDBFILE_TDBFILE, "OS;0x%X;TDbFile::TDbFile", (TUint)this));
  1.1493 +	}
  1.1494 +
  1.1495 +/**
  1.1496 +Casts the passed sqlite3_file pointer to a reference to the derived class - TDbFile&.
  1.1497 +All sqlite3_file pointers passed to TFileIo methods are actually pointers to TDbFile instances. 
  1.1498 +So the cast is safe.
  1.1499 +
  1.1500 +@param aDbFile A pointer to a sqlite3_file instance
  1.1501 +
  1.1502 +@return A TDbFile reference. 
  1.1503 +@see TFileIo
  1.1504 +@see TVfs
  1.1505 +@see TDbFile
  1.1506 +
  1.1507 +@panic Sqlite 20 In _DEBUG mode if aDbFile is NULL.
  1.1508 +
  1.1509 +@internalComponent
  1.1510 +*/
  1.1511 +static inline TDbFile& DbFile(sqlite3_file* aDbFile)
  1.1512 +	{
  1.1513 +	__ASSERT_DEBUG(aDbFile != 0, __SQLITEPANIC2(ESqliteOsPanicNullDbFilePtr));
  1.1514 +	return *(static_cast <TDbFile*> (aDbFile));
  1.1515 +	}
  1.1516 +
  1.1517 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1518 +/////////////////////       TFileIo class definition    ///////////////////////////////////////////////////////////////////////
  1.1519 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.1520 +
  1.1521 +/**
  1.1522 +SQLite OS porting layer API.
  1.1523 +
  1.1524 +Closes the file referred by aDbFile parameter.
  1.1525 +
  1.1526 +@param aDbFile A pointer to a TDbFile instance, than contains the file handle to be closed.
  1.1527 +
  1.1528 +@return SQLITE_OK
  1.1529 +
  1.1530 +@see TDbFile
  1.1531 +*/
  1.1532 +/* static */ int TFileIo::Close(sqlite3_file* aDbFile)
  1.1533 +	{
  1.1534 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1535 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TFILEIO_CLOSE1, "OS;0x%X;TFileIo::Close", (TUint)&dbFile));
  1.1536 +	__OS_CALL(EOsFileClose, 0, 0);
  1.1537 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileClose], ::OsCallProfile(dbFile.iIsJournal, EOsFileClose), 0, 0, aDbFile, 0);
  1.1538 +	__FS_CALL(EFsOpFileClose, 0);
  1.1539 +	dbFile.iFileBuf.Close();
  1.1540 +	return SQLITE_OK;
  1.1541 +	}
  1.1542 +
  1.1543 +/**
  1.1544 +SQLite OS porting layer API.
  1.1545 +
  1.1546 +Reads from the file referred by the aDbFile parameter.
  1.1547 +
  1.1548 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle to be read from.
  1.1549 +@param aBuf Output parameter. The data read from the file will be copied there.
  1.1550 +			The buffer size must be at least aAmt bytes.
  1.1551 +@param aAmt The amount of data to be read form the file.
  1.1552 +@param aOffset The offset in the file where the read operation should start.
  1.1553 +
  1.1554 +@return SQLITE_IOERR_READ, 			The file read or seek operation has failed;
  1.1555 +	    SQLITE_IOERR_SHORT_READ, 	The amount of the data read is less than aAmt;
  1.1556 +	    SQLITE_IOERR_NOMEM,			An out of memory condition has occured;
  1.1557 +	    SQLITE_OK,					The operation has completed successfully.
  1.1558 +	    
  1.1559 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.1560 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.1561 +
  1.1562 +@see COsLayerData::SetOsErrorCode()
  1.1563 +@see TDbFile
  1.1564 +*/
  1.1565 +/* static */ int TFileIo::Read(sqlite3_file* aDbFile, void* aBuf, int aAmt, sqlite3_int64 aOffset)
  1.1566 +	{
  1.1567 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1568 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_READ_ENTRY, "OS-Entry;0x%X;TFileIo::Read;aAmt=%d;aOffset=%lld", (TUint)&dbFile, aAmt, aOffset));
  1.1569 +	__OS_CALL(EOsFileRead, 0, 0);
  1.1570 +	__COUNTER_INCR(TheSqlSrvProfilerFileRead);
  1.1571 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileRead], ::OsCallProfile(dbFile.iIsJournal, EOsFileRead), aOffset, aAmt, aDbFile, 0);
  1.1572 +	TPtr8 ptr((TUint8*)aBuf, 0, aAmt);
  1.1573 +	TInt err = dbFile.iFileBuf.Read(aOffset, ptr);
  1.1574 +	TInt cnt = ptr.Length();
  1.1575 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_READ);
  1.1576 +	if(cnt != aAmt && (sqliteErr == SQLITE_OK || sqliteErr == SQLITE_IOERR_SHORT_READ))
  1.1577 +		{
  1.1578 +		Mem::FillZ(static_cast <TUint8*> (aBuf) + cnt, aAmt - cnt);
  1.1579 +		err = KErrEof;
  1.1580 +		sqliteErr = SQLITE_IOERR_SHORT_READ;
  1.1581 +		}
  1.1582 +	COsLayerData::Instance().SetOsErrorCode(err);
  1.1583 +	SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TFILEIO_READ_EXIT, "OS-Exit;0x%X;TFileIo::Read;cnt=%d;err=%d;sqliteErr=%d", (TUint)&dbFile, cnt, err, sqliteErr));
  1.1584 +	return sqliteErr;
  1.1585 +	}
  1.1586 +
  1.1587 +//Creates a temporary file in "\temp" subdirectory of osLayerData.iSysPrivDir directory.
  1.1588 +//If the function fails, the temp file will be closed and deleted, 
  1.1589 +//the related Symbian OS error will be returned to the caller.
  1.1590 +/* static */TInt TFileIo::DoCreateTempFile(TDbFile& aDbFile)
  1.1591 +    {
  1.1592 +    COsLayerData& osLayerData = COsLayerData::Instance();
  1.1593 +    //TParse2 is used in order to avoid the need of another TFileName stack based variable
  1.1594 +	class TParse2 : public TParse
  1.1595 +		{
  1.1596 +	public:
  1.1597 +		inline TFileName& FileName()
  1.1598 +			{
  1.1599 +			return static_cast <TFileName&> (NameBuf());
  1.1600 +			}
  1.1601 +		};
  1.1602 +	TParse2 parse;
  1.1603 +	(void)parse.Set(osLayerData.iSysPrivDir, 0, 0);//this call can't fail
  1.1604 +	(void)parse.AddDir(KTempFileDir);//this call can't fail
  1.1605 +    __FS_CALL(EFsOpFileCreateTemp, 0);
  1.1606 +    TInt err = aDbFile.iFileBuf.Temp(osLayerData.iFs, parse.FullName(), parse.FileName(), EFileRead|EFileWrite|EDeleteOnClose);        
  1.1607 +    if(err == KErrPathNotFound)
  1.1608 +        {
  1.1609 +        err = osLayerData.iFs.MkDirAll(parse.DriveAndPath());
  1.1610 +        if(err == KErrNone)
  1.1611 +            {
  1.1612 +            err = aDbFile.iFileBuf.Temp(osLayerData.iFs, parse.FullName(), parse.FileName(), EFileRead|EFileWrite|EDeleteOnClose);
  1.1613 +            }
  1.1614 +        }
  1.1615 +    if(err == KErrNone)
  1.1616 +        {
  1.1617 +        TInt recReadBufSize = -1;
  1.1618 +        err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(aDbFile, recReadBufSize);
  1.1619 +        if(err != KErrNone)
  1.1620 +            {
  1.1621 +            aDbFile.iFileBuf.Close();//With EDeleteOnClose flag set, the file will be deleted
  1.1622 +            }
  1.1623 +        else
  1.1624 +            {
  1.1625 +            (void)aDbFile.iFileBuf.SetReadAheadSize(aDbFile.iSectorSize, recReadBufSize);
  1.1626 +            aDbFile.iIsFileCreated = ETrue;
  1.1627 +            }
  1.1628 +        }
  1.1629 +    return err;
  1.1630 +    }
  1.1631 +
  1.1632 +/**
  1.1633 +SQLite OS porting layer API.
  1.1634 +
  1.1635 +Writes to the file referred by the aDbFile parameter.
  1.1636 +"Write beyond the end of the file" operations are allowed.
  1.1637 +
  1.1638 +If the write operation is in the 1st db file page and there is a registered "free pages" callback 
  1.1639 +(TDbFile::iFreePageCallback) and the free pages count is above the defined value,
  1.1640 +then the callback will be called.
  1.1641 +
  1.1642 +If the file to be written to is a temp file, which is not created yet, then the file will be created.
  1.1643 +
  1.1644 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle to be written to.
  1.1645 +@param aData The data to be written to the file. The buffer size must be at least aAmt bytes.
  1.1646 +@param aAmt The amount of data to be written to the file.
  1.1647 +@param aOffset The offset in the file where the write operation should start.
  1.1648 +
  1.1649 +@return SQLITE_FULL,       	The file write or seek operation has failed.
  1.1650 +							The disk is full;
  1.1651 +	    SQLITE_IOERR_NOMEM,	An out of memory condition has occured;
  1.1652 +	    SQLITE_OK,			The operation has completed successfully.
  1.1653 +	    
  1.1654 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.1655 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.1656 +	    
  1.1657 +@see COsLayerData::SetOsErrorCode()
  1.1658 +@see TDbFile
  1.1659 +*/
  1.1660 +/* static */ int TFileIo::Write(sqlite3_file* aDbFile, const void* aData, int aAmt, sqlite3_int64 aOffset)
  1.1661 +	{
  1.1662 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1663 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_WRITE_ENTRY, "OS-Entry;0x%X;TFileIo::Write;aAmt=%d;aOffset=%lld", (TUint)&dbFile, aAmt, aOffset));
  1.1664 +	__OS_CALL(EOsFileWrite, 0, 0);
  1.1665 +    __COUNTER_INCR(TheSqlSrvProfilerFileWrite);
  1.1666 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileWrite], ::OsCallProfile(dbFile.iIsJournal, EOsFileWrite), aOffset, aAmt, aDbFile, 0);
  1.1667 +	TInt err = KErrNone;
  1.1668 +	if(!dbFile.iIsFileCreated)
  1.1669 +	    {//Create a temp file if it has not been created. 
  1.1670 +	    err = TFileIo::DoCreateTempFile(dbFile);
  1.1671 +	    }
  1.1672 +	if(err != KErrNone)
  1.1673 +	    {
  1.1674 +        COsLayerData::Instance().SetOsErrorCode(err);
  1.1675 +		return ::Os2SqliteErr(err, SQLITE_FULL);
  1.1676 +	    }
  1.1677 +	err = KErrAccessDenied;
  1.1678 +	if(!dbFile.iReadOnly)
  1.1679 +		{
  1.1680 +		TPtrC8 ptr((const TUint8*)aData, aAmt);
  1.1681 +		err = dbFile.iFileBuf.Write(aOffset, ptr);
  1.1682 +		}
  1.1683 +	COsLayerData::Instance().SetOsErrorCode(err);
  1.1684 +	
  1.1685 +	const TInt KFreePageCountOffset = 36;//hard-coded constant. SQLite does not offer anything - a constant or #define.
  1.1686 +	//The checks in the "if" bellow do:
  1.1687 +	// - "err == KErrNone" - check the free page count only after a successful "write";
  1.1688 +	// - "aOffset == 0"    - check the free page count only if the write operation affects the system page (at aOffset = 0);
  1.1689 +	// - "aAmt >= (KFreePageCountOffset + sizeof(int))" - check the free page count only if the amount of bytes to be written
  1.1690 +	//						 is more than the offset of the free page counter (othewrise the free page counter is not affected
  1.1691 +	//						 by this write operation);
  1.1692 +	// - "dbFile.iFreePageCallback.IsValid()" - check the free page count only if there is a valid callback;
  1.1693 +	if(err == KErrNone  && aOffset == 0 && aAmt >= (KFreePageCountOffset + sizeof(int)) && dbFile.iFreePageCallback.IsValid())
  1.1694 +		{
  1.1695 +		const TUint8* ptr = static_cast <const TUint8*> (aData) + KFreePageCountOffset;
  1.1696 +		TInt freePageCount = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
  1.1697 +		dbFile.iFreePageCallback.CheckAndCallback(freePageCount);
  1.1698 +		}
  1.1699 +		
  1.1700 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_FULL);
  1.1701 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_WRITE_EXIT, "OS-Exit;0x%X;TFileIo::Write;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr));
  1.1702 +	return sqliteErr;
  1.1703 +	}
  1.1704 +
  1.1705 +/**
  1.1706 +SQLite OS porting layer API.
  1.1707 +
  1.1708 +Truncates the file referred by the aDbFile parameter.
  1.1709 +
  1.1710 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1711 +@param aLength The new file size in bytes.
  1.1712 +
  1.1713 +@return SQLITE_FULL,       	The disk is full;
  1.1714 +		SQLITE_IOERR,		This is a read-only file.
  1.1715 +	    					The file truncate operation has failed;
  1.1716 +	    SQLITE_IOERR_NOMEM,	An out of memory condition has occured;
  1.1717 +	    SQLITE_OK,			The operation has completed successfully.
  1.1718 +	    
  1.1719 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.1720 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.1721 +
  1.1722 +@see COsLayerData::SetOsErrorCode()
  1.1723 +@see TDbFile
  1.1724 +*/
  1.1725 +/* static */ int TFileIo::Truncate(sqlite3_file* aDbFile, sqlite3_int64 aLength)
  1.1726 +	{
  1.1727 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1728 +	SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_TRUNCATE_ENTRY, "OS-Entry;0x%X;TFileIo::Truncate;aLength=%lld", (TUint)&dbFile, aLength));
  1.1729 +	__OS_CALL(EOsFileTruncate, 0, 0);
  1.1730 +    __COUNTER_INCR(TheSqlSrvProfilerFileSetSize);
  1.1731 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileTruncate], ::OsCallProfile(dbFile.iIsJournal, EOsFileTruncate), aLength, 0, aDbFile, 0);
  1.1732 +	if(dbFile.iReadOnly)
  1.1733 +		{
  1.1734 +		COsLayerData::Instance().SetOsErrorCode(KErrAccessDenied);
  1.1735 +  		return SQLITE_IOERR;	
  1.1736 +		}
  1.1737 +	__FS_CALL(EFsOpFileSetSize, 0);
  1.1738 +	TInt err = dbFile.iFileBuf.SetSize(aLength);
  1.1739 +	COsLayerData::Instance().SetOsErrorCode(err);
  1.1740 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR);
  1.1741 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_TRUNCATE_EXIT, "OS-Exit;0x%X;TFileIo::Truncate;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr));
  1.1742 +	return sqliteErr;
  1.1743 +	}
  1.1744 +
  1.1745 +/**
  1.1746 +SQLite OS porting layer API.
  1.1747 +
  1.1748 +Flushes the file referred by the aDbFile parameter.
  1.1749 +
  1.1750 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1751 +
  1.1752 +@return SQLITE_IOERR,		This is a read-only file.
  1.1753 +	    					The file flush operation has failed;
  1.1754 +	    SQLITE_IOERR_NOMEM,	An out of memory condition has occured;
  1.1755 +	    SQLITE_OK,			The operation has completed successfully.
  1.1756 +	    
  1.1757 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.1758 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.1759 +
  1.1760 +@see COsLayerData::SetOsErrorCode()
  1.1761 +@see TDbFile
  1.1762 +*/
  1.1763 +/* static */int TFileIo::Sync(sqlite3_file* aDbFile, int /* aFlags */)
  1.1764 +	{
  1.1765 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1766 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TFILEIO_SYNC_ENTRY, "OS-Entry;0x%X;TFileIo::Sync", (TUint)&dbFile));
  1.1767 +	__OS_CALL(EOsFileSync, 0, 0);
  1.1768 +    __COUNTER_INCR(TheSqlSrvProfilerFileSync);
  1.1769 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileSync], ::OsCallProfile(dbFile.iIsJournal, EOsFileSync), 0, 0, aDbFile, 0);
  1.1770 +	if(dbFile.iReadOnly)
  1.1771 +		{
  1.1772 +		COsLayerData::Instance().SetOsErrorCode(KErrAccessDenied);
  1.1773 +		return SQLITE_IOERR;
  1.1774 +		}
  1.1775 +	__FS_CALL(EFsOpFileSync, 0);
  1.1776 +	TInt err = dbFile.iFileBuf.Flush();
  1.1777 +	COsLayerData::Instance().SetOsErrorCode(err);
  1.1778 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR);
  1.1779 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_SYNC_EXIT, "OS-Exit;0x%X;TFileIo::Sync;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr));
  1.1780 +	return sqliteErr;
  1.1781 +	}
  1.1782 +
  1.1783 +/**
  1.1784 +SQLite OS porting layer API.
  1.1785 +
  1.1786 +Returns the size of the file referred by the aDbFile parameter.
  1.1787 +
  1.1788 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1789 +@param aSize Output parameter. If the function completes successfully, the file size will be stored there.
  1.1790 +
  1.1791 +@return SQLITE_IOERR,			The file size operation has failed;
  1.1792 +	    SQLITE_IOERR_NOMEM,		An out of memory condition has occured;
  1.1793 +	    SQLITE_OK,				The operation has completed successfully.
  1.1794 +	    
  1.1795 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.1796 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.1797 +	    
  1.1798 +@see COsLayerData::SetOsErrorCode()
  1.1799 +@see TDbFile
  1.1800 +*/
  1.1801 +/* static */ int TFileIo::FileSize(sqlite3_file* aDbFile, sqlite3_int64* aSize)
  1.1802 +	{
  1.1803 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1804 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TFILEIO_FILESIZE_ENTRY, "OS-Entry;0x%X;TFileIo::FileSize", (TUint)&dbFile));
  1.1805 +	__OS_CALL(EOsFileFileSize, 0, 0);
  1.1806 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileFileSize], ::OsCallProfile(dbFile.iIsJournal, EOsFileFileSize), 0, 0, aDbFile, 0);
  1.1807 +	__FS_CALL(EFsOpFileSize, 0);
  1.1808 +	TInt err =  dbFile.iFileBuf.Size(*aSize);
  1.1809 +	COsLayerData::Instance().SetOsErrorCode(err);
  1.1810 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR);
  1.1811 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_FILESIZE_EXIT, "OS-Exit;0x%X;TFileIo::FileSize;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr));
  1.1812 +	return sqliteErr;
  1.1813 +	}
  1.1814 +
  1.1815 +/**
  1.1816 +SQLite OS porting layer API.
  1.1817 +
  1.1818 +Locks the file, referred by the aDbFile parameter, with the specified lock type.
  1.1819 +Since this is a single-threaded OS porting layer implementation, the file is not actually locked - small
  1.1820 +performance optimisation. The file lock type is stored for later use by the CheckReservedLock() call.
  1.1821 +
  1.1822 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1823 +@param aLockType Lock type: SQLITE_LOCK_NONE, SQLITE_LOCK_SHARED, SQLITE_LOCK_RESERVED, SQLITE_LOCK_PENDING or
  1.1824 +				 SQLITE_LOCK_EXCLUSIVE.
  1.1825 +
  1.1826 +@return SQLITE_OK,	The operation has completed successfully.
  1.1827 +
  1.1828 +@see TFileIo::CheckReservedLock()
  1.1829 +@see TFileIo::Unlock()
  1.1830 +	    
  1.1831 +@see TDbFile
  1.1832 +*/
  1.1833 +/* static */ int TFileIo::Lock(sqlite3_file* aDbFile, int aLockType)
  1.1834 +	{
  1.1835 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1836 +	__OS_CALL(EOsFileLock, 0, 0);
  1.1837 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileLock], ::OsCallProfile(dbFile.iIsJournal, EOsFileLock), aLockType, 0, aDbFile, 0);
  1.1838 +	//If there is already a lock of this type or more restrictive on the database file, do nothing.
  1.1839 +	if(dbFile.iLockType >= aLockType)
  1.1840 +		{
  1.1841 +		return SQLITE_OK;
  1.1842 +		}
  1.1843 +	dbFile.iLockType = aLockType;
  1.1844 +	return SQLITE_OK;
  1.1845 +	}
  1.1846 +
  1.1847 +/**
  1.1848 +SQLite OS porting layer API.
  1.1849 +
  1.1850 +Unlocks the file, referred by the aDbFile parameter.
  1.1851 +Since this is a single-threaded OS porting layer implementation, the file never gets locked - small
  1.1852 +performance optimisation. The Unlock() call only sets the stored file lock type with the aLockType value.
  1.1853 +
  1.1854 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1855 +@param aLockType Lock type: SQLITE_LOCK_NONE, SQLITE_LOCK_SHARED, SQLITE_LOCK_RESERVED, SQLITE_LOCK_PENDING or
  1.1856 +				 SQLITE_LOCK_EXCLUSIVE.
  1.1857 +
  1.1858 +@return SQLITE_OK,	The operation has completed successfully.
  1.1859 +
  1.1860 +@see TFileIo::CheckReservedLock()
  1.1861 +@see TFileIo::Lock()
  1.1862 +	    
  1.1863 +@see TDbFile
  1.1864 +*/
  1.1865 +/* static */ int TFileIo::Unlock(sqlite3_file* aDbFile, int aLockType)
  1.1866 +	{
  1.1867 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1868 +	__OS_CALL(EOsFileUnlock, 0, 0);
  1.1869 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileUnlock], ::OsCallProfile(dbFile.iIsJournal, EOsFileUnlock), aLockType, 0, aDbFile, 0);
  1.1870 +	dbFile.iLockType = aLockType;
  1.1871 +	return SQLITE_OK;
  1.1872 +	}
  1.1873 +
  1.1874 +/**
  1.1875 +SQLite OS porting layer API.
  1.1876 +
  1.1877 +Checks if the file lock type is SQLITE_LOCK_RESERVED or bigger.
  1.1878 +Since this is a single-threaded OS porting layer implementation, the file never gets locked - small
  1.1879 +performance optimisation. The CheckReservedLock() call only checks if the stored file lock type 
  1.1880 +is bigger or equal than SQLITE_LOCK_RESERVED.
  1.1881 +
  1.1882 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1883 +@param aResOut Output parameter. It should be set to 1 if the stored lock type is bigger or equal 
  1.1884 +							     than SQLITE_LOCK_RESERVED.
  1.1885 +
  1.1886 +@return SQLITE_OK.
  1.1887 +
  1.1888 +@see TFileIo::Lock()
  1.1889 +@see TFileIo::Unlock()
  1.1890 +	    
  1.1891 +@see TDbFile
  1.1892 +*/
  1.1893 +/* static */ int TFileIo::CheckReservedLock(sqlite3_file* aDbFile, int *aResOut)
  1.1894 +	{
  1.1895 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1896 +	__OS_CALL(EOsFileCheckReservedLock, 0, 0);
  1.1897 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileCheckReservedLock], ::OsCallProfile(dbFile.iIsJournal, EOsFileCheckReservedLock), 0, 0, aDbFile, 0);
  1.1898 +	*aResOut = dbFile.iLockType >= SQLITE_LOCK_RESERVED ? 1 : 0;
  1.1899 +  	return SQLITE_OK;
  1.1900 +	}
  1.1901 +
  1.1902 +/**
  1.1903 +SQLite OS porting layer API.
  1.1904 +
  1.1905 +Performs an aOp operation on the file referred by the aDbFile parameter.
  1.1906 +Since the only supported operation at the moment is SQLITE_FCNTL_LOCKSTATE, and the current lock type is stored as
  1.1907 +a data memebr of TDbFile, the function implementation has been optimised - no file I/O calls. The stored file lock type
  1.1908 +is retured if the operation is SQLITE_FCNTL_LOCKSTATE.
  1.1909 +
  1.1910 +Note: The range of supported operations includes KSqlFcntlRegisterFreePageCallback now.
  1.1911 +      When the function is called with aOp = KSqlFcntlRegisterFreePageCallback, then a callback will be registered
  1.1912 +      and called when the number of the free pages goes above certain threshold.
  1.1913 +
  1.1914 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1915 +@param aOp File operation type. Currently only SQLITE_FCNTL_LOCKSTATE is supported.
  1.1916 +@param aArg An additional input/output parameter which purpose depends on the type of the current file operation.
  1.1917 +			If the file operation is SQLITE_FCNTL_LOCKSTATE, then aArg is used as an output parameter, where
  1.1918 +			the file lock type is stored.
  1.1919 +			If the operation type is KSqlFcntlRegisterFreePageCallback, then aArg points to a TSqlFreePageCallback object,
  1.1920 +			that contains the free page threshold and the callback.
  1.1921 +
  1.1922 +@return SQLITE_ERROR,	Non-supported operation;
  1.1923 +		SQLITE_OK,		The operation has completed successfully.
  1.1924 +	    
  1.1925 +@see TDbFile
  1.1926 +*/
  1.1927 +/* static */ int TFileIo::FileControl(sqlite3_file* aDbFile, int aOp, void* aArg)
  1.1928 +	{
  1.1929 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1930 +	SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TFILEIO_FILECONTROL_ENTRY, "OS-Entry;0x%X;TFileIo::FileControl;aOp=%d", (TUint)&dbFile, aOp));
  1.1931 +	__OS_CALL(EOsFileFileControl, 0, 0);
  1.1932 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileFileControl], ::OsCallProfile(dbFile.iIsJournal, EOsFileFileControl), aOp, 0, aDbFile, 0);
  1.1933 +	TInt err = KErrNone;
  1.1934 +	switch(aOp)
  1.1935 +		{
  1.1936 +		case SQLITE_FCNTL_LOCKSTATE:
  1.1937 +			*(int*)aArg = dbFile.iLockType;
  1.1938 +			break;
  1.1939 +		case KSqlFcntlRegisterFreePageCallback:
  1.1940 +			{
  1.1941 +			err = KErrArgument;
  1.1942 +			if(aArg)
  1.1943 +				{
  1.1944 +				TSqlFreePageCallback* rq = static_cast <TSqlFreePageCallback*> (aArg);
  1.1945 +				if(rq->IsValid())
  1.1946 +					{
  1.1947 +					dbFile.iFreePageCallback = *rq;
  1.1948 +					err = KErrNone;
  1.1949 +					}
  1.1950 +				}
  1.1951 +			}
  1.1952 +			break;
  1.1953 +		default:
  1.1954 +			err = KErrArgument;
  1.1955 +			break;
  1.1956 +		}
  1.1957 +	COsLayerData::Instance().SetOsErrorCode(err);
  1.1958 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_ERROR);
  1.1959 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TFILEIO_FILECONTROL_EXIT, "OS-Exit;0x%X;TFileIo::FileControl;err=%d;sqliteErr=%d", (TUint)&dbFile, err, sqliteErr));
  1.1960 +	return sqliteErr;
  1.1961 +	}
  1.1962 +
  1.1963 +/**
  1.1964 +SQLite OS porting layer API.
  1.1965 +
  1.1966 +Retrieves the sector size of the media of the file referred by the aDbFile parameter.
  1.1967 +Since the sector size never changes till the file is open, the function has been optimised - no file I/O calls.
  1.1968 +The sector size is retrieved during the TVfs::Open() call and stored in TDbFile::iSectorSize. The SectorSize()
  1.1969 +call returns the value of TDbFile::iSectorSize.
  1.1970 +
  1.1971 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1972 +
  1.1973 +@return The sector size.
  1.1974 +
  1.1975 +@panic Sqlite 19 In _DEBUG mode - TDbFile::iSectorSize is negative or 0 .
  1.1976 +	    
  1.1977 +@see TDbFile
  1.1978 +@see TVfs::Open()
  1.1979 +*/
  1.1980 +/* static */ int TFileIo::SectorSize(sqlite3_file* aDbFile)
  1.1981 +	{
  1.1982 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.1983 +	__OS_CALL(EOsFileSectorSize, 0, 0);
  1.1984 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileSectorSize], ::OsCallProfile(dbFile.iIsJournal, EOsFileSectorSize), 0, 0, aDbFile, 0);
  1.1985 +	__ASSERT_DEBUG(dbFile.iSectorSize > 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.1986 +	return dbFile.iSectorSize;
  1.1987 +	}
  1.1988 +
  1.1989 +/**
  1.1990 +SQLite OS porting layer API.
  1.1991 +
  1.1992 +Retrieves the device characteristics of the device of the file referred by the aDbFile parameter.
  1.1993 +Since the device characteristics never change till the file is open, the function has been optimised - no file I/O calls.
  1.1994 +The device characteristics are retrieved during the TVfs::Open() call and stored in TDbFile::iDeviceCharacteristics. 
  1.1995 +The DeviceCharacteristics() call returns the value of TDbFile::iDeviceCharacteristics.
  1.1996 +
  1.1997 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.1998 +
  1.1999 +@return A bit set containing the device characteristics.
  1.2000 +	    
  1.2001 +@panic Sqlite 19 In _DEBUG mode - TDbFile::iDeviceCharacteristics is negative or 0 .
  1.2002 +
  1.2003 +@see TDbFile
  1.2004 +@see TVfs::Open()
  1.2005 +*/
  1.2006 +/* static */ int TFileIo::DeviceCharacteristics(sqlite3_file* aDbFile)
  1.2007 +	{
  1.2008 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.2009 +	__OS_CALL(EOsFileDeviceCharacteristics, 0, 0);
  1.2010 +	__OSTIME_COUNTER(TheOsCallTicks[EOsFileDeviceCharacteristics], ::OsCallProfile(dbFile.iIsJournal, EOsFileDeviceCharacteristics), 0, 0, aDbFile, 0);
  1.2011 +	__ASSERT_DEBUG(dbFile.iDeviceCharacteristics >= 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.2012 +	return dbFile.iDeviceCharacteristics;	
  1.2013 +	}
  1.2014 +
  1.2015 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2016 +///////////////////////////////////       TVfs class definition     ///////////////////////////////////////////////////////////
  1.2017 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2018 +
  1.2019 +
  1.2020 +/**
  1.2021 +Opens a private secure database.
  1.2022 +Actually the database file has been created or opened by the client's process. 
  1.2023 +This function only adopts the passed in aMsg parameter file handle.
  1.2024 +
  1.2025 +@param aDbFile 		Output parameter, where the initialized file handle will be stored.
  1.2026 +@param aMsg    		A reference to the current RMessage2 instance. Contains the file handle of the database created
  1.2027 +					or opened by the client's process.
  1.2028 +@param aReadOnly	True if the file is read-only.
  1.2029 +
  1.2030 +@return KErrNone,          The operation has completed succesfully;
  1.2031 +	    KErrNoMemory,      Out of memory condition has occured;
  1.2032 +                           Note that other system-wide error codes may also be returned.
  1.2033 +	    
  1.2034 +@see TDbFile
  1.2035 +@see TVfs::Open()
  1.2036 +*/
  1.2037 +/* static */ TInt TVfs::DoOpenFromHandle(TDbFile& aDbFile, const RMessage2& aMsg, TBool aReadOnly)
  1.2038 +	{
  1.2039 +	__FS_CALL(EFsOpFileAdopt, 0);
  1.2040 +	TInt err = aDbFile.iFileBuf.AdoptFromClient(aMsg, KFhSessHandleIdx, KFhFileHandleIdx);
  1.2041 +	if(err == KErrNone)
  1.2042 +		{
  1.2043 +		aDbFile.iReadOnly = aReadOnly;
  1.2044 +		}
  1.2045 +	return err;
  1.2046 +	};
  1.2047 +
  1.2048 +/**
  1.2049 +Collects information about the drive referred by the aDriveNo parameter.
  1.2050 +
  1.2051 +@param aFs			RFs instance.
  1.2052 +@param aDriveNo     The drive about which an information will be collected.
  1.2053 +@param aVolumeInfo	Output parameter. A reference to a TVolumeIOParamInfo object where the collected information will be stored.
  1.2054 +
  1.2055 +@return KErrNone,          The operation has completed succesfully;
  1.2056 +	    KErrNoMemory,      Out of memory condition has occured;
  1.2057 +                           Note that other system-wide error codes may also be returned.
  1.2058 +	    
  1.2059 +@see TVfs::Open()
  1.2060 +*/
  1.2061 +/* static */ inline TInt TVfs::DoGetVolumeIoParamInfo(RFs& aFs, TInt aDriveNo, TVolumeIOParamInfo& aVolumeInfo)
  1.2062 +	{
  1.2063 +	__FS_CALL(EFsOpFsVolumeIoParam, 0);
  1.2064 +	TInt err = aFs.VolumeIOParam(aDriveNo, aVolumeInfo); 
  1.2065 +	SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_DOGETVOLUMEIOPARAMINFO, "OS;0;TVfs::DoGetVolumeIoParamInfo;aDriveNo=%d;err=%d", aDriveNo, err));
  1.2066 +	return err;		
  1.2067 +	}
  1.2068 +
  1.2069 +//Maps disk sector sizes to SQLITE_IOCAP_ATOMIC<n> constants
  1.2070 +
  1.2071 +struct TSqliteSectorSizeMap
  1.2072 +	{
  1.2073 +	TInt	iSectorSize;
  1.2074 +	TInt	iSqliteSectorSizeConstant;
  1.2075 +	};
  1.2076 +
  1.2077 +//Used in TVfs::DoGetDeviceCharacteristics() to find which SQLITE_IOCAP_ATOMIC<n> constant should be used
  1.2078 +//for the specified sector size
  1.2079 +const TSqliteSectorSizeMap KSqliteSectorSizeMap[] = 
  1.2080 +	{
  1.2081 +		{  512, SQLITE_IOCAP_ATOMIC512},		
  1.2082 +		{ 1024, SQLITE_IOCAP_ATOMIC1K},			
  1.2083 +		{ 2048, SQLITE_IOCAP_ATOMIC2K},			
  1.2084 +		{ 4096, SQLITE_IOCAP_ATOMIC4K},			
  1.2085 +		{ 8192, SQLITE_IOCAP_ATOMIC8K},		
  1.2086 +		{16384, SQLITE_IOCAP_ATOMIC16K},			
  1.2087 +		{32768, SQLITE_IOCAP_ATOMIC32K},			
  1.2088 +		{65536, SQLITE_IOCAP_ATOMIC64K}			
  1.2089 +	};
  1.2090 +
  1.2091 +/**
  1.2092 +Retrieves and returns in a bit set the device characteristics.
  1.2093 +
  1.2094 +@param aDriveInfo	A TDriveInfo reference from which the device characteristics will be extracted.
  1.2095 +@param aVolumeInfo	A TVolumeIOParamInfo reference from which the device characteristics will be extracted.
  1.2096 +
  1.2097 +@return A bit set containing the device characteristics: 
  1.2098 +			SQLITE_IOCAP_SAFE_APPEND, SQLITE_IOCAP_ATOMIC, the atomic block size.
  1.2099 +	    
  1.2100 +@see TVfs::DoGetVolumeIoParamInfo();
  1.2101 +@see TVfs::Open()
  1.2102 +*/
  1.2103 +/* static */ TInt TVfs::DoGetDeviceCharacteristics(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo)
  1.2104 +	{
  1.2105 +	TInt deviceCharacteristics = 0;	
  1.2106 +	if(aDriveInfo.iDriveAtt & (KDriveAttLocal | KDriveAttInternal))
  1.2107 +		{
  1.2108 +		deviceCharacteristics |= SQLITE_IOCAP_SAFE_APPEND;//Data written first, file size updated second
  1.2109 +		}
  1.2110 +	if(aDriveInfo.iDriveAtt & KDriveAttTransaction)
  1.2111 +		{
  1.2112 +		deviceCharacteristics |= SQLITE_IOCAP_ATOMIC;	
  1.2113 +		}
  1.2114 +	for(TInt i=0;i<(sizeof(KSqliteSectorSizeMap)/sizeof(KSqliteSectorSizeMap[0]));++i)
  1.2115 +		{
  1.2116 +		if(KSqliteSectorSizeMap[i].iSectorSize == aVolumeInfo.iBlockSize)
  1.2117 +			{
  1.2118 +			deviceCharacteristics |= KSqliteSectorSizeMap[i].iSqliteSectorSizeConstant;
  1.2119 +			break;
  1.2120 +			}
  1.2121 +		}
  1.2122 +	return deviceCharacteristics;
  1.2123 +	}
  1.2124 +
  1.2125 +/**
  1.2126 +Retrieves and returns the sector size of the drive referred by the aDriveInfo parameter.
  1.2127 +The sector size must be a power of two.
  1.2128 +The sector size is extracted only if aDriveInfo refers to a removable device, otherwise the
  1.2129 +SQLITE_DEFAULT_SECTOR_SIZE value (512 bytes) will be used as a sector size.
  1.2130 +
  1.2131 +@param aDriveInfo	A TDriveInfo reference.
  1.2132 +@param aVolumeInfo	A TVolumeIOParamInfo reference.
  1.2133 +
  1.2134 +@return The sector size of the drive referred by the aDriveInfo parameter.
  1.2135 +
  1.2136 +@panic Sqlite 19 In _DEBUG mode - The sector size is negative, zero or is not a power of two.
  1.2137 +	    
  1.2138 +@see TVfs::Open()
  1.2139 +*/
  1.2140 +/* static */ TInt TVfs::DoGetSectorSize(const TDriveInfo& aDriveInfo, const TVolumeIOParamInfo& aVolumeInfo)
  1.2141 +	{
  1.2142 +	//Initialize the sectorSize variable only if: 
  1.2143 +	// - aDriveInfo refers to a removable drive
  1.2144 +	// - aVolumeInfo.iBlockSize > SQLITE_DEFAULT_SECTOR_SIZE;
  1.2145 +	// - aVolumeInfo.iBlockSize is power of 2;
  1.2146 +	TInt sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
  1.2147 +	if(aDriveInfo.iDriveAtt & KDriveAttRemovable)
  1.2148 +		{
  1.2149 +		if(aVolumeInfo.iBlockSize > SQLITE_DEFAULT_SECTOR_SIZE && (aVolumeInfo.iBlockSize & (aVolumeInfo.iBlockSize - 1)) == 0)
  1.2150 +			{
  1.2151 +			sectorSize = aVolumeInfo.iBlockSize;
  1.2152 +			}
  1.2153 +		}
  1.2154 +	__ASSERT_DEBUG(sectorSize > 0 && (sectorSize & (sectorSize - 1)) == 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.2155 +	return sectorSize;
  1.2156 +	}
  1.2157 +
  1.2158 +/**
  1.2159 +Retrieves in a bit set the device characteristics of the device of the file referred by the aDbFile parameter.
  1.2160 +Retrieves the sector size of the drive of the file referred by the aDbFile parameter. 
  1.2161 +The sector size and the device characteristics will be stored in iSectorSize and iDeviceCharacteristics TDbFile data members.
  1.2162 +The stored values will be used later by TFileIo::DeviceCharacteristics() and TFileIo::SectorSize().
  1.2163 +
  1.2164 +@param aDbFile	Input/Output parameter. A TDriveInfo reference. The collected information will be stored in TDbDrive
  1.2165 +				data members.
  1.2166 +@param aRecReadBufSize Output parameter. The recommended buffer size for optimised reading performance.
  1.2167 +
  1.2168 +@return KErrNone,          The operation has completed succesfully;
  1.2169 +                           Note that other system-wide error codes may also be returned.
  1.2170 +
  1.2171 +@panic Sqlite 19 In _DEBUG mode - TDbFile::iSectorSize has been already initialized.
  1.2172 +@panic Sqlite 19 In _DEBUG mode - TDbFile::iDeviceCharacteristics has been already initialized.
  1.2173 +
  1.2174 +@see TVfs::DoGetDeviceCharacteristics();
  1.2175 +@see TVfs::DoGetSectorSize();
  1.2176 +@see TVfs::Open()
  1.2177 +@see TDbFile
  1.2178 +@see TFileIo::DeviceCharacteristics()
  1.2179 +@see TFileIo::SectorSize()
  1.2180 +*/
  1.2181 +/* static */ TInt TVfs::DoGetDeviceCharacteristicsAndSectorSize(TDbFile& aDbFile, TInt& aRecReadBufSize)
  1.2182 +	{
  1.2183 +	__ASSERT_DEBUG(aDbFile.iDeviceCharacteristics < 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.2184 +	__ASSERT_DEBUG(aDbFile.iSectorSize <= 0, __SQLITEPANIC2(ESqliteOsPanicInternalError));
  1.2185 +	TInt driveNo;
  1.2186 +	TDriveInfo driveInfo;
  1.2187 +	__FS_CALL(EFsOpFileDrive, 0);
  1.2188 +	TInt err = aDbFile.iFileBuf.Drive(driveNo, driveInfo);
  1.2189 +	if(err != KErrNone)
  1.2190 +		{
  1.2191 +		return err;	
  1.2192 +		}
  1.2193 +	TVolumeIOParamInfo volumeInfo;
  1.2194 +	err = TVfs::DoGetVolumeIoParamInfo(COsLayerData::Instance().iFs, driveNo, volumeInfo);
  1.2195 +	if(err != KErrNone)
  1.2196 +		{
  1.2197 +		return err;	
  1.2198 +		}
  1.2199 +	aDbFile.iDeviceCharacteristics = TVfs::DoGetDeviceCharacteristics(driveInfo, volumeInfo);
  1.2200 +	aDbFile.iSectorSize = TVfs::DoGetSectorSize(driveInfo, volumeInfo);
  1.2201 +	aRecReadBufSize = volumeInfo.iRecReadBufSize;
  1.2202 +	SQLITE_TRACE_OS(OstTraceExt5(TRACE_INTERNALS, TVFS_DOGETGETDEVICECHARACTERISTICSANDSECTORSIZE, "OS;0x%X;TVfs::DoGetDeviceCharacteristicsAndSectorSize;driveNo=%d;sectorSize=%d;devCharact=0x%X;readBufSize=%d", (TUint)&aDbFile, driveNo, aDbFile.iSectorSize, (TUint)aDbFile.iDeviceCharacteristics, volumeInfo.iRecReadBufSize));
  1.2203 +	return KErrNone;
  1.2204 +	}
  1.2205 +
  1.2206 +/**
  1.2207 +SQLite OS porting layer API.
  1.2208 +
  1.2209 +The behaviour of the RFile/RFile64::SetSize operation is not atomic for non-rugged drives. 
  1.2210 +When RFile/RFile64::SetSize() is called 2 operations occurs:-
  1.2211 +
  1.2212 +1)The cluster chain of the file is updated.
  1.2213 +2)The new file size is added to the file cache.
  1.2214 +
  1.2215 +If a power loss occurs after a SetSize there is a chance that the cluster chain was updated 
  1.2216 +but the new file size is not yet flushed to the file. This puts the file into an inconsistent state.
  1.2217 +This is most likely to occur in the journal file where the time between a SetSize and Flush can 
  1.2218 +be long. 
  1.2219 +
  1.2220 +For this reason this check is added when the file is opened to see if the end of the file can 
  1.2221 +be read straight away, if an error is returned then it is assumed that the SetSize has not be 
  1.2222 +completed previously. In this case the file is deleted and re-created.
  1.2223 + 
  1.2224 +@param aDbFile A pointer to a TDbFile instance, that contains the file handle.
  1.2225 +@param aFname A string of 16-bit wide characters containing name of the file to be checked.
  1.2226 +@param aFmode The mode in which the file is opened. These mode are documented in TFileMode.
  1.2227 +
  1.2228 +@return KErrNone,          The operation has completed succesfully;
  1.2229 +                           Note that other system-wide error codes may also be returned.
  1.2230 +@see TFileMode
  1.2231 +@see TVfs::Open()
  1.2232 +@see TDbFile
  1.2233 +*/
  1.2234 +/* static */ TInt TVfs::DoFileSizeCorruptionCheck(TDbFile& aDbFile, const TDesC& aFname, TInt aFmode)
  1.2235 +    {
  1.2236 +    const TInt KMinSize = 16;
  1.2237 +    TInt64 size;
  1.2238 +    TInt err = KErrNone ;
  1.2239 +    TBuf8<KMinSize> buf;
  1.2240 +
  1.2241 +    err = aDbFile.iFileBuf.Size(size);
  1.2242 +    if (err != KErrNone)
  1.2243 +        {
  1.2244 +        return err;
  1.2245 +        }
  1.2246 +    TBool IsMinFileSize = (size >= KMinSize);
  1.2247 +    
  1.2248 +    if (IsMinFileSize)
  1.2249 +        {
  1.2250 +        err = aDbFile.iFileBuf.Read(size - KMinSize, buf);
  1.2251 +        }
  1.2252 +    
  1.2253 +    if (err == KErrCorrupt || err == KErrEof || !IsMinFileSize)
  1.2254 +        {
  1.2255 +        COsLayerData& osLayerData = COsLayerData::Instance();
  1.2256 +    
  1.2257 +        aDbFile.iFileBuf.Close();
  1.2258 +        __SQLITETRACE_OSEXPR(TInt err2 =) osLayerData.iFs.Delete(aFname);
  1.2259 +		SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TVFS_DOFILESIZECORRUPTIONCHECK1, "OS;0x%X;TVfs::DoFileSizeCorruptionCheck;size=%lld;err=%d;deleteErr=%d", (TUint)&aDbFile, size, err, err2));
  1.2260 +        err = aDbFile.iFileBuf.Create(osLayerData.iFs, aFname, aFmode);
  1.2261 +		SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_DOFILESIZECORRUPTIONCHECK2, "OS;0x%X;TVfs::DoFileSizeCorruptionCheck;createErr=%d", (TUint)&aDbFile, err));
  1.2262 +        }
  1.2263 +    return err;
  1.2264 +    }
  1.2265 +
  1.2266 +/**
  1.2267 +SQLite OS porting layer API.
  1.2268 +
  1.2269 +Opens or creates a file which name is in the aFileName parameter.
  1.2270 +If the function succeeds, the file handle and other related information will be stored in the place pointed by the 
  1.2271 +aDbFile parameter, a memory block of sizeof(TDbFile) size for which is allocated by the caller.
  1.2272 +The function will also retrieve the sector size and the device characteristics and store them in aDbFile,
  1.2273 +which is actually a TDbFile pointer, for later use.
  1.2274 +
  1.2275 +@param aFileName Zero-terminated, UTF8 encoded file name.
  1.2276 +				 If aFileName is NULL then a temporary file is created.
  1.2277 +@param aDbFile Output parameter. The file handle and other related information will be stored there.
  1.2278 +@param aFlags  "Open/Create" input flags: 
  1.2279 +					SQLITE_OPEN_DELETEONCLOSE,
  1.2280 +					SQLITE_OPEN_READWRITE,
  1.2281 +					SQLITE_OPEN_EXCLUSIVE,
  1.2282 +					SQLITE_OPEN_CREATE
  1.2283 +@param aOutFlags  "Open/Create" output flags:
  1.2284 +					SQLITE_OPEN_READWRITE,
  1.2285 +					SQLITE_OPEN_READONLY
  1.2286 +
  1.2287 +@return SQLITE_CANTOPEN,    The aFileName parameter cannot be converted to UTF16.
  1.2288 +							Any other file I/O error will also be reported as SQLITE_CANTOPEN;
  1.2289 +	    SQLITE_IOERR_NOMEM,	An out of memory condition has occured;
  1.2290 +	    SQLITE_OK,			The operation has completed successfully.
  1.2291 +	    
  1.2292 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.2293 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.2294 +
  1.2295 +@see COsLayerData::SetOsErrorCode()
  1.2296 +@see TDbFile
  1.2297 +*/
  1.2298 +/* static */ int TVfs::Open(sqlite3_vfs* aVfs, const char* aFileName, sqlite3_file* aDbFile, int aFlags, int* aOutFlags)
  1.2299 +	{
  1.2300 +	__OS_CALL(EOsVfsOpen, 0, 0);
  1.2301 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsOpen], ::OsCallProfile(EFalse, EOsVfsOpen), 0, 0, aDbFile, aFileName);
  1.2302 +	COsLayerData& osLayerData = COsLayerData::Instance();
  1.2303 +	new (aDbFile) TDbFile;
  1.2304 +	TDbFile& dbFile = ::DbFile(aDbFile);
  1.2305 +    if(!aFileName)
  1.2306 +        {  
  1.2307 +        //It is to create and open a temp file if aFileName is NULL. In this case,
  1.2308 +        //we will defer the file creation util it is needed.  
  1.2309 +        dbFile.pMethods = &TheFileIoApi;
  1.2310 +        dbFile.iIsFileCreated = EFalse;
  1.2311 +        if(aOutFlags)
  1.2312 +            {
  1.2313 +            *aOutFlags = SQLITE_OPEN_READWRITE;
  1.2314 +            }
  1.2315 +		osLayerData.SetOsErrorCode(KErrNone);
  1.2316 +        return SQLITE_OK;
  1.2317 +        }  
  1.2318 +	TFileName fname;
  1.2319 +    if(!::ConvertToUnicode(aFileName, fname))
  1.2320 +		{
  1.2321 +        osLayerData.SetOsErrorCode(KErrBadName);
  1.2322 +        return SQLITE_CANTOPEN;	
  1.2323 +    	}
  1.2324 +	SQLITE_TRACE_OS(OstTraceExt3(TRACE_INTERNALS, TVFS_OPEN_ENTRY, "OS-Entry;0x%X;TVfs::Open;fname=%S;aFlags=0x%X", (TUint)&aDbFile, __SQLITEPRNSTR(fname), (TUint)aFlags));
  1.2325 +	TFhStrType fhStrType = aFileName ? ::FhStringProps(aFileName) : ENotFhStr;
  1.2326 +	TInt err = KErrNone;
  1.2327 +	if(fhStrType == EFhMainDbStr)
  1.2328 +		{//Main db file, open from handle
  1.2329 +		const RMessage2* msg;
  1.2330 +		TBool readOnly;
  1.2331 +		osLayerData.RetrieveAndResetFhData(msg, readOnly);
  1.2332 +		err = msg != NULL ? TVfs::DoOpenFromHandle(dbFile, *msg, readOnly) : KErrGeneral;
  1.2333 +		}
  1.2334 +	else
  1.2335 +		{
  1.2336 +		if(fhStrType == EFhStr)
  1.2337 +			{//Not the main db file. Remove invalid characters in the file name
  1.2338 +			::FhConvertToFileName(fname, osLayerData.iSysPrivDir);//If fname does not have a path, iSysPrivDir will be used
  1.2339 +			}
  1.2340 +		TInt fmode = EFileRead;
  1.2341 +		if(aFlags & SQLITE_OPEN_READWRITE)
  1.2342 +			{
  1.2343 +			fmode |= EFileWrite;
  1.2344 +			}
  1.2345 +		if(aFlags & SQLITE_OPEN_EXCLUSIVE)
  1.2346 +			{
  1.2347 +			fmode |= EFileShareExclusive;
  1.2348 +			}
  1.2349 +		if(aFlags & SQLITE_OPEN_DELETEONCLOSE)
  1.2350 +			{
  1.2351 +			fmode |= EDeleteOnClose;
  1.2352 +			}
  1.2353 +		err = KErrAccessDenied;
  1.2354 +		TInt prevErr = KErrNone;
  1.2355 +		if(aFlags & SQLITE_OPEN_CREATE)
  1.2356 +			{
  1.2357 +			__FS_CALL(EFsOpFileCreate, 0);
  1.2358 +			prevErr = err = dbFile.iFileBuf.Create(osLayerData.iFs, fname, fmode);
  1.2359 +			}
  1.2360 +		if(err != KErrNone && err != KErrNoMemory && err != KErrDiskFull)
  1.2361 +			{
  1.2362 +			__FS_CALL(EFsOpFileOpen, 0);
  1.2363 +			err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  1.2364 +
  1.2365 +			if(err == KErrNone && (aFlags & KJournalFileTypeBitMask))
  1.2366 +				{
  1.2367 +				err = TVfs::DoFileSizeCorruptionCheck(dbFile, fname, fmode);
  1.2368 +				}
  1.2369 +			}
  1.2370 +		if((err != KErrNone && err != KErrNoMemory && err != KErrDiskFull) && (aFlags & SQLITE_OPEN_READWRITE))
  1.2371 +			{
  1.2372 +			aFlags &= ~SQLITE_OPEN_READWRITE;
  1.2373 +			aFlags |= SQLITE_OPEN_READONLY;
  1.2374 +			fmode &= ~EFileWrite;
  1.2375 +			__FS_CALL(EFsOpFileOpen, 0);
  1.2376 +			err = dbFile.iFileBuf.Open(osLayerData.iFs, fname, fmode);
  1.2377 +			}
  1.2378 +		if(err != KErrNone && prevErr == KErrAccessDenied)
  1.2379 +			{
  1.2380 +			err = KErrAccessDenied;
  1.2381 +			}
  1.2382 +		}
  1.2383 +	TInt recReadBufSize = -1;
  1.2384 +	if(err == KErrNone)
  1.2385 +		{
  1.2386 +		err = TVfs::DoGetDeviceCharacteristicsAndSectorSize(dbFile, recReadBufSize);
  1.2387 +		}
  1.2388 +	osLayerData.SetOsErrorCode(err);
  1.2389 +	if(err != KErrNone)
  1.2390 +		{
  1.2391 +		__FS_CALL(EFsOpFileClose, 0);
  1.2392 +		dbFile.iFileBuf.Close();	
  1.2393 +		}
  1.2394 +	else
  1.2395 +		{
  1.2396 +		dbFile.pMethods = &TheFileIoApi;
  1.2397 +		if(fhStrType != EFhMainDbStr)
  1.2398 +			{
  1.2399 +			dbFile.iReadOnly = !(aFlags & SQLITE_OPEN_READWRITE);
  1.2400 +			}
  1.2401 +		if(aOutFlags)
  1.2402 +			{
  1.2403 +			*aOutFlags = dbFile.iReadOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE;
  1.2404 +			}
  1.2405 +		(void)dbFile.iFileBuf.SetReadAheadSize(dbFile.iSectorSize, recReadBufSize);
  1.2406 +		}
  1.2407 +#ifdef _SQLPROFILER
  1.2408 +	dbFile.iIsJournal = aFlags & KJournalFileTypeBitMask; 
  1.2409 +#endif
  1.2410 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_CANTOPEN);
  1.2411 +	SQLITE_TRACE_OS(OstTraceExt4(TRACE_INTERNALS, TVFS_OPEN_EXIT, "OS-Exit;0x%X;TVfs::Open;outFlags=0x%X;err=%d;sqliteErr=%d", (TUint)&aDbFile, aOutFlags ? (TUint)*aOutFlags : 0, err, sqliteErr));
  1.2412 +	return sqliteErr;
  1.2413 +	}
  1.2414 +
  1.2415 +/**
  1.2416 +SQLite OS porting layer API.
  1.2417 +
  1.2418 +Deletes a file which name is in the aFileName parameter.
  1.2419 +
  1.2420 +@param aFileName Zero-terminated, UTF8 encoded file name.
  1.2421 +
  1.2422 +@return SQLITE_ERROR,    	The aFileName parameter cannot be converted to UTF16.
  1.2423 +							The file name refers to a private secure database;
  1.2424 +	    SQLITE_IOERR_NOMEM,	An out of memory condition has occured;
  1.2425 +	    SQLITE_IOERR_DELETE,The delete file operation has failed;
  1.2426 +	    SQLITE_OK,			The operation has completed successfully.
  1.2427 +	    
  1.2428 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.2429 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.2430 +
  1.2431 +@see COsLayerData::SetOsErrorCode()
  1.2432 +*/
  1.2433 +/* static */ int TVfs::Delete(sqlite3_vfs* aVfs, const char* aFileName, int /*aSyncDir*/)
  1.2434 +	{
  1.2435 +	__OS_CALL(EOsVfsDelete, 0, 0);
  1.2436 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsDelete], ::OsCallProfile(EFalse, EOsVfsDelete), 0, 0, 0, aFileName);
  1.2437 +	COsLayerData& osLayerData = COsLayerData::Instance();
  1.2438 +	TBuf<KMaxFileName + 1> fname;
  1.2439 +	if(!::ConvertToUnicode(aFileName, fname))
  1.2440 +		{
  1.2441 +		osLayerData.SetOsErrorCode(KErrBadName);
  1.2442 +		SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_DELETE1, "OS;0;TVfs::Delete;err=KErrBadName"));
  1.2443 +		return SQLITE_ERROR;	
  1.2444 +		}
  1.2445 +	SQLITE_TRACE_OS(OstTraceExt1(TRACE_INTERNALS, TVFS_DELETE_ENTRY, "OS-Entry;0;TVfs::Delete;fname=%S", __SQLITEPRNSTR(fname)));
  1.2446 +	TFhStrType fhStrType = FhStringProps(aFileName);
  1.2447 +	if(fhStrType == EFhMainDbStr)
  1.2448 +		{//Deleting files not in your own private data cage - not allowed!
  1.2449 +		osLayerData.SetOsErrorCode(KErrPermissionDenied);
  1.2450 +		SQLITE_TRACE_OS(OstTraceExt1(TRACE_INTERNALS, TVFS_DELETE2, "OS;0;TVfs::Delete;err=KErrPermissionDenied;fname=%S", __SQLITEPRNSTR(fname)));
  1.2451 +		return SQLITE_ERROR;	
  1.2452 +		}
  1.2453 +	if(fhStrType == EFhStr)
  1.2454 +		{
  1.2455 +		::FhConvertToFileName(fname, osLayerData.iSysPrivDir);//If fname does not have a path, iSysPrivDir will be used
  1.2456 +		}
  1.2457 +	__FS_CALL(EFsOpFileDelete, 0);
  1.2458 +	TInt err = osLayerData.iFs.Delete(fname);
  1.2459 +	osLayerData.SetOsErrorCode(err);
  1.2460 +	TInt sqliteErr = ::Os2SqliteErr(err, SQLITE_IOERR_DELETE);	
  1.2461 +	SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_DELETE_EXIT, "OS-Exit;0;TVfs::Delete;err=%d;sqliteErr=%d", err, sqliteErr));
  1.2462 +	return sqliteErr;
  1.2463 +	}
  1.2464 +
  1.2465 +/**
  1.2466 +SQLite OS porting layer API.
  1.2467 +
  1.2468 +Retrieves an information about a file which name is in the aFileName parameter.
  1.2469 +The requested information type can be: does the file exist, is the file read-only or read/write.
  1.2470 +
  1.2471 +@param aFileName Zero-terminated, UTF8 encoded file name.
  1.2472 +@param aFlags This parameter can be one of: SQLITE_ACCESS_READ, SQLITE_ACCESS_EXISTS or SQLITE_ACCESS_READWRITE.
  1.2473 +@param aResOut Output parameter, set to 1 if the tested condition is true, 0 otherwise.
  1.2474 +
  1.2475 +@return SQLITE_OK, 			The call has completed successfully,
  1.2476 +		SQLITE_IOERR_NOMEM, An out of memory conditon has occured,
  1.2477 +		SQLITE_IOERR_ACCESS,File I/O error;  
  1.2478 +	    
  1.2479 +If the function succeeds, COsLayerData::SetOsErrorCode() is called with KErrNone, otherwise COsLayerData::SetOsErrorCode() is called
  1.2480 +with the reported by the OS API error. The stored error code will be used later by the SQLite API caller.
  1.2481 +
  1.2482 +@see COsLayerData::SetOsErrorCode()
  1.2483 +*/
  1.2484 +/* static */ int TVfs::Access(sqlite3_vfs* aVfs, const char* aFileName, int aFlags, int* aResOut)
  1.2485 +	{
  1.2486 +	__OS_CALL(EOsVfsAccess, 0, 0);
  1.2487 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsAccess], ::OsCallProfile(EFalse, EOsVfsAccess), aFlags, 0, 0, aFileName);
  1.2488 +	COsLayerData& osLayerData = COsLayerData::Instance();
  1.2489 +	TBuf<KMaxFileName + 1> fname;
  1.2490 +	if(!::ConvertToUnicode(aFileName, fname))
  1.2491 +		{
  1.2492 +		osLayerData.SetOsErrorCode(KErrGeneral);
  1.2493 +		SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_ACCESS1, "OS;0;TVfs::Access;err=KErrGeneral"));
  1.2494 +		return SQLITE_IOERR_ACCESS;
  1.2495 +		}
  1.2496 +	SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_ACCESS_ENTRY, "OS-Entry;0;TVfs::Access;fname=%S;aFlags=0x%X", __SQLITEPRNSTR(fname), (TUint)aFlags));
  1.2497 +	TFhStrType fhStrType = ::FhStringProps(aFileName);
  1.2498 +	if(fhStrType == EFhStr)
  1.2499 +		{
  1.2500 +		::FhConvertToFileName(fname, osLayerData.iSysPrivDir);//If fname does not have a path, iSysPrivDir will be used
  1.2501 +		}
  1.2502 +	TEntry entry;
  1.2503 +	__FS_CALL(EFsOpFsEntry, 0);
  1.2504 +	TInt err = osLayerData.iFs.Entry(fname, entry);
  1.2505 +	if(aFlags == SQLITE_ACCESS_EXISTS && err == KErrNotFound)
  1.2506 +		{
  1.2507 +		osLayerData.SetOsErrorCode(KErrNone);
  1.2508 +		*aResOut = 0;
  1.2509 +		SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_ACCESS_EXIT1, "OS-Exit;0;TVfs::Access;Exists-NoFound"));
  1.2510 +		return SQLITE_OK;
  1.2511 +		}
  1.2512 +	if(err != KErrNone)
  1.2513 +		{
  1.2514 +		osLayerData.SetOsErrorCode(err);
  1.2515 +		SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TVFS_ACCESS_EXIT2, "OS-Exit;0;TVfs::Access;err=%d", err));
  1.2516 +		return err == KErrNoMemory ? SQLITE_IOERR_NOMEM : SQLITE_IOERR_ACCESS;
  1.2517 +		}
  1.2518 +	*aResOut = 0;
  1.2519 +	switch(aFlags)
  1.2520 +		{
  1.2521 +		case SQLITE_ACCESS_READ:
  1.2522 +			*aResOut =  entry.IsReadOnly();
  1.2523 +			break;
  1.2524 +		case SQLITE_ACCESS_EXISTS:
  1.2525 +			*aResOut = 1;
  1.2526 +			break;
  1.2527 +		case SQLITE_ACCESS_READWRITE:
  1.2528 +			*aResOut = !entry.IsReadOnly();
  1.2529 +			break;
  1.2530 +		default:
  1.2531 +			break;			
  1.2532 +		}
  1.2533 +	osLayerData.SetOsErrorCode(KErrNone);
  1.2534 +	SQLITE_TRACE_OS(OstTrace1(TRACE_INTERNALS, TVFS_ACCESS_EXIT3, "OS-Exit;0;TVfs::Access;aResOut=%d", *aResOut));
  1.2535 +	return SQLITE_OK;
  1.2536 +	}
  1.2537 +
  1.2538 +/**
  1.2539 +SQLite OS porting layer API.
  1.2540 +
  1.2541 +Accepts UTF8 encoded, zero-terminated file as an input argument in the aRelative parameter
  1.2542 +and constructs the full file path in the aBuf output parameter.
  1.2543 +
  1.2544 +If the format of aRelative argument is <[SID]FileName.[EXT]>, then the database file name will be 
  1.2545 +treated as a name of a secure database file which has to be created/opened in the server's private 
  1.2546 +directory on the system drive.
  1.2547 +
  1.2548 +If the format of aRelative argument is <Drive:[SID]FileName.[EXT]>, then the database file name 
  1.2549 +will be treated as a name of a secure database file which has to be created/opened in the server's 
  1.2550 +private directory on <Drive:> drive. 
  1.2551 +
  1.2552 +If the format of aRelative argument is <Drive:\Path\FileName.[EXT]>, then the database file name
  1.2553 +will be treated as a name of a non-secure database file in <Drive:\Path\> directory.
  1.2554 +If aRelative contains file handles, then it will be treated as a name of a file belonging to server's
  1.2555 +private data cage. 
  1.2556 +
  1.2557 +@param aRelative The input file name, zero-terminated, UTF8 encoded.
  1.2558 +@param aBufLen The output buffer length.
  1.2559 +@param aBuf Output buffer for the constructed full file name path. The allocated buffer length must be at least aBufLen bytes.
  1.2560 +
  1.2561 +@return SQLITE_ERROR, The aRelative parameter is NULL or cannot be converted to UTF16;
  1.2562 +		SQLITE_OK The operation has completed successfully.
  1.2563 +*/
  1.2564 +/* static */ int TVfs::FullPathName(sqlite3_vfs* aVfs, const char* aRelative, int aBufLen, char* aBuf)
  1.2565 +	{
  1.2566 +	__OS_CALL(EOsVfsFullPathName, 0, 0);
  1.2567 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsFullPathName], ::OsCallProfile(EFalse, EOsVfsFullPathName), aBufLen, 0, 0, aRelative);
  1.2568 +	COsLayerData& osLayerData = COsLayerData::Instance();
  1.2569 +	osLayerData.StoreFhData(NULL, EFalse);
  1.2570 +	//Convert the received file name to UTF16
  1.2571 +	TBuf<KMaxFileName + 1> fname;
  1.2572 +	if(!::ConvertToUnicode(aRelative, fname))
  1.2573 +		{
  1.2574 +		SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME1, "OS;0;TVfs::FullPathName;err=SQLITE_ERROR"));
  1.2575 +		return SQLITE_ERROR;
  1.2576 +		}
  1.2577 +	SQLITE_TRACE_OS(OstTraceExt2(TRACE_INTERNALS, TVFS_FULLPATHNAME_ENTRY, "OS-Entry;0;TVfs::FullPathName;fname=%S;aBufLen=%d", __SQLITEPRNSTR(fname), aBufLen));
  1.2578 +	//Zero-terminate the converted file name
  1.2579 +	fname.Append(TChar(0));
  1.2580 +	TParse parse;
  1.2581 +	TFhStrType strType = ::FhStringProps(aRelative);//Detect string type - it may not be a real file name
  1.2582 +	if(strType == EFhMainDbStr)
  1.2583 +		{//The additonal information has to be extracted and fname reformatted, because SQLITE will
  1.2584 +		 //use the returned full file name when making a decission to share the cache.
  1.2585 +		::FhExtractAndStore(fname);
  1.2586 +		(void)parse.Set(fname, 0, 0);//the file name has to be verified by the file server
  1.2587 +		}
  1.2588 +	else
  1.2589 +		{
  1.2590 +		(void)parse.Set(fname, &osLayerData.iSysPrivDir, 0);//If fname does not have a path, iSysPrivDir will be used
  1.2591 +		}
  1.2592 +	TPtr8 dest8(reinterpret_cast <TUint8*> (aBuf), aBufLen);	
  1.2593 +	if(!::ConvertFromUnicode(parse.FullName(), dest8))
  1.2594 +		{//Zero the stored fh data, because it has been initialized by the FhExtractAndStore(fname) call (couple of lines above)
  1.2595 +		osLayerData.StoreFhData(NULL, EFalse);
  1.2596 +		SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME_EXIT1, "OS-Exit;0;TVfs::FullPathName;err=SQLITE_ERROR"));
  1.2597 +		return SQLITE_ERROR;	
  1.2598 +		}
  1.2599 +	SQLITE_TRACE_OS(OstTrace0(TRACE_INTERNALS, TVFS_FULLPATHNAME_EXIT2, "OS-Exit;0;TVfs::FullPathName;err=SQLITE_OK"));
  1.2600 +	return SQLITE_OK;
  1.2601 +	}
  1.2602 +
  1.2603 +/**
  1.2604 +SQLite OS porting layer API.
  1.2605 +
  1.2606 +Generates a set of random numbers and stores them in the aBuf output parameter.
  1.2607 +
  1.2608 +@param aBufLen The output buffer length.
  1.2609 +@param aBuf Output buffer for the generated random numbers. The allocated buffer length must be at least aBufLen bytes.
  1.2610 +
  1.2611 +@return The length of the used part of the output buffer.
  1.2612 +*/
  1.2613 +/* static */ int TVfs::Randomness(sqlite3_vfs* aVfs, int aBufLen, char* aBuf)
  1.2614 +	{
  1.2615 +	__OS_CALL(EOsVfsRandomness, 0, 0);
  1.2616 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsRandomness], ::OsCallProfile(EFalse, EOsVfsRandomness), aBufLen, 0, 0, 0);
  1.2617 +	COsLayerData& osLayerData = COsLayerData::Instance();
  1.2618 +	const TInt KRandIterations = aBufLen / sizeof(int);
  1.2619 +	for(TInt i=0;i<KRandIterations;++i)
  1.2620 +		{
  1.2621 +		TInt val = Math::Rand(osLayerData.iSeed);
  1.2622 +		Mem::Copy(&aBuf[i * sizeof(int)], &val, sizeof(val));
  1.2623 +		}
  1.2624 +	return KRandIterations * sizeof(int);
  1.2625 +	}
  1.2626 +
  1.2627 +/**
  1.2628 +SQLite OS porting layer API.
  1.2629 +
  1.2630 +Sleeps for aMicrosec microseconds.
  1.2631 +
  1.2632 +@param aMicrosec The sleep interval in microseconds.
  1.2633 +
  1.2634 +@return The aMicrosec value.
  1.2635 +*/
  1.2636 +/* static */ int TVfs::Sleep(sqlite3_vfs* aVfs, int aMicrosec)
  1.2637 +	{
  1.2638 +	__OS_CALL(EOsVfsSleep, 0, 0);
  1.2639 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsSleep], ::OsCallProfile(EFalse, EOsVfsSleep), aMicrosec, 0, 0, 0);
  1.2640 +	User::AfterHighRes(TTimeIntervalMicroSeconds32(aMicrosec));
  1.2641 +	return aMicrosec;
  1.2642 +	}
  1.2643 +
  1.2644 +/**
  1.2645 +SQLite OS porting layer API.
  1.2646 +
  1.2647 +Retrieves the current date and time.
  1.2648 +
  1.2649 +@param aNow Output parameter, where the data and time value will be stored.
  1.2650 +			SQLite processes all times and dates as Julian Day numbers and
  1.2651 +			aNow parameter will contain the julian date and time.
  1.2652 +
  1.2653 +@return 0.
  1.2654 +*/
  1.2655 +/* static */ int TVfs::CurrentTime(sqlite3_vfs* aVfs, double* aNow)
  1.2656 +	{
  1.2657 +	__OS_CALL(EOsVfsCurrentTime, 0, 0);
  1.2658 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsCurrentTime], ::OsCallProfile(EFalse, EOsVfsCurrentTime), 0, 0, 0, 0);
  1.2659 +	TTime now;
  1.2660 +	now.UniversalTime();
  1.2661 +	TDateTime date = now.DateTime();
  1.2662 +	TInt year = date.Year();
  1.2663 +	TInt month = date.Month() + 1;
  1.2664 +	TInt day = date.Day() + 1;
  1.2665 +	
  1.2666 +    //Calculate the Julian days
  1.2667 +	TInt jd = day - 32076 +
  1.2668 +	    1461*(year + 4800 + (month - 14)/12)/4 +
  1.2669 +	    367*(month - 2 - (month - 14)/12*12)/12 -
  1.2670 +	    3*((year + 4900 + (month - 14)/12)/100)/4;
  1.2671 +          	
  1.2672 +	*aNow = jd;
  1.2673 +
  1.2674 +    // Add the fractional hours, mins and seconds
  1.2675 +	*aNow += (date.Hour() + 12.0) / 24.0;
  1.2676 +	*aNow += date.Minute() / 1440.0;
  1.2677 +	*aNow += date.Second() / 86400.0;
  1.2678 +	
  1.2679 +	return 0;
  1.2680 +	}
  1.2681 +
  1.2682 +/**
  1.2683 +SQLite OS porting layer API.
  1.2684 +
  1.2685 +Retrieves a text description of the last OS error.
  1.2686 +Note: the method has a default "no-op" implementation at the moment. 
  1.2687 +
  1.2688 +@return 0.
  1.2689 +*/
  1.2690 +/* static */int TVfs::GetLastError(sqlite3_vfs* aVfs, int /*aBufLen*/, char* /*aBuf*/)
  1.2691 +	{
  1.2692 +	__OS_CALL(EOsVfsGetLastError, 0, 0);
  1.2693 +	__OSTIME_COUNTER(TheOsCallTicks[EOsVfsGetLastError], ::OsCallProfile(EFalse, EOsVfsGetLastError), 0, 0, 0, 0);
  1.2694 +	return 0;
  1.2695 +	}
  1.2696 +
  1.2697 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2698 +///////////////////////////////////       Memory allocation functions     /////////////////////////////////////////////////////
  1.2699 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2700 +
  1.2701 +/**
  1.2702 +SQLite OS porting layer API.
  1.2703 +
  1.2704 +Memory allocation routine.
  1.2705 +
  1.2706 +EXPORT_C required to match IMPORT_C in stdlib.h and avoid compiler warning
  1.2707 +
  1.2708 +@internalComponent
  1.2709 +*/
  1.2710 +extern "C" EXPORT_C void* sqlite3SymbianMalloc(size_t aSize)
  1.2711 +	{
  1.2712 +	__MEM_CALL(EMemOpAlloc, aSize, 0);
  1.2713 +	return Allocator().Alloc(aSize);
  1.2714 +	}
  1.2715 +
  1.2716 +/**
  1.2717 +SQLite OS porting layer API.
  1.2718 +
  1.2719 +Memory reallocation routine.
  1.2720 +
  1.2721 +EXPORT_C required to match IMPORT_C in stdlib.h and avoid compiler warning
  1.2722 +
  1.2723 +@internalComponent
  1.2724 +*/
  1.2725 +extern "C" EXPORT_C void* sqlite3SymbianRealloc(void* aPtr, size_t aSize)
  1.2726 +	{
  1.2727 +#ifdef _SQLPROFILER
  1.2728 +	TInt size = Allocator().AllocLen(aPtr);
  1.2729 +	__MEM_CALL(EMemOpRealloc, aSize, size);
  1.2730 +#endif
  1.2731 +	return Allocator().ReAlloc(aPtr, aSize);
  1.2732 +	}
  1.2733 +
  1.2734 +/**
  1.2735 +SQLite OS porting layer API.
  1.2736 +
  1.2737 +Memory free routine.
  1.2738 +
  1.2739 +EXPORT_C required to match IMPORT_C in stdlib.h and avoid compiler warning
  1.2740 +
  1.2741 +@internalComponent
  1.2742 +*/
  1.2743 +extern "C" EXPORT_C void sqlite3SymbianFree(void* aPtr)
  1.2744 +	{
  1.2745 +#ifdef _SQLPROFILER
  1.2746 +	TInt size = Allocator().AllocLen(aPtr);
  1.2747 +	__MEM_CALL(EMemOpFree, size, 0);
  1.2748 +#endif
  1.2749 +	Allocator().Free(aPtr);
  1.2750 +	}
  1.2751 +
  1.2752 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2753 +///////////////////////////////////       SQLite init/release functions     ///////////////////////////////////////////////////
  1.2754 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2755 +
  1.2756 +/**
  1.2757 +Registers the single sqlite3_vfs instance ("TheVfsApi" global variable) by calling sqlite3_vfs_register()
  1.2758 +*/
  1.2759 +extern "C" int sqlite3_os_init(void)
  1.2760 +	{
  1.2761 +	return sqlite3_vfs_register(&TheVfsApi, 1);//"1" means - make TheVfsApi to be the default VFS object
  1.2762 +	}
  1.2763 +
  1.2764 +/**
  1.2765 +Unregisters the single sqlite3_vfs instance ("TheVfsApi" global variable) by calling sqlite3_vfs_unregister()
  1.2766 +*/
  1.2767 +extern "C" int sqlite3_os_end(void)
  1.2768 +	{
  1.2769 +	return sqlite3_vfs_unregister(&TheVfsApi);
  1.2770 +	}
  1.2771 +
  1.2772 +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1.2773 +
  1.2774 +#endif//SQLITE_OS_SYMBIAN
  1.2775 +