blob: 24d0e7ca3f46df12bc6e802ef86bde9bfe1fd660 [file] [log] [blame]
drhbbd42a62004-05-22 17:41:58 +00001/*
2** 2004 May 22
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
13** This file contains code that is specific to windows.
14*/
drhbbd42a62004-05-22 17:41:58 +000015#include "sqliteInt.h"
danielk197729bafea2008-06-26 10:41:19 +000016#if SQLITE_OS_WIN /* This file is used for windows only */
drhbbd42a62004-05-22 17:41:58 +000017
drhb11caac2007-08-24 17:52:21 +000018
19/*
20** A Note About Memory Allocation:
21**
22** This driver uses malloc()/free() directly rather than going through
23** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers
24** are designed for use on embedded systems where memory is scarce and
25** malloc failures happen frequently. Win32 does not typically run on
26** embedded systems, and when it does the developers normally have bigger
27** problems to worry about than running out of memory. So there is not
28** a compelling need to use the wrappers.
29**
30** But there is a good reason to not use the wrappers. If we use the
31** wrappers then we will get simulated malloc() failures within this
32** driver. And that causes all kinds of problems for our tests. We
33** could enhance SQLite to deal with simulated malloc failures within
34** the OS driver, but the code to deal with those failure would not
35** be exercised on Linux (which does not need to malloc() in the driver)
36** and so we would have difficulty writing coverage tests for that
37** code. Better to leave the code out, we think.
38**
39** The point of this discussion is as follows: When creating a new
40** OS layer for an embedded system, if you use this file as an example,
41** avoid the use of malloc()/free(). Those routines work ok on windows
42** desktops but not so well in embedded systems.
43*/
44
drhbbd42a62004-05-22 17:41:58 +000045#include <winbase.h>
46
drh09bf0e82005-03-21 00:36:08 +000047#ifdef __CYGWIN__
48# include <sys/cygwin.h>
49#endif
50
drhbbd42a62004-05-22 17:41:58 +000051/*
52** Macros used to determine whether or not to use threads.
53*/
54#if defined(THREADSAFE) && THREADSAFE
55# define SQLITE_W32_THREADS 1
56#endif
57
58/*
59** Include code that is common to all os_*.c files
60*/
61#include "os_common.h"
62
63/*
shane171fa292008-09-01 22:15:18 +000064** Some microsoft compilers lack this definition.
65*/
66#ifndef INVALID_FILE_ATTRIBUTES
67# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
68#endif
69
70/*
drhcc78fea2006-01-06 16:17:05 +000071** Determine if we are dealing with WindowsCE - which has a much
72** reduced API.
73*/
shane891adea2008-10-22 16:55:47 +000074#if SQLITE_OS_WINCE
drhd2832bf2007-01-10 18:56:15 +000075# define AreFileApisANSI() 1
shaneea598922009-10-21 02:00:47 +000076# define FormatMessageW(a,b,c,d,e,f,g) 0
drhcc78fea2006-01-06 16:17:05 +000077#endif
78
drh83235212010-05-14 16:34:34 +000079/* Forward references */
80typedef struct winShm winShm; /* A connection to shared-memory */
81typedef struct winShmNode winShmNode; /* A region of shared-memory */
82
drhcc78fea2006-01-06 16:17:05 +000083/*
drh72aead82006-01-23 15:54:25 +000084** WinCE lacks native support for file locking so we have to fake it
85** with some code of our own.
86*/
danielk197729bafea2008-06-26 10:41:19 +000087#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +000088typedef struct winceLock {
89 int nReaders; /* Number of reader locks obtained */
90 BOOL bPending; /* Indicates a pending lock has been obtained */
91 BOOL bReserved; /* Indicates a reserved lock has been obtained */
92 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
93} winceLock;
94#endif
95
96/*
drh153c62c2007-08-24 03:51:33 +000097** The winFile structure is a subclass of sqlite3_file* specific to the win32
drh054889e2005-11-30 03:20:31 +000098** portability layer.
drh9cbe6352005-11-29 03:13:21 +000099*/
drh054889e2005-11-30 03:20:31 +0000100typedef struct winFile winFile;
101struct winFile {
drh83235212010-05-14 16:34:34 +0000102 const sqlite3_io_methods *pMethod; /*** Must be first ***/
103 sqlite3_vfs *pVfs; /* The VFS used to open this file */
drh9cbe6352005-11-29 03:13:21 +0000104 HANDLE h; /* Handle for accessing the file */
105 unsigned char locktype; /* Type of lock currently held on this file */
106 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
shane9db299f2009-01-30 05:59:10 +0000107 DWORD lastErrno; /* The Windows errno from the last I/O error */
shane50daafc2009-03-05 05:54:55 +0000108 DWORD sectorSize; /* Sector size of the device file is on */
drh83235212010-05-14 16:34:34 +0000109 winShm *pShm; /* Instance of shared memory on this file */
110 const char *zPath; /* Full pathname of this file */
danielk197729bafea2008-06-26 10:41:19 +0000111#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +0000112 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
113 HANDLE hMutex; /* Mutex used to control access to shared lock */
114 HANDLE hShared; /* Shared memory segment used for locking */
115 winceLock local; /* Locks obtained by this instance of winFile */
116 winceLock *shared; /* Global shared lock memory for the file */
drhcc78fea2006-01-06 16:17:05 +0000117#endif
drh9cbe6352005-11-29 03:13:21 +0000118};
119
shane50daafc2009-03-05 05:54:55 +0000120/*
121** Forward prototypes.
122*/
123static int getSectorSize(
124 sqlite3_vfs *pVfs,
125 const char *zRelative /* UTF-8 file name */
126);
drh9cbe6352005-11-29 03:13:21 +0000127
drh9cbe6352005-11-29 03:13:21 +0000128/*
drhc0929982005-09-05 19:08:29 +0000129** The following variable is (normally) set once and never changes
130** thereafter. It records whether the operating system is Win95
131** or WinNT.
132**
133** 0: Operating system unknown.
134** 1: Operating system is Win95.
135** 2: Operating system is WinNT.
136**
137** In order to facilitate testing on a WinNT system, the test fixture
138** can manually set this value to 1 to emulate Win98 behavior.
139*/
drh153c62c2007-08-24 03:51:33 +0000140#ifdef SQLITE_TEST
drhc0929982005-09-05 19:08:29 +0000141int sqlite3_os_type = 0;
drh153c62c2007-08-24 03:51:33 +0000142#else
143static int sqlite3_os_type = 0;
144#endif
drhc0929982005-09-05 19:08:29 +0000145
146/*
drhcc78fea2006-01-06 16:17:05 +0000147** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
148** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +0000149**
150** Here is an interesting observation: Win95, Win98, and WinME lack
151** the LockFileEx() API. But we can still statically link against that
shane50daafc2009-03-05 05:54:55 +0000152** API as long as we don't call it when running Win95/98/ME. A call to
drhc0929982005-09-05 19:08:29 +0000153** this routine is used to determine if the host is Win95/98/ME or
154** WinNT/2K/XP so that we will know whether or not we can safely call
155** the LockFileEx() API.
156*/
danielk197729bafea2008-06-26 10:41:19 +0000157#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +0000158# define isNT() (1)
159#else
160 static int isNT(void){
161 if( sqlite3_os_type==0 ){
162 OSVERSIONINFO sInfo;
163 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
164 GetVersionEx(&sInfo);
165 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
166 }
167 return sqlite3_os_type==2;
drhc0929982005-09-05 19:08:29 +0000168 }
danielk197729bafea2008-06-26 10:41:19 +0000169#endif /* SQLITE_OS_WINCE */
drhcc78fea2006-01-06 16:17:05 +0000170
drhc0929982005-09-05 19:08:29 +0000171/*
drh584c0942006-12-21 03:20:40 +0000172** Convert a UTF-8 string to microsoft unicode (UTF-16?).
173**
drhb11caac2007-08-24 17:52:21 +0000174** Space to hold the returned string is obtained from malloc.
drhc0929982005-09-05 19:08:29 +0000175*/
176static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000177 int nChar;
drhc0929982005-09-05 19:08:29 +0000178 WCHAR *zWideFilename;
179
drhe3dd8bb2006-02-27 23:44:35 +0000180 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
drhb11caac2007-08-24 17:52:21 +0000181 zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000182 if( zWideFilename==0 ){
183 return 0;
184 }
drhe3dd8bb2006-02-27 23:44:35 +0000185 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
186 if( nChar==0 ){
drhb11caac2007-08-24 17:52:21 +0000187 free(zWideFilename);
drhc0929982005-09-05 19:08:29 +0000188 zWideFilename = 0;
189 }
190 return zWideFilename;
191}
192
193/*
drh584c0942006-12-21 03:20:40 +0000194** Convert microsoft unicode to UTF-8. Space to hold the returned string is
drhb11caac2007-08-24 17:52:21 +0000195** obtained from malloc().
drhc0929982005-09-05 19:08:29 +0000196*/
197static char *unicodeToUtf8(const WCHAR *zWideFilename){
198 int nByte;
199 char *zFilename;
200
201 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000202 zFilename = malloc( nByte );
drhc0929982005-09-05 19:08:29 +0000203 if( zFilename==0 ){
204 return 0;
205 }
206 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
207 0, 0);
208 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000209 free(zFilename);
drhc0929982005-09-05 19:08:29 +0000210 zFilename = 0;
211 }
212 return zFilename;
213}
214
drh371de5a2006-10-30 13:37:22 +0000215/*
drh584c0942006-12-21 03:20:40 +0000216** Convert an ansi string to microsoft unicode, based on the
217** current codepage settings for file apis.
218**
219** Space to hold the returned string is obtained
drhb11caac2007-08-24 17:52:21 +0000220** from malloc.
drh371de5a2006-10-30 13:37:22 +0000221*/
222static WCHAR *mbcsToUnicode(const char *zFilename){
223 int nByte;
224 WCHAR *zMbcsFilename;
drh584c0942006-12-21 03:20:40 +0000225 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000226
drh584c0942006-12-21 03:20:40 +0000227 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
drhb11caac2007-08-24 17:52:21 +0000228 zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
drh371de5a2006-10-30 13:37:22 +0000229 if( zMbcsFilename==0 ){
230 return 0;
231 }
drh584c0942006-12-21 03:20:40 +0000232 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
drh371de5a2006-10-30 13:37:22 +0000233 if( nByte==0 ){
drhb11caac2007-08-24 17:52:21 +0000234 free(zMbcsFilename);
drh371de5a2006-10-30 13:37:22 +0000235 zMbcsFilename = 0;
236 }
237 return zMbcsFilename;
238}
239
240/*
drh584c0942006-12-21 03:20:40 +0000241** Convert microsoft unicode to multibyte character string, based on the
242** user's Ansi codepage.
243**
244** Space to hold the returned string is obtained from
drhb11caac2007-08-24 17:52:21 +0000245** malloc().
drh371de5a2006-10-30 13:37:22 +0000246*/
247static char *unicodeToMbcs(const WCHAR *zWideFilename){
248 int nByte;
249 char *zFilename;
drh584c0942006-12-21 03:20:40 +0000250 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000251
drh584c0942006-12-21 03:20:40 +0000252 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000253 zFilename = malloc( nByte );
drh371de5a2006-10-30 13:37:22 +0000254 if( zFilename==0 ){
255 return 0;
256 }
drh584c0942006-12-21 03:20:40 +0000257 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
drh371de5a2006-10-30 13:37:22 +0000258 0, 0);
259 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000260 free(zFilename);
drh371de5a2006-10-30 13:37:22 +0000261 zFilename = 0;
262 }
263 return zFilename;
264}
265
266/*
267** Convert multibyte character string to UTF-8. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000268** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000269*/
drh1d298852008-11-18 19:18:52 +0000270char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
drh371de5a2006-10-30 13:37:22 +0000271 char *zFilenameUtf8;
272 WCHAR *zTmpWide;
273
274 zTmpWide = mbcsToUnicode(zFilename);
275 if( zTmpWide==0 ){
276 return 0;
277 }
278 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000279 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000280 return zFilenameUtf8;
281}
282
283/*
284** Convert UTF-8 to multibyte character string. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000285** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000286*/
287static char *utf8ToMbcs(const char *zFilename){
288 char *zFilenameMbcs;
289 WCHAR *zTmpWide;
290
291 zTmpWide = utf8ToUnicode(zFilename);
292 if( zTmpWide==0 ){
293 return 0;
294 }
295 zFilenameMbcs = unicodeToMbcs(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000296 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000297 return zFilenameMbcs;
298}
299
danielk197729bafea2008-06-26 10:41:19 +0000300#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +0000301/*************************************************************************
302** This section contains code for WinCE only.
303*/
304/*
305** WindowsCE does not have a localtime() function. So create a
306** substitute.
307*/
308#include <time.h>
309struct tm *__cdecl localtime(const time_t *t)
310{
311 static struct tm y;
312 FILETIME uTm, lTm;
313 SYSTEMTIME pTm;
drhc51250a2007-09-20 14:39:23 +0000314 sqlite3_int64 t64;
drh72aead82006-01-23 15:54:25 +0000315 t64 = *t;
316 t64 = (t64 + 11644473600)*10000000;
shane11bb41f2009-09-10 20:23:30 +0000317 uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
318 uTm.dwHighDateTime= (DWORD)(t64 >> 32);
drh72aead82006-01-23 15:54:25 +0000319 FileTimeToLocalFileTime(&uTm,&lTm);
320 FileTimeToSystemTime(&lTm,&pTm);
321 y.tm_year = pTm.wYear - 1900;
322 y.tm_mon = pTm.wMonth - 1;
323 y.tm_wday = pTm.wDayOfWeek;
324 y.tm_mday = pTm.wDay;
325 y.tm_hour = pTm.wHour;
326 y.tm_min = pTm.wMinute;
327 y.tm_sec = pTm.wSecond;
328 return &y;
329}
330
331/* This will never be called, but defined to make the code compile */
332#define GetTempPathA(a,b)
333
334#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
335#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
336#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
337
shane11bb41f2009-09-10 20:23:30 +0000338#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
drh72aead82006-01-23 15:54:25 +0000339
340/*
341** Acquire a lock on the handle h
342*/
343static void winceMutexAcquire(HANDLE h){
344 DWORD dwErr;
345 do {
346 dwErr = WaitForSingleObject(h, INFINITE);
347 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
348}
349/*
350** Release a lock acquired by winceMutexAcquire()
351*/
352#define winceMutexRelease(h) ReleaseMutex(h)
353
354/*
355** Create the mutex and shared memory used for locking in the file
356** descriptor pFile
357*/
358static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
359 WCHAR *zTok;
360 WCHAR *zName = utf8ToUnicode(zFilename);
361 BOOL bInit = TRUE;
362
363 /* Initialize the local lockdata */
364 ZeroMemory(&pFile->local, sizeof(pFile->local));
365
366 /* Replace the backslashes from the filename and lowercase it
367 ** to derive a mutex name. */
368 zTok = CharLowerW(zName);
369 for (;*zTok;zTok++){
370 if (*zTok == '\\') *zTok = '_';
371 }
372
373 /* Create/open the named mutex */
374 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
375 if (!pFile->hMutex){
shane9db299f2009-01-30 05:59:10 +0000376 pFile->lastErrno = GetLastError();
drhb11caac2007-08-24 17:52:21 +0000377 free(zName);
drh72aead82006-01-23 15:54:25 +0000378 return FALSE;
379 }
380
381 /* Acquire the mutex before continuing */
382 winceMutexAcquire(pFile->hMutex);
383
384 /* Since the names of named mutexes, semaphores, file mappings etc are
385 ** case-sensitive, take advantage of that by uppercasing the mutex name
386 ** and using that as the shared filemapping name.
387 */
388 CharUpperW(zName);
389 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
390 PAGE_READWRITE, 0, sizeof(winceLock),
391 zName);
392
393 /* Set a flag that indicates we're the first to create the memory so it
394 ** must be zero-initialized */
395 if (GetLastError() == ERROR_ALREADY_EXISTS){
396 bInit = FALSE;
397 }
398
drhb11caac2007-08-24 17:52:21 +0000399 free(zName);
drh72aead82006-01-23 15:54:25 +0000400
401 /* If we succeeded in making the shared memory handle, map it. */
402 if (pFile->hShared){
403 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
404 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
405 /* If mapping failed, close the shared memory handle and erase it */
406 if (!pFile->shared){
shane9db299f2009-01-30 05:59:10 +0000407 pFile->lastErrno = GetLastError();
drh72aead82006-01-23 15:54:25 +0000408 CloseHandle(pFile->hShared);
409 pFile->hShared = NULL;
410 }
411 }
412
413 /* If shared memory could not be created, then close the mutex and fail */
414 if (pFile->hShared == NULL){
415 winceMutexRelease(pFile->hMutex);
416 CloseHandle(pFile->hMutex);
417 pFile->hMutex = NULL;
418 return FALSE;
419 }
420
421 /* Initialize the shared memory if we're supposed to */
422 if (bInit) {
423 ZeroMemory(pFile->shared, sizeof(winceLock));
424 }
425
426 winceMutexRelease(pFile->hMutex);
427 return TRUE;
428}
429
430/*
431** Destroy the part of winFile that deals with wince locks
432*/
433static void winceDestroyLock(winFile *pFile){
434 if (pFile->hMutex){
435 /* Acquire the mutex */
436 winceMutexAcquire(pFile->hMutex);
437
438 /* The following blocks should probably assert in debug mode, but they
439 are to cleanup in case any locks remained open */
440 if (pFile->local.nReaders){
441 pFile->shared->nReaders --;
442 }
443 if (pFile->local.bReserved){
444 pFile->shared->bReserved = FALSE;
445 }
446 if (pFile->local.bPending){
447 pFile->shared->bPending = FALSE;
448 }
449 if (pFile->local.bExclusive){
450 pFile->shared->bExclusive = FALSE;
451 }
452
453 /* De-reference and close our copy of the shared memory handle */
454 UnmapViewOfFile(pFile->shared);
455 CloseHandle(pFile->hShared);
456
457 /* Done with the mutex */
458 winceMutexRelease(pFile->hMutex);
459 CloseHandle(pFile->hMutex);
460 pFile->hMutex = NULL;
461 }
462}
463
464/*
465** An implementation of the LockFile() API of windows for wince
466*/
467static BOOL winceLockFile(
468 HANDLE *phFile,
469 DWORD dwFileOffsetLow,
470 DWORD dwFileOffsetHigh,
471 DWORD nNumberOfBytesToLockLow,
472 DWORD nNumberOfBytesToLockHigh
473){
474 winFile *pFile = HANDLE_TO_WINFILE(phFile);
475 BOOL bReturn = FALSE;
476
shane11bb41f2009-09-10 20:23:30 +0000477 UNUSED_PARAMETER(dwFileOffsetHigh);
478 UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
479
drh72aead82006-01-23 15:54:25 +0000480 if (!pFile->hMutex) return TRUE;
481 winceMutexAcquire(pFile->hMutex);
482
483 /* Wanting an exclusive lock? */
shane11bb41f2009-09-10 20:23:30 +0000484 if (dwFileOffsetLow == (DWORD)SHARED_FIRST
485 && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
drh72aead82006-01-23 15:54:25 +0000486 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
487 pFile->shared->bExclusive = TRUE;
488 pFile->local.bExclusive = TRUE;
489 bReturn = TRUE;
490 }
491 }
492
493 /* Want a read-only lock? */
shane11bb41f2009-09-10 20:23:30 +0000494 else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
shane338ea3c2009-08-05 04:08:29 +0000495 nNumberOfBytesToLockLow == 1){
drh72aead82006-01-23 15:54:25 +0000496 if (pFile->shared->bExclusive == 0){
497 pFile->local.nReaders ++;
498 if (pFile->local.nReaders == 1){
499 pFile->shared->nReaders ++;
500 }
501 bReturn = TRUE;
502 }
503 }
504
505 /* Want a pending lock? */
shane11bb41f2009-09-10 20:23:30 +0000506 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
drh72aead82006-01-23 15:54:25 +0000507 /* If no pending lock has been acquired, then acquire it */
508 if (pFile->shared->bPending == 0) {
509 pFile->shared->bPending = TRUE;
510 pFile->local.bPending = TRUE;
511 bReturn = TRUE;
512 }
513 }
shane338ea3c2009-08-05 04:08:29 +0000514
drh72aead82006-01-23 15:54:25 +0000515 /* Want a reserved lock? */
shane11bb41f2009-09-10 20:23:30 +0000516 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
drh72aead82006-01-23 15:54:25 +0000517 if (pFile->shared->bReserved == 0) {
518 pFile->shared->bReserved = TRUE;
519 pFile->local.bReserved = TRUE;
520 bReturn = TRUE;
521 }
522 }
523
524 winceMutexRelease(pFile->hMutex);
525 return bReturn;
526}
527
528/*
529** An implementation of the UnlockFile API of windows for wince
530*/
531static BOOL winceUnlockFile(
532 HANDLE *phFile,
533 DWORD dwFileOffsetLow,
534 DWORD dwFileOffsetHigh,
535 DWORD nNumberOfBytesToUnlockLow,
536 DWORD nNumberOfBytesToUnlockHigh
537){
538 winFile *pFile = HANDLE_TO_WINFILE(phFile);
539 BOOL bReturn = FALSE;
540
shane11bb41f2009-09-10 20:23:30 +0000541 UNUSED_PARAMETER(dwFileOffsetHigh);
542 UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
543
drh72aead82006-01-23 15:54:25 +0000544 if (!pFile->hMutex) return TRUE;
545 winceMutexAcquire(pFile->hMutex);
546
547 /* Releasing a reader lock or an exclusive lock */
shane11bb41f2009-09-10 20:23:30 +0000548 if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
drh72aead82006-01-23 15:54:25 +0000549 /* Did we have an exclusive lock? */
550 if (pFile->local.bExclusive){
shane11bb41f2009-09-10 20:23:30 +0000551 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
drh72aead82006-01-23 15:54:25 +0000552 pFile->local.bExclusive = FALSE;
553 pFile->shared->bExclusive = FALSE;
554 bReturn = TRUE;
555 }
556
557 /* Did we just have a reader lock? */
558 else if (pFile->local.nReaders){
shane11bb41f2009-09-10 20:23:30 +0000559 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
drh72aead82006-01-23 15:54:25 +0000560 pFile->local.nReaders --;
561 if (pFile->local.nReaders == 0)
562 {
563 pFile->shared->nReaders --;
564 }
565 bReturn = TRUE;
566 }
567 }
568
569 /* Releasing a pending lock */
shane11bb41f2009-09-10 20:23:30 +0000570 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
drh72aead82006-01-23 15:54:25 +0000571 if (pFile->local.bPending){
572 pFile->local.bPending = FALSE;
573 pFile->shared->bPending = FALSE;
574 bReturn = TRUE;
575 }
576 }
577 /* Releasing a reserved lock */
shane11bb41f2009-09-10 20:23:30 +0000578 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
drh72aead82006-01-23 15:54:25 +0000579 if (pFile->local.bReserved) {
580 pFile->local.bReserved = FALSE;
581 pFile->shared->bReserved = FALSE;
582 bReturn = TRUE;
583 }
584 }
585
586 winceMutexRelease(pFile->hMutex);
587 return bReturn;
588}
589
590/*
591** An implementation of the LockFileEx() API of windows for wince
592*/
593static BOOL winceLockFileEx(
594 HANDLE *phFile,
595 DWORD dwFlags,
596 DWORD dwReserved,
597 DWORD nNumberOfBytesToLockLow,
598 DWORD nNumberOfBytesToLockHigh,
599 LPOVERLAPPED lpOverlapped
600){
shane11bb41f2009-09-10 20:23:30 +0000601 UNUSED_PARAMETER(dwReserved);
602 UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
603
drh72aead82006-01-23 15:54:25 +0000604 /* If the caller wants a shared read lock, forward this call
605 ** to winceLockFile */
shane11bb41f2009-09-10 20:23:30 +0000606 if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
drh72aead82006-01-23 15:54:25 +0000607 dwFlags == 1 &&
shane11bb41f2009-09-10 20:23:30 +0000608 nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
drh72aead82006-01-23 15:54:25 +0000609 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
610 }
611 return FALSE;
612}
613/*
614** End of the special code for wince
615*****************************************************************************/
danielk197729bafea2008-06-26 10:41:19 +0000616#endif /* SQLITE_OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000617
drh153c62c2007-08-24 03:51:33 +0000618/*****************************************************************************
619** The next group of routines implement the I/O methods specified
620** by the sqlite3_io_methods object.
621******************************************************************************/
drhbbd42a62004-05-22 17:41:58 +0000622
623/*
624** Close a file.
drh59e63a62006-06-04 23:31:48 +0000625**
626** It is reported that an attempt to close a handle might sometimes
627** fail. This is a very unreasonable result, but windows is notorious
628** for being unreasonable so I do not doubt that it might happen. If
629** the close fails, we pause for 100 milliseconds and try again. As
630** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
631** giving up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000632*/
drh59e63a62006-06-04 23:31:48 +0000633#define MX_CLOSE_ATTEMPT 3
drh153c62c2007-08-24 03:51:33 +0000634static int winClose(sqlite3_file *id){
635 int rc, cnt = 0;
636 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +0000637
638 assert( id!=0 );
drh83235212010-05-14 16:34:34 +0000639 assert( pFile->pShm==0 );
drh308c2a52010-05-14 11:30:18 +0000640 OSTRACE(("CLOSE %d\n", pFile->h));
drh153c62c2007-08-24 03:51:33 +0000641 do{
642 rc = CloseHandle(pFile->h);
shaned94b0552008-09-30 04:20:07 +0000643 }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
danielk197729bafea2008-06-26 10:41:19 +0000644#if SQLITE_OS_WINCE
drhd641d512008-02-20 00:00:00 +0000645#define WINCE_DELETION_ATTEMPTS 3
drh153c62c2007-08-24 03:51:33 +0000646 winceDestroyLock(pFile);
drh7229ed42007-10-08 12:29:17 +0000647 if( pFile->zDeleteOnClose ){
drhd641d512008-02-20 00:00:00 +0000648 int cnt = 0;
649 while(
650 DeleteFileW(pFile->zDeleteOnClose)==0
651 && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
652 && cnt++ < WINCE_DELETION_ATTEMPTS
653 ){
654 Sleep(100); /* Wait a little before trying again */
655 }
drh7229ed42007-10-08 12:29:17 +0000656 free(pFile->zDeleteOnClose);
657 }
drhcc78fea2006-01-06 16:17:05 +0000658#endif
shaneh04882a92010-05-11 02:49:39 +0000659 OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
drh153c62c2007-08-24 03:51:33 +0000660 OpenCounter(-1);
drheb4fa522006-06-04 23:02:20 +0000661 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000662}
663
664/*
drh153c62c2007-08-24 03:51:33 +0000665** Some microsoft compilers lack this definition.
666*/
667#ifndef INVALID_SET_FILE_POINTER
668# define INVALID_SET_FILE_POINTER ((DWORD)-1)
669#endif
670
671/*
drhbbd42a62004-05-22 17:41:58 +0000672** Read data from a file into a buffer. Return SQLITE_OK if all
673** bytes were read successfully and SQLITE_IOERR if anything goes
674** wrong.
675*/
drh153c62c2007-08-24 03:51:33 +0000676static int winRead(
677 sqlite3_file *id, /* File to read from */
678 void *pBuf, /* Write content into this buffer */
679 int amt, /* Number of bytes to read */
680 sqlite3_int64 offset /* Begin reading at this offset */
681){
drh1bd10f82008-12-10 21:19:56 +0000682 LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
683 LONG lowerBits = (LONG)(offset & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000684 DWORD rc;
drh153c62c2007-08-24 03:51:33 +0000685 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000686 DWORD error;
shane50daafc2009-03-05 05:54:55 +0000687 DWORD got;
688
drh9cbe6352005-11-29 03:13:21 +0000689 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +0000690 SimulateIOError(return SQLITE_IOERR_READ);
drh308c2a52010-05-14 11:30:18 +0000691 OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype));
drh153c62c2007-08-24 03:51:33 +0000692 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
shane9db299f2009-01-30 05:59:10 +0000693 if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
694 pFile->lastErrno = error;
drh153c62c2007-08-24 03:51:33 +0000695 return SQLITE_FULL;
696 }
697 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
shane9db299f2009-01-30 05:59:10 +0000698 pFile->lastErrno = GetLastError();
drhaedd8922007-01-05 14:38:54 +0000699 return SQLITE_IOERR_READ;
drhbbd42a62004-05-22 17:41:58 +0000700 }
701 if( got==(DWORD)amt ){
702 return SQLITE_OK;
703 }else{
drh4c17c3f2008-11-07 00:06:18 +0000704 /* Unread parts of the buffer must be zero-filled */
drhbafda092007-01-03 23:36:22 +0000705 memset(&((char*)pBuf)[got], 0, amt-got);
drh551b7732006-11-06 21:20:25 +0000706 return SQLITE_IOERR_SHORT_READ;
drhbbd42a62004-05-22 17:41:58 +0000707 }
708}
709
710/*
711** Write data from a buffer into a file. Return SQLITE_OK on success
712** or some other error code on failure.
713*/
drh153c62c2007-08-24 03:51:33 +0000714static int winWrite(
715 sqlite3_file *id, /* File to write into */
716 const void *pBuf, /* The bytes to be written */
717 int amt, /* Number of bytes to write */
718 sqlite3_int64 offset /* Offset into the file to begin writing at */
719){
drh1bd10f82008-12-10 21:19:56 +0000720 LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
721 LONG lowerBits = (LONG)(offset & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000722 DWORD rc;
drh153c62c2007-08-24 03:51:33 +0000723 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000724 DWORD error;
shane50daafc2009-03-05 05:54:55 +0000725 DWORD wrote = 0;
726
drh9cbe6352005-11-29 03:13:21 +0000727 assert( id!=0 );
drh153c62c2007-08-24 03:51:33 +0000728 SimulateIOError(return SQLITE_IOERR_WRITE);
drh59685932006-09-14 13:47:11 +0000729 SimulateDiskfullError(return SQLITE_FULL);
drh308c2a52010-05-14 11:30:18 +0000730 OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
drh153c62c2007-08-24 03:51:33 +0000731 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
shane9db299f2009-01-30 05:59:10 +0000732 if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
733 pFile->lastErrno = error;
drh153c62c2007-08-24 03:51:33 +0000734 return SQLITE_FULL;
735 }
drh4c7f9412005-02-03 00:29:47 +0000736 assert( amt>0 );
drh153c62c2007-08-24 03:51:33 +0000737 while(
738 amt>0
739 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
740 && wrote>0
741 ){
drhbbd42a62004-05-22 17:41:58 +0000742 amt -= wrote;
743 pBuf = &((char*)pBuf)[wrote];
744 }
745 if( !rc || amt>(int)wrote ){
shane9db299f2009-01-30 05:59:10 +0000746 pFile->lastErrno = GetLastError();
drhbbd42a62004-05-22 17:41:58 +0000747 return SQLITE_FULL;
748 }
749 return SQLITE_OK;
750}
751
752/*
drh153c62c2007-08-24 03:51:33 +0000753** Truncate an open file to a specified size
drhbbdc2b92005-09-19 12:53:18 +0000754*/
drhc51250a2007-09-20 14:39:23 +0000755static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
drh1bd10f82008-12-10 21:19:56 +0000756 LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
757 LONG lowerBits = (LONG)(nByte & 0xffffffff);
shaneh04882a92010-05-11 02:49:39 +0000758 DWORD dwRet;
drh153c62c2007-08-24 03:51:33 +0000759 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +0000760 DWORD error;
shaneh04882a92010-05-11 02:49:39 +0000761 int rc = SQLITE_OK;
shane50daafc2009-03-05 05:54:55 +0000762
763 assert( id!=0 );
drh308c2a52010-05-14 11:30:18 +0000764 OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte));
drh153c62c2007-08-24 03:51:33 +0000765 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
shaneh04882a92010-05-11 02:49:39 +0000766 dwRet = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
767 if( dwRet==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
shane50daafc2009-03-05 05:54:55 +0000768 pFile->lastErrno = error;
shaneh04882a92010-05-11 02:49:39 +0000769 rc = SQLITE_IOERR_TRUNCATE;
shane50daafc2009-03-05 05:54:55 +0000770 /* SetEndOfFile will fail if nByte is negative */
shaneh04882a92010-05-11 02:49:39 +0000771 }else if( !SetEndOfFile(pFile->h) ){
shane50daafc2009-03-05 05:54:55 +0000772 pFile->lastErrno = GetLastError();
shaneh04882a92010-05-11 02:49:39 +0000773 rc = SQLITE_IOERR_TRUNCATE;
shanea3465f22008-10-12 02:27:38 +0000774 }
shaneh04882a92010-05-11 02:49:39 +0000775 OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc==SQLITE_OK ? "ok" : "failed"));
776 return rc;
drhbbd42a62004-05-22 17:41:58 +0000777}
778
drhdec6fae2007-09-03 17:02:50 +0000779#ifdef SQLITE_TEST
780/*
781** Count the number of fullsyncs and normal syncs. This is used to test
782** that syncs and fullsyncs are occuring at the right times.
783*/
784int sqlite3_sync_count = 0;
785int sqlite3_fullsync_count = 0;
786#endif
787
drhbbd42a62004-05-22 17:41:58 +0000788/*
789** Make sure all writes to a particular file are committed to disk.
790*/
drh153c62c2007-08-24 03:51:33 +0000791static int winSync(sqlite3_file *id, int flags){
shane18e526c2008-12-10 22:30:24 +0000792#ifndef SQLITE_NO_SYNC
drh153c62c2007-08-24 03:51:33 +0000793 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +0000794
795 assert( id!=0 );
drh308c2a52010-05-14 11:30:18 +0000796 OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
shane18e526c2008-12-10 22:30:24 +0000797#else
798 UNUSED_PARAMETER(id);
799#endif
shane7d3846a2008-12-11 02:58:26 +0000800#ifndef SQLITE_TEST
801 UNUSED_PARAMETER(flags);
802#else
drhdec6fae2007-09-03 17:02:50 +0000803 if( flags & SQLITE_SYNC_FULL ){
804 sqlite3_fullsync_count++;
805 }
806 sqlite3_sync_count++;
807#endif
shane84ca3832008-11-13 18:20:43 +0000808 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
809 ** no-op
810 */
811#ifdef SQLITE_NO_SYNC
812 return SQLITE_OK;
813#else
drh153c62c2007-08-24 03:51:33 +0000814 if( FlushFileBuffers(pFile->h) ){
drhbbd42a62004-05-22 17:41:58 +0000815 return SQLITE_OK;
816 }else{
shane9db299f2009-01-30 05:59:10 +0000817 pFile->lastErrno = GetLastError();
drhbbd42a62004-05-22 17:41:58 +0000818 return SQLITE_IOERR;
819 }
shane84ca3832008-11-13 18:20:43 +0000820#endif
drhbbd42a62004-05-22 17:41:58 +0000821}
822
823/*
drhbbd42a62004-05-22 17:41:58 +0000824** Determine the current size of a file in bytes
825*/
drh153c62c2007-08-24 03:51:33 +0000826static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
shane50daafc2009-03-05 05:54:55 +0000827 DWORD upperBits;
828 DWORD lowerBits;
drh153c62c2007-08-24 03:51:33 +0000829 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000830 DWORD error;
shane50daafc2009-03-05 05:54:55 +0000831
832 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +0000833 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh153c62c2007-08-24 03:51:33 +0000834 lowerBits = GetFileSize(pFile->h, &upperBits);
shane9db299f2009-01-30 05:59:10 +0000835 if( (lowerBits == INVALID_FILE_SIZE)
836 && ((error = GetLastError()) != NO_ERROR) )
837 {
838 pFile->lastErrno = error;
839 return SQLITE_IOERR_FSTAT;
840 }
drh153c62c2007-08-24 03:51:33 +0000841 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000842 return SQLITE_OK;
843}
844
845/*
drh602bbd32006-01-06 20:22:29 +0000846** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
847*/
848#ifndef LOCKFILE_FAIL_IMMEDIATELY
849# define LOCKFILE_FAIL_IMMEDIATELY 1
850#endif
851
852/*
drh9c105bb2004-10-02 20:38:28 +0000853** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000854** Different API routines are called depending on whether or not this
855** is Win95 or WinNT.
856*/
drh153c62c2007-08-24 03:51:33 +0000857static int getReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000858 int res;
859 if( isNT() ){
860 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000861 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000862 ovlp.OffsetHigh = 0;
863 ovlp.hEvent = 0;
drh153c62c2007-08-24 03:51:33 +0000864 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
865 0, SHARED_SIZE, 0, &ovlp);
shane891adea2008-10-22 16:55:47 +0000866/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
867*/
868#if SQLITE_OS_WINCE==0
drhbbd42a62004-05-22 17:41:58 +0000869 }else{
drh9c105bb2004-10-02 20:38:28 +0000870 int lk;
drh2fa18682008-03-19 14:15:34 +0000871 sqlite3_randomness(sizeof(lk), &lk);
drh1bd10f82008-12-10 21:19:56 +0000872 pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
drh153c62c2007-08-24 03:51:33 +0000873 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000874#endif
drh51c6d962004-06-06 00:42:25 +0000875 }
shane9db299f2009-01-30 05:59:10 +0000876 if( res == 0 ){
877 pFile->lastErrno = GetLastError();
878 }
drh51c6d962004-06-06 00:42:25 +0000879 return res;
880}
881
882/*
883** Undo a readlock
884*/
drh054889e2005-11-30 03:20:31 +0000885static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000886 int res;
887 if( isNT() ){
drh054889e2005-11-30 03:20:31 +0000888 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
shane891adea2008-10-22 16:55:47 +0000889/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
890*/
891#if SQLITE_OS_WINCE==0
drh51c6d962004-06-06 00:42:25 +0000892 }else{
drh054889e2005-11-30 03:20:31 +0000893 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000894#endif
drh51c6d962004-06-06 00:42:25 +0000895 }
shane9db299f2009-01-30 05:59:10 +0000896 if( res == 0 ){
897 pFile->lastErrno = GetLastError();
898 }
drh51c6d962004-06-06 00:42:25 +0000899 return res;
900}
901
tpoindex9a09a3c2004-12-20 19:01:32 +0000902/*
drhb3e04342004-06-08 00:47:47 +0000903** Lock the file with the lock specified by parameter locktype - one
904** of the following:
905**
906** (1) SHARED_LOCK
907** (2) RESERVED_LOCK
908** (3) PENDING_LOCK
909** (4) EXCLUSIVE_LOCK
910**
911** Sometimes when requesting one lock state, additional lock states
912** are inserted in between. The locking might fail on one of the later
913** transitions leaving the lock state different from what it started but
914** still short of its goal. The following chart shows the allowed
915** transitions and the inserted intermediate states:
916**
917** UNLOCKED -> SHARED
918** SHARED -> RESERVED
919** SHARED -> (PENDING) -> EXCLUSIVE
920** RESERVED -> (PENDING) -> EXCLUSIVE
921** PENDING -> EXCLUSIVE
922**
drh9c06c952005-11-26 00:25:00 +0000923** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +0000924** erases all locks at once and returns us immediately to locking level 0.
925** It is not possible to lower the locking level one step at a time. You
926** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000927*/
drh153c62c2007-08-24 03:51:33 +0000928static int winLock(sqlite3_file *id, int locktype){
drh51c6d962004-06-06 00:42:25 +0000929 int rc = SQLITE_OK; /* Return code from subroutines */
930 int res = 1; /* Result of a windows lock call */
drh153c62c2007-08-24 03:51:33 +0000931 int newLocktype; /* Set pFile->locktype to this value before exiting */
drhe54ca3f2004-06-07 01:52:14 +0000932 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +0000933 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000934 DWORD error = NO_ERROR;
drh51c6d962004-06-06 00:42:25 +0000935
shane50daafc2009-03-05 05:54:55 +0000936 assert( id!=0 );
drh308c2a52010-05-14 11:30:18 +0000937 OSTRACE(("LOCK %d %d was %d(%d)\n",
shaneh50f64552010-05-12 17:14:59 +0000938 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte));
drh51c6d962004-06-06 00:42:25 +0000939
940 /* If there is already a lock of this type or more restrictive on the
941 ** OsFile, do nothing. Don't use the end_lock: exit path, as
942 ** sqlite3OsEnterMutex() hasn't been called yet.
943 */
drh054889e2005-11-30 03:20:31 +0000944 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +0000945 return SQLITE_OK;
946 }
947
drhb3e04342004-06-08 00:47:47 +0000948 /* Make sure the locking sequence is correct
949 */
drh054889e2005-11-30 03:20:31 +0000950 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000951 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +0000952 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000953
drh51c6d962004-06-06 00:42:25 +0000954 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
955 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
956 ** the PENDING_LOCK byte is temporary.
957 */
drh054889e2005-11-30 03:20:31 +0000958 newLocktype = pFile->locktype;
shane9db299f2009-01-30 05:59:10 +0000959 if( (pFile->locktype==NO_LOCK)
960 || ( (locktype==EXCLUSIVE_LOCK)
961 && (pFile->locktype==RESERVED_LOCK))
drhe54ca3f2004-06-07 01:52:14 +0000962 ){
drhb3e04342004-06-08 00:47:47 +0000963 int cnt = 3;
drh054889e2005-11-30 03:20:31 +0000964 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000965 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000966 ** held by another reader process who will release it momentarily.
967 */
drh308c2a52010-05-14 11:30:18 +0000968 OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
drhbbd42a62004-05-22 17:41:58 +0000969 Sleep(1);
970 }
drhe54ca3f2004-06-07 01:52:14 +0000971 gotPendingLock = res;
shane9db299f2009-01-30 05:59:10 +0000972 if( !res ){
973 error = GetLastError();
974 }
drh51c6d962004-06-06 00:42:25 +0000975 }
976
977 /* Acquire a shared lock
978 */
drhb3e04342004-06-08 00:47:47 +0000979 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000980 assert( pFile->locktype==NO_LOCK );
981 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000982 if( res ){
983 newLocktype = SHARED_LOCK;
shane9db299f2009-01-30 05:59:10 +0000984 }else{
985 error = GetLastError();
drh51c6d962004-06-06 00:42:25 +0000986 }
987 }
988
989 /* Acquire a RESERVED lock
990 */
drhb3e04342004-06-08 00:47:47 +0000991 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000992 assert( pFile->locktype==SHARED_LOCK );
993 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +0000994 if( res ){
995 newLocktype = RESERVED_LOCK;
shane9db299f2009-01-30 05:59:10 +0000996 }else{
997 error = GetLastError();
drhe54ca3f2004-06-07 01:52:14 +0000998 }
999 }
1000
1001 /* Acquire a PENDING lock
1002 */
drhb3e04342004-06-08 00:47:47 +00001003 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +00001004 newLocktype = PENDING_LOCK;
1005 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +00001006 }
1007
1008 /* Acquire an EXCLUSIVE lock
1009 */
drhe54ca3f2004-06-07 01:52:14 +00001010 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001011 assert( pFile->locktype>=SHARED_LOCK );
1012 res = unlockReadLock(pFile);
drh308c2a52010-05-14 11:30:18 +00001013 OSTRACE(("unreadlock = %d\n", res));
drh054889e2005-11-30 03:20:31 +00001014 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +00001015 if( res ){
1016 newLocktype = EXCLUSIVE_LOCK;
1017 }else{
shane9db299f2009-01-30 05:59:10 +00001018 error = GetLastError();
drh308c2a52010-05-14 11:30:18 +00001019 OSTRACE(("error-code = %d\n", error));
drh8fea1282007-05-14 12:12:11 +00001020 getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +00001021 }
1022 }
1023
1024 /* If we are holding a PENDING lock that ought to be released, then
1025 ** release it now.
1026 */
drhb3e04342004-06-08 00:47:47 +00001027 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001028 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001029 }
1030
1031 /* Update the state of the lock has held in the file descriptor then
1032 ** return the appropriate result code.
1033 */
1034 if( res ){
drh51c6d962004-06-06 00:42:25 +00001035 rc = SQLITE_OK;
1036 }else{
drh308c2a52010-05-14 11:30:18 +00001037 OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
1038 locktype, newLocktype));
shane9db299f2009-01-30 05:59:10 +00001039 pFile->lastErrno = error;
drh51c6d962004-06-06 00:42:25 +00001040 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +00001041 }
drh1bd10f82008-12-10 21:19:56 +00001042 pFile->locktype = (u8)newLocktype;
drhbbd42a62004-05-22 17:41:58 +00001043 return rc;
1044}
1045
1046/*
drh51c6d962004-06-06 00:42:25 +00001047** This routine checks if there is a RESERVED lock held on the specified
1048** file by this or any other process. If such a lock is held, return
1049** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +00001050*/
danielk1977861f7452008-06-05 11:39:11 +00001051static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
drhbbd42a62004-05-22 17:41:58 +00001052 int rc;
drh054889e2005-11-30 03:20:31 +00001053 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +00001054
1055 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +00001056 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +00001057 rc = 1;
drh308c2a52010-05-14 11:30:18 +00001058 OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
drhbbd42a62004-05-22 17:41:58 +00001059 }else{
drh054889e2005-11-30 03:20:31 +00001060 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001061 if( rc ){
drh054889e2005-11-30 03:20:31 +00001062 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +00001063 }
drh2ac3ee92004-06-07 16:27:46 +00001064 rc = !rc;
drh308c2a52010-05-14 11:30:18 +00001065 OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
drhbbd42a62004-05-22 17:41:58 +00001066 }
danielk1977861f7452008-06-05 11:39:11 +00001067 *pResOut = rc;
1068 return SQLITE_OK;
drhbbd42a62004-05-22 17:41:58 +00001069}
1070
1071/*
drha6abd042004-06-09 17:37:22 +00001072** Lower the locking level on file descriptor id to locktype. locktype
1073** must be either NO_LOCK or SHARED_LOCK.
1074**
1075** If the locking level of the file descriptor is already at or below
1076** the requested locking level, this routine is a no-op.
1077**
drh9c105bb2004-10-02 20:38:28 +00001078** It is not possible for this routine to fail if the second argument
1079** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1080** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +00001081*/
drh153c62c2007-08-24 03:51:33 +00001082static int winUnlock(sqlite3_file *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001083 int type;
drh054889e2005-11-30 03:20:31 +00001084 winFile *pFile = (winFile*)id;
drh153c62c2007-08-24 03:51:33 +00001085 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001086 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001087 assert( locktype<=SHARED_LOCK );
drh308c2a52010-05-14 11:30:18 +00001088 OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
1089 pFile->locktype, pFile->sharedLockByte));
drh054889e2005-11-30 03:20:31 +00001090 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001091 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001092 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1093 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001094 /* This should never happen. We should always be able to
1095 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +00001096 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +00001097 }
drhbbd42a62004-05-22 17:41:58 +00001098 }
drhe54ca3f2004-06-07 01:52:14 +00001099 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001100 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001101 }
drh9c105bb2004-10-02 20:38:28 +00001102 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001103 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001104 }
drhb3e04342004-06-08 00:47:47 +00001105 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001106 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001107 }
drh1bd10f82008-12-10 21:19:56 +00001108 pFile->locktype = (u8)locktype;
drh9c105bb2004-10-02 20:38:28 +00001109 return rc;
drhbbd42a62004-05-22 17:41:58 +00001110}
1111
1112/*
drh9e33c2c2007-08-31 18:34:59 +00001113** Control and query of the open file handle.
drh0ccebe72005-06-07 22:22:50 +00001114*/
drh9e33c2c2007-08-31 18:34:59 +00001115static int winFileControl(sqlite3_file *id, int op, void *pArg){
1116 switch( op ){
1117 case SQLITE_FCNTL_LOCKSTATE: {
1118 *(int*)pArg = ((winFile*)id)->locktype;
1119 return SQLITE_OK;
1120 }
shane9db299f2009-01-30 05:59:10 +00001121 case SQLITE_LAST_ERRNO: {
1122 *(int*)pArg = (int)((winFile*)id)->lastErrno;
1123 return SQLITE_OK;
1124 }
drhf5d6e472010-05-19 19:39:26 +00001125 case SQLITE_FCNTL_SIZE_HINT: {
1126 sqlite3_int64 sz = *(sqlite3_int64*)pArg;
1127 winTruncate(id, sz);
1128 return SQLITE_OK;
1129 }
drh9e33c2c2007-08-31 18:34:59 +00001130 }
drh153c62c2007-08-24 03:51:33 +00001131 return SQLITE_ERROR;
drh9cbe6352005-11-29 03:13:21 +00001132}
1133
1134/*
danielk1977a3d4c882007-03-23 10:08:38 +00001135** Return the sector size in bytes of the underlying block device for
1136** the specified file. This is almost always 512 bytes, but may be
1137** larger for some devices.
1138**
1139** SQLite code assumes this function cannot fail. It also assumes that
1140** if two files are created in the same file-system directory (i.e.
drh85b623f2007-12-13 21:54:09 +00001141** a database and its journal file) that the sector size will be the
danielk1977a3d4c882007-03-23 10:08:38 +00001142** same for both.
1143*/
drh153c62c2007-08-24 03:51:33 +00001144static int winSectorSize(sqlite3_file *id){
shane50daafc2009-03-05 05:54:55 +00001145 assert( id!=0 );
1146 return (int)(((winFile*)id)->sectorSize);
danielk1977a3d4c882007-03-23 10:08:38 +00001147}
1148
1149/*
drh153c62c2007-08-24 03:51:33 +00001150** Return a vector of device characteristics.
drh9c06c952005-11-26 00:25:00 +00001151*/
drh153c62c2007-08-24 03:51:33 +00001152static int winDeviceCharacteristics(sqlite3_file *id){
shane18e526c2008-12-10 22:30:24 +00001153 UNUSED_PARAMETER(id);
dan8ce49d62010-06-19 18:12:02 +00001154 return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
drh153c62c2007-08-24 03:51:33 +00001155}
1156
drh83235212010-05-14 16:34:34 +00001157/****************************************************************************
1158********************************* Shared Memory *****************************
1159**
1160** The next subdivision of code manages the shared-memory primitives.
1161*/
1162#ifndef SQLITE_OMIT_WAL
1163
1164/*
1165** Helper functions to obtain and relinquish the global mutex. The
1166** global mutex is used to protect the winLockInfo objects used by
1167** this file, all of which may be shared by multiple threads.
1168**
1169** Function winShmMutexHeld() is used to assert() that the global mutex
1170** is held when required. This function is only used as part of assert()
1171** statements. e.g.
1172**
1173** winShmEnterMutex()
1174** assert( winShmMutexHeld() );
1175** winEnterLeave()
1176*/
1177static void winShmEnterMutex(void){
1178 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
1179}
1180static void winShmLeaveMutex(void){
1181 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
1182}
1183#ifdef SQLITE_DEBUG
1184static int winShmMutexHeld(void) {
1185 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
1186}
1187#endif
1188
1189/*
1190** Object used to represent a single file opened and mmapped to provide
1191** shared memory. When multiple threads all reference the same
1192** log-summary, each thread has its own winFile object, but they all
1193** point to a single instance of this object. In other words, each
1194** log-summary is opened only once per process.
1195**
1196** winShmMutexHeld() must be true when creating or destroying
1197** this object or while reading or writing the following fields:
1198**
1199** nRef
1200** pNext
1201**
1202** The following fields are read-only after the object is created:
1203**
1204** fid
1205** zFilename
1206**
1207** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
1208** winShmMutexHeld() is true when reading or writing any other field
1209** in this structure.
1210**
1211** To avoid deadlocks, mutex and mutexBuf are always released in the
1212** reverse order that they are acquired. mutexBuf is always acquired
1213** first and released last. This invariant is check by asserting
1214** sqlite3_mutex_notheld() on mutex whenever mutexBuf is acquired or
1215** released.
1216*/
1217struct winShmNode {
1218 sqlite3_mutex *mutex; /* Mutex to access this object */
drh83235212010-05-14 16:34:34 +00001219 char *zFilename; /* Name of the file */
1220 winFile hFile; /* File handle from winOpen */
dan9785fc92010-06-14 16:16:33 +00001221
1222 int szRegion; /* Size of shared-memory regions */
1223 int nRegion; /* Size of array apRegion */
1224 struct ShmRegion {
1225 HANDLE hMap; /* File handle from CreateFileMapping */
1226 void *pMap;
1227 } *aRegion;
drh83235212010-05-14 16:34:34 +00001228 DWORD lastErrno; /* The Windows errno from the last I/O error */
dan9785fc92010-06-14 16:16:33 +00001229
drh83235212010-05-14 16:34:34 +00001230 int nRef; /* Number of winShm objects pointing to this */
1231 winShm *pFirst; /* All winShm objects pointing to this */
1232 winShmNode *pNext; /* Next in list of all winShmNode objects */
1233#ifdef SQLITE_DEBUG
drh83235212010-05-14 16:34:34 +00001234 u8 nextShmId; /* Next available winShm.id value */
1235#endif
1236};
1237
1238/*
1239** A global array of all winShmNode objects.
1240**
1241** The winShmMutexHeld() must be true while reading or writing this list.
1242*/
1243static winShmNode *winShmNodeList = 0;
1244
1245/*
1246** Structure used internally by this VFS to record the state of an
1247** open shared memory connection.
1248**
1249** winShm.pFile->mutex must be held while reading or writing the
1250** winShm.pNext and winShm.locks[] elements.
1251**
1252** The winShm.pFile element is initialized when the object is created
1253** and is read-only thereafter.
1254*/
1255struct winShm {
1256 winShmNode *pShmNode; /* The underlying winShmNode object */
1257 winShm *pNext; /* Next winShm with the same winShmNode */
drh83235212010-05-14 16:34:34 +00001258 u8 hasMutex; /* True if holding the winShmNode mutex */
1259 u8 hasMutexBuf; /* True if holding pFile->mutexBuf */
drh83235212010-05-14 16:34:34 +00001260#ifdef SQLITE_DEBUG
1261 u8 id; /* Id of this connection with its winShmNode */
1262#endif
1263};
1264
1265/*
drh83235212010-05-14 16:34:34 +00001266** Constants used for locking
1267*/
drh20e1f082010-05-31 16:10:12 +00001268#define WIN_SHM_BASE ((18+SQLITE_SHM_NLOCK)*4) /* first lock byte */
1269#define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
drh83235212010-05-14 16:34:34 +00001270
1271/*
drh20e1f082010-05-31 16:10:12 +00001272** Apply advisory locks for all n bytes beginning at ofst.
drh83235212010-05-14 16:34:34 +00001273*/
1274#define _SHM_UNLCK 1
1275#define _SHM_RDLCK 2
1276#define _SHM_WRLCK 3
1277static int winShmSystemLock(
1278 winShmNode *pFile, /* Apply locks to this open shared-memory segment */
1279 int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
drh20e1f082010-05-31 16:10:12 +00001280 int ofst, /* Offset to first byte to be locked/unlocked */
1281 int nByte /* Number of bytes to lock or unlock */
drh83235212010-05-14 16:34:34 +00001282){
1283 OVERLAPPED ovlp;
1284 DWORD dwFlags;
drh83235212010-05-14 16:34:34 +00001285 int rc = 0; /* Result code form Lock/UnlockFileEx() */
drh83235212010-05-14 16:34:34 +00001286
1287 /* Access to the winShmNode object is serialized by the caller */
1288 assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
1289
1290 /* Initialize the locking parameters */
drh20e1f082010-05-31 16:10:12 +00001291 dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
drh83235212010-05-14 16:34:34 +00001292 if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
1293
1294 /* Find the first bit in lockMask that is set */
drh83235212010-05-14 16:34:34 +00001295 memset(&ovlp, 0, sizeof(OVERLAPPED));
drh20e1f082010-05-31 16:10:12 +00001296 ovlp.Offset = ofst;
drh83235212010-05-14 16:34:34 +00001297
1298 /* Release/Acquire the system-level lock */
1299 if( lockType==_SHM_UNLCK ){
drh20e1f082010-05-31 16:10:12 +00001300 rc = UnlockFileEx(pFile->hFile.h, 0, nByte, 0, &ovlp);
drh83235212010-05-14 16:34:34 +00001301 }else{
drh20e1f082010-05-31 16:10:12 +00001302 rc = LockFileEx(pFile->hFile.h, dwFlags, 0, nByte, 0, &ovlp);
drh83235212010-05-14 16:34:34 +00001303 }
1304 if( !rc ){
1305 OSTRACE(("SHM-LOCK %d %s ERROR 0x%08lx\n",
1306 pFile->hFile.h,
1307 lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx",
1308 GetLastError()));
drh83235212010-05-14 16:34:34 +00001309 }
1310 rc = (rc!=0) ? SQLITE_OK : SQLITE_BUSY;
1311
drh83235212010-05-14 16:34:34 +00001312 return rc;
1313}
1314
drh05cb5b22010-06-03 18:02:48 +00001315/* Forward references to VFS methods */
1316static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
1317static int winDelete(sqlite3_vfs *,const char*,int);
1318
drh83235212010-05-14 16:34:34 +00001319/*
1320** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
1321**
1322** This is not a VFS shared-memory method; it is a utility function called
1323** by VFS shared-memory methods.
1324*/
drh05cb5b22010-06-03 18:02:48 +00001325static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
drh83235212010-05-14 16:34:34 +00001326 winShmNode **pp;
1327 winShmNode *p;
1328 assert( winShmMutexHeld() );
1329 pp = &winShmNodeList;
1330 while( (p = *pp)!=0 ){
1331 if( p->nRef==0 ){
dan9785fc92010-06-14 16:16:33 +00001332 int i;
drh83235212010-05-14 16:34:34 +00001333 if( p->mutex ) sqlite3_mutex_free(p->mutex);
dan9785fc92010-06-14 16:16:33 +00001334 for(i=0; i<p->nRegion; i++){
1335 UnmapViewOfFile(p->aRegion[i].pMap);
1336 CloseHandle(p->aRegion[i].hMap);
drh83235212010-05-14 16:34:34 +00001337 }
1338 if( p->hFile.h != INVALID_HANDLE_VALUE ) {
1339 winClose((sqlite3_file *)&p->hFile);
1340 }
drh05cb5b22010-06-03 18:02:48 +00001341 if( deleteFlag ) winDelete(pVfs, p->zFilename, 0);
drh83235212010-05-14 16:34:34 +00001342 *pp = p->pNext;
dan9785fc92010-06-14 16:16:33 +00001343 sqlite3_free(p->aRegion);
drh83235212010-05-14 16:34:34 +00001344 sqlite3_free(p);
1345 }else{
1346 pp = &p->pNext;
1347 }
1348 }
1349}
1350
drh83235212010-05-14 16:34:34 +00001351/*
1352** Open a shared-memory area. This particular implementation uses
1353** mmapped files.
1354**
1355** zName is a filename used to identify the shared-memory area. The
1356** implementation does not (and perhaps should not) use this name
1357** directly, but rather use it as a template for finding an appropriate
1358** name for the shared-memory storage. In this implementation, the
1359** string "-index" is appended to zName and used as the name of the
1360** mmapped file.
1361**
1362** When opening a new shared-memory file, if no other instances of that
1363** file are currently open, in this process or in other processes, then
1364** the file must be truncated to zero length or have its header cleared.
1365*/
1366static int winShmOpen(
1367 sqlite3_file *fd /* The file to which to attach shared memory */
1368){
1369 struct winFile *pDbFd; /* Database to which to attach SHM */
1370 struct winShm *p; /* The connection to be opened */
1371 struct winShmNode *pShmNode = 0; /* The underlying mmapped file */
1372 int rc; /* Result code */
1373 struct winShmNode *pNew; /* Newly allocated winShmNode */
1374 int nName; /* Size of zName in bytes */
1375
1376 pDbFd = (winFile*)fd;
1377 assert( pDbFd->pShm==0 ); /* Not previously opened */
1378
1379 /* Allocate space for the new sqlite3_shm object. Also speculatively
1380 ** allocate space for a new winShmNode and filename.
1381 */
1382 p = sqlite3_malloc( sizeof(*p) );
1383 if( p==0 ) return SQLITE_NOMEM;
1384 memset(p, 0, sizeof(*p));
1385 nName = sqlite3Strlen30(pDbFd->zPath);
1386 pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 );
1387 if( pNew==0 ){
1388 sqlite3_free(p);
1389 return SQLITE_NOMEM;
1390 }
1391 memset(pNew, 0, sizeof(*pNew));
1392 pNew->zFilename = (char*)&pNew[1];
1393 sqlite3_snprintf(nName+15, pNew->zFilename, "%s-wal-index", pDbFd->zPath);
1394
1395 /* Look to see if there is an existing winShmNode that can be used.
1396 ** If no matching winShmNode currently exists, create a new one.
1397 */
1398 winShmEnterMutex();
1399 for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
1400 /* TBD need to come up with better match here. Perhaps
1401 ** use FILE_ID_BOTH_DIR_INFO Structure.
1402 */
1403 if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
1404 }
1405 if( pShmNode ){
1406 sqlite3_free(pNew);
1407 }else{
1408 pShmNode = pNew;
1409 pNew = 0;
drh83235212010-05-14 16:34:34 +00001410 ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
1411 pShmNode->pNext = winShmNodeList;
1412 winShmNodeList = pShmNode;
1413
1414 pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
1415 if( pShmNode->mutex==0 ){
1416 rc = SQLITE_NOMEM;
1417 goto shm_open_err;
1418 }
drh83235212010-05-14 16:34:34 +00001419 rc = winOpen(pDbFd->pVfs,
1420 pShmNode->zFilename, /* Name of the file (UTF-8) */
1421 (sqlite3_file*)&pShmNode->hFile, /* File handle here */
1422 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
1423 0);
1424 if( SQLITE_OK!=rc ){
1425 rc = SQLITE_CANTOPEN_BKPT;
1426 goto shm_open_err;
1427 }
1428
1429 /* Check to see if another process is holding the dead-man switch.
1430 ** If not, truncate the file to zero length.
1431 */
drh20e1f082010-05-31 16:10:12 +00001432 if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
drh83235212010-05-14 16:34:34 +00001433 rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
1434 }
1435 if( rc==SQLITE_OK ){
drh20e1f082010-05-31 16:10:12 +00001436 winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
1437 rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
drh83235212010-05-14 16:34:34 +00001438 }
1439 if( rc ) goto shm_open_err;
1440 }
1441
1442 /* Make the new connection a child of the winShmNode */
1443 p->pShmNode = pShmNode;
1444 p->pNext = pShmNode->pFirst;
1445#ifdef SQLITE_DEBUG
1446 p->id = pShmNode->nextShmId++;
1447#endif
1448 pShmNode->pFirst = p;
1449 pShmNode->nRef++;
1450 pDbFd->pShm = p;
1451 winShmLeaveMutex();
1452 return SQLITE_OK;
1453
1454 /* Jump here on any error */
1455shm_open_err:
drh20e1f082010-05-31 16:10:12 +00001456 winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
drh05cb5b22010-06-03 18:02:48 +00001457 winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */
drh83235212010-05-14 16:34:34 +00001458 sqlite3_free(p);
1459 sqlite3_free(pNew);
1460 winShmLeaveMutex();
1461 return rc;
1462}
1463
1464/*
1465** Close a connection to shared-memory. Delete the underlying
1466** storage if deleteFlag is true.
1467*/
1468static int winShmClose(
1469 sqlite3_file *fd, /* Database holding shared memory */
1470 int deleteFlag /* Delete after closing if true */
1471){
1472 winFile *pDbFd; /* Database holding shared-memory */
1473 winShm *p; /* The connection to be closed */
1474 winShmNode *pShmNode; /* The underlying shared-memory file */
1475 winShm **pp; /* For looping over sibling connections */
1476
1477 pDbFd = (winFile*)fd;
1478 p = pDbFd->pShm;
1479 pShmNode = p->pShmNode;
1480
drh83235212010-05-14 16:34:34 +00001481 /* Remove connection p from the set of connections associated
1482 ** with pShmNode */
1483 sqlite3_mutex_enter(pShmNode->mutex);
1484 for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
1485 *pp = p->pNext;
1486
1487 /* Free the connection p */
1488 sqlite3_free(p);
1489 pDbFd->pShm = 0;
1490 sqlite3_mutex_leave(pShmNode->mutex);
1491
1492 /* If pShmNode->nRef has reached 0, then close the underlying
1493 ** shared-memory file, too */
1494 winShmEnterMutex();
1495 assert( pShmNode->nRef>0 );
1496 pShmNode->nRef--;
1497 if( pShmNode->nRef==0 ){
drh05cb5b22010-06-03 18:02:48 +00001498 winShmPurge(pDbFd->pVfs, deleteFlag);
drh83235212010-05-14 16:34:34 +00001499 }
1500 winShmLeaveMutex();
1501
1502 return SQLITE_OK;
1503}
1504
1505/*
dan9785fc92010-06-14 16:16:33 +00001506** This function is called to obtain a pointer to region iRegion of the
1507** shared-memory associated with the database file fd. Shared-memory regions
1508** are numbered starting from zero. Each shared-memory region is szRegion
1509** bytes in size.
drh83235212010-05-14 16:34:34 +00001510**
dan9785fc92010-06-14 16:16:33 +00001511** If an error occurs, an error code is returned and *pp is set to NULL.
drh83235212010-05-14 16:34:34 +00001512**
dan9785fc92010-06-14 16:16:33 +00001513** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
1514** region has not been allocated (by any client, including one running in a
1515** separate process), then *pp is set to NULL and SQLITE_OK returned. If
1516** isWrite is non-zero and the requested shared-memory region has not yet
1517** been allocated, it is allocated by this function.
1518**
1519** If the shared-memory region has already been allocated or is allocated by
1520** this call as described above, then it is mapped into this processes
1521** address space (if it is not already), *pp is set to point to the mapped
1522** memory and SQLITE_OK returned.
drh83235212010-05-14 16:34:34 +00001523*/
dan9785fc92010-06-14 16:16:33 +00001524static int winShmMap(
1525 sqlite3_file *fd, /* Handle open on database file */
1526 int iRegion, /* Region to retrieve */
1527 int szRegion, /* Size of regions */
1528 int isWrite, /* True to extend file if necessary */
1529 void volatile **pp /* OUT: Mapped memory */
drh83235212010-05-14 16:34:34 +00001530){
1531 winFile *pDbFd = (winFile*)fd;
1532 winShm *p = pDbFd->pShm;
1533 winShmNode *pShmNode = p->pShmNode;
1534 int rc = SQLITE_OK;
1535
drh83235212010-05-14 16:34:34 +00001536 sqlite3_mutex_enter(pShmNode->mutex);
dan9785fc92010-06-14 16:16:33 +00001537 assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
1538
1539 if( pShmNode->nRegion<=iRegion ){
1540 struct ShmRegion *apNew; /* New aRegion[] array */
1541 int nByte = (iRegion+1)*szRegion; /* Minimum required file size */
1542 sqlite3_int64 sz; /* Current size of wal-index file */
1543
1544 pShmNode->szRegion = szRegion;
1545
1546 /* The requested region is not mapped into this processes address space.
1547 ** Check to see if it has been allocated (i.e. if the wal-index file is
1548 ** large enough to contain the requested region).
1549 */
1550 rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
1551 if( rc!=SQLITE_OK ){
1552 goto shmpage_out;
drh83235212010-05-14 16:34:34 +00001553 }
dan9785fc92010-06-14 16:16:33 +00001554
1555 if( sz<nByte ){
1556 /* The requested memory region does not exist. If isWrite is set to
1557 ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
1558 **
1559 ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
1560 ** the requested memory region.
1561 */
1562 if( !isWrite ) goto shmpage_out;
1563 rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
1564 if( rc!=SQLITE_OK ){
1565 goto shmpage_out;
1566 }
1567 }
1568
1569 /* Map the requested memory region into this processes address space. */
1570 apNew = (struct ShmRegion *)sqlite3_realloc(
1571 pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
1572 );
1573 if( !apNew ){
1574 rc = SQLITE_IOERR_NOMEM;
1575 goto shmpage_out;
1576 }
1577 pShmNode->aRegion = apNew;
1578
1579 while( pShmNode->nRegion<=iRegion ){
1580 HANDLE hMap; /* file-mapping handle */
1581 void *pMap = 0; /* Mapped memory region */
1582
1583 hMap = CreateFileMapping(pShmNode->hFile.h,
1584 NULL, PAGE_READWRITE, 0, nByte, NULL
1585 );
1586 if( hMap ){
1587 pMap = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
1588 0, 0, nByte
1589 );
1590 }
1591 if( !pMap ){
drh83235212010-05-14 16:34:34 +00001592 pShmNode->lastErrno = GetLastError();
1593 rc = SQLITE_IOERR;
dan9785fc92010-06-14 16:16:33 +00001594 if( hMap ) CloseHandle(hMap);
1595 goto shmpage_out;
drh83235212010-05-14 16:34:34 +00001596 }
dan9785fc92010-06-14 16:16:33 +00001597
1598 pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
1599 pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
1600 pShmNode->nRegion++;
drh83235212010-05-14 16:34:34 +00001601 }
1602 }
dan9785fc92010-06-14 16:16:33 +00001603
1604shmpage_out:
1605 if( pShmNode->nRegion>iRegion ){
1606 char *p = (char *)pShmNode->aRegion[iRegion].pMap;
1607 *pp = (void *)&p[iRegion*szRegion];
1608 }else{
1609 *pp = 0;
1610 }
drh83235212010-05-14 16:34:34 +00001611 sqlite3_mutex_leave(pShmNode->mutex);
1612 return rc;
1613}
1614
1615/*
drh83235212010-05-14 16:34:34 +00001616** Change the lock state for a shared-memory segment.
1617*/
1618static int winShmLock(
drh20e1f082010-05-31 16:10:12 +00001619 sqlite3_file *fd, /* Database file holding the shared memory */
1620 int ofst, /* First lock to acquire or release */
1621 int n, /* Number of locks to acquire or release */
1622 int flags /* What to do with the lock */
drh83235212010-05-14 16:34:34 +00001623){
1624 winFile *pDbFd = (winFile*)fd;
1625 winShm *p = pDbFd->pShm;
1626 winShmNode *pShmNode = p->pShmNode;
1627 int rc = SQLITE_PROTOCOL;
1628
drh20e1f082010-05-31 16:10:12 +00001629 assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
1630 assert( n>=1 );
1631 assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
1632 || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
1633 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
1634 || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
1635 assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
drh83235212010-05-14 16:34:34 +00001636
drh83235212010-05-14 16:34:34 +00001637 sqlite3_mutex_enter(pShmNode->mutex);
drh20e1f082010-05-31 16:10:12 +00001638 if( flags & SQLITE_SHM_UNLOCK ){
1639 rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
1640 }else if( flags & SQLITE_SHM_SHARED ){
1641 rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
1642 }else{
1643 rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
drh83235212010-05-14 16:34:34 +00001644 }
1645 sqlite3_mutex_leave(pShmNode->mutex);
drh20e1f082010-05-31 16:10:12 +00001646 OSTRACE(("SHM-LOCK shmid-%d, pid-%d %s\n",
1647 p->id, (int)GetCurrentProcessId(), rc ? "failed" : "ok"));
drh83235212010-05-14 16:34:34 +00001648 return rc;
1649}
1650
drh286a2882010-05-20 23:51:06 +00001651/*
1652** Implement a memory barrier or memory fence on shared memory.
1653**
1654** All loads and stores begun before the barrier must complete before
1655** any load or store begun after the barrier.
1656*/
1657static void winShmBarrier(
1658 sqlite3_file *fd /* Database holding the shared memory */
1659){
1660 /* MemoryBarrier(); // does not work -- do not know why not */
1661 winShmEnterMutex();
1662 winShmLeaveMutex();
1663}
1664
drh83235212010-05-14 16:34:34 +00001665#else
1666# define winShmOpen 0
drh6b017cc2010-06-14 18:01:46 +00001667# define winShmMap 0
drh83235212010-05-14 16:34:34 +00001668# define winShmLock 0
drh286a2882010-05-20 23:51:06 +00001669# define winShmBarrier 0
drh83235212010-05-14 16:34:34 +00001670# define winShmClose 0
1671#endif /* #ifndef SQLITE_OMIT_WAL */
1672/*
1673***************************** End Shared Memory *****************************
1674****************************************************************************/
1675
drh153c62c2007-08-24 03:51:33 +00001676/*
1677** This vector defines all the methods that can operate on an
1678** sqlite3_file for win32.
1679*/
1680static const sqlite3_io_methods winIoMethod = {
drh83235212010-05-14 16:34:34 +00001681 2, /* iVersion */
drh9c06c952005-11-26 00:25:00 +00001682 winClose,
1683 winRead,
1684 winWrite,
drh9c06c952005-11-26 00:25:00 +00001685 winTruncate,
drh054889e2005-11-30 03:20:31 +00001686 winSync,
drh054889e2005-11-30 03:20:31 +00001687 winFileSize,
1688 winLock,
1689 winUnlock,
drh054889e2005-11-30 03:20:31 +00001690 winCheckReservedLock,
drhcc6bb3e2007-08-31 16:11:35 +00001691 winFileControl,
danielk1977a3d4c882007-03-23 10:08:38 +00001692 winSectorSize,
drh83235212010-05-14 16:34:34 +00001693 winDeviceCharacteristics,
1694 winShmOpen, /* xShmOpen */
drh83235212010-05-14 16:34:34 +00001695 winShmLock, /* xShmLock */
drh6b017cc2010-06-14 18:01:46 +00001696 winShmMap, /* xShmMap */
drh286a2882010-05-20 23:51:06 +00001697 winShmBarrier, /* xShmBarrier */
drh6b017cc2010-06-14 18:01:46 +00001698 winShmClose /* xShmClose */
drh9c06c952005-11-26 00:25:00 +00001699};
1700
drh153c62c2007-08-24 03:51:33 +00001701/***************************************************************************
1702** Here ends the I/O methods that form the sqlite3_io_methods object.
1703**
1704** The next block of code implements the VFS methods.
1705****************************************************************************/
1706
drh054889e2005-11-30 03:20:31 +00001707/*
drh153c62c2007-08-24 03:51:33 +00001708** Convert a UTF-8 filename into whatever form the underlying
1709** operating system wants filenames in. Space to hold the result
drhb11caac2007-08-24 17:52:21 +00001710** is obtained from malloc and must be freed by the calling
drh153c62c2007-08-24 03:51:33 +00001711** function.
drh054889e2005-11-30 03:20:31 +00001712*/
drh153c62c2007-08-24 03:51:33 +00001713static void *convertUtf8Filename(const char *zFilename){
1714 void *zConverted = 0;
1715 if( isNT() ){
1716 zConverted = utf8ToUnicode(zFilename);
shane891adea2008-10-22 16:55:47 +00001717/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1718*/
1719#if SQLITE_OS_WINCE==0
drh054889e2005-11-30 03:20:31 +00001720 }else{
drh153c62c2007-08-24 03:51:33 +00001721 zConverted = utf8ToMbcs(zFilename);
shane891adea2008-10-22 16:55:47 +00001722#endif
drh054889e2005-11-30 03:20:31 +00001723 }
drh153c62c2007-08-24 03:51:33 +00001724 /* caller will handle out of memory */
1725 return zConverted;
1726}
1727
1728/*
danielk197717b90b52008-06-06 11:11:25 +00001729** Create a temporary file name in zBuf. zBuf must be big enough to
1730** hold at pVfs->mxPathname characters.
1731*/
1732static int getTempname(int nBuf, char *zBuf){
1733 static char zChars[] =
1734 "abcdefghijklmnopqrstuvwxyz"
1735 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1736 "0123456789";
shane3582c5a2008-07-31 01:34:34 +00001737 size_t i, j;
danielk197717b90b52008-06-06 11:11:25 +00001738 char zTempPath[MAX_PATH+1];
1739 if( sqlite3_temp_directory ){
1740 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1741 }else if( isNT() ){
1742 char *zMulti;
1743 WCHAR zWidePath[MAX_PATH];
1744 GetTempPathW(MAX_PATH-30, zWidePath);
1745 zMulti = unicodeToUtf8(zWidePath);
1746 if( zMulti ){
1747 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1748 free(zMulti);
1749 }else{
1750 return SQLITE_NOMEM;
1751 }
shane891adea2008-10-22 16:55:47 +00001752/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1753** Since the ASCII version of these Windows API do not exist for WINCE,
1754** it's important to not reference them for WINCE builds.
1755*/
1756#if SQLITE_OS_WINCE==0
danielk197717b90b52008-06-06 11:11:25 +00001757 }else{
1758 char *zUtf8;
1759 char zMbcsPath[MAX_PATH];
1760 GetTempPathA(MAX_PATH-30, zMbcsPath);
drh1d298852008-11-18 19:18:52 +00001761 zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
danielk197717b90b52008-06-06 11:11:25 +00001762 if( zUtf8 ){
1763 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1764 free(zUtf8);
1765 }else{
1766 return SQLITE_NOMEM;
1767 }
shane891adea2008-10-22 16:55:47 +00001768#endif
danielk197717b90b52008-06-06 11:11:25 +00001769 }
drhea678832008-12-10 19:26:22 +00001770 for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
danielk197717b90b52008-06-06 11:11:25 +00001771 zTempPath[i] = 0;
1772 sqlite3_snprintf(nBuf-30, zBuf,
1773 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
drhea678832008-12-10 19:26:22 +00001774 j = sqlite3Strlen30(zBuf);
danielk197717b90b52008-06-06 11:11:25 +00001775 sqlite3_randomness(20, &zBuf[j]);
1776 for(i=0; i<20; i++, j++){
1777 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1778 }
1779 zBuf[j] = 0;
drh308c2a52010-05-14 11:30:18 +00001780 OSTRACE(("TEMP FILENAME: %s\n", zBuf));
danielk197717b90b52008-06-06 11:11:25 +00001781 return SQLITE_OK;
1782}
1783
shane820800d2008-07-22 05:32:03 +00001784/*
1785** The return value of getLastErrorMsg
1786** is zero if the error message fits in the buffer, or non-zero
1787** otherwise (if the message was truncated).
1788*/
1789static int getLastErrorMsg(int nBuf, char *zBuf){
shane820800d2008-07-22 05:32:03 +00001790 /* FormatMessage returns 0 on failure. Otherwise it
1791 ** returns the number of TCHARs written to the output
1792 ** buffer, excluding the terminating null char.
1793 */
shaneea598922009-10-21 02:00:47 +00001794 DWORD error = GetLastError();
1795 DWORD dwLen = 0;
shanef639c402009-11-03 19:42:30 +00001796 char *zOut = 0;
shane820800d2008-07-22 05:32:03 +00001797
shaneea598922009-10-21 02:00:47 +00001798 if( isNT() ){
1799 WCHAR *zTempWide = NULL;
1800 dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1801 NULL,
1802 error,
1803 0,
1804 (LPWSTR) &zTempWide,
1805 0,
1806 0);
1807 if( dwLen > 0 ){
1808 /* allocate a buffer and convert to UTF8 */
1809 zOut = unicodeToUtf8(zTempWide);
1810 /* free the system buffer allocated by FormatMessage */
1811 LocalFree(zTempWide);
1812 }
1813/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1814** Since the ASCII version of these Windows API do not exist for WINCE,
1815** it's important to not reference them for WINCE builds.
1816*/
1817#if SQLITE_OS_WINCE==0
1818 }else{
1819 char *zTemp = NULL;
1820 dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1821 NULL,
1822 error,
1823 0,
1824 (LPSTR) &zTemp,
1825 0,
1826 0);
1827 if( dwLen > 0 ){
1828 /* allocate a buffer and convert to UTF8 */
1829 zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
1830 /* free the system buffer allocated by FormatMessage */
1831 LocalFree(zTemp);
1832 }
1833#endif
1834 }
1835 if( 0 == dwLen ){
1836 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
1837 }else{
1838 /* copy a maximum of nBuf chars to output buffer */
1839 sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
1840 /* free the UTF8 buffer */
1841 free(zOut);
1842 }
shane820800d2008-07-22 05:32:03 +00001843 return 0;
1844}
1845
danielk197717b90b52008-06-06 11:11:25 +00001846/*
drh153c62c2007-08-24 03:51:33 +00001847** Open a file.
1848*/
1849static int winOpen(
1850 sqlite3_vfs *pVfs, /* Not used */
1851 const char *zName, /* Name of the file (UTF-8) */
1852 sqlite3_file *id, /* Write the SQLite file handle here */
1853 int flags, /* Open mode flags */
1854 int *pOutFlags /* Status return flags */
1855){
1856 HANDLE h;
1857 DWORD dwDesiredAccess;
1858 DWORD dwShareMode;
1859 DWORD dwCreationDisposition;
1860 DWORD dwFlagsAndAttributes = 0;
shaned94b0552008-09-30 04:20:07 +00001861#if SQLITE_OS_WINCE
1862 int isTemp = 0;
1863#endif
drh153c62c2007-08-24 03:51:33 +00001864 winFile *pFile = (winFile*)id;
danielk197717b90b52008-06-06 11:11:25 +00001865 void *zConverted; /* Filename in OS encoding */
1866 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
1867 char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */
1868
shane50daafc2009-03-05 05:54:55 +00001869 assert( id!=0 );
shane18e526c2008-12-10 22:30:24 +00001870 UNUSED_PARAMETER(pVfs);
1871
shaneh04882a92010-05-11 02:49:39 +00001872 pFile->h = INVALID_HANDLE_VALUE;
1873
danielk197717b90b52008-06-06 11:11:25 +00001874 /* If the second argument to this function is NULL, generate a
1875 ** temporary file name to use
1876 */
1877 if( !zUtf8Name ){
1878 int rc = getTempname(MAX_PATH+1, zTmpname);
1879 if( rc!=SQLITE_OK ){
1880 return rc;
1881 }
1882 zUtf8Name = zTmpname;
1883 }
1884
1885 /* Convert the filename to the system encoding. */
1886 zConverted = convertUtf8Filename(zUtf8Name);
drh153c62c2007-08-24 03:51:33 +00001887 if( zConverted==0 ){
1888 return SQLITE_NOMEM;
1889 }
1890
1891 if( flags & SQLITE_OPEN_READWRITE ){
1892 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1893 }else{
1894 dwDesiredAccess = GENERIC_READ;
1895 }
shane68d405e2009-04-23 19:08:32 +00001896 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
1897 ** created. SQLite doesn't use it to indicate "exclusive access"
1898 ** as it is usually understood.
1899 */
1900 assert(!(flags & SQLITE_OPEN_EXCLUSIVE) || (flags & SQLITE_OPEN_CREATE));
1901 if( flags & SQLITE_OPEN_EXCLUSIVE ){
1902 /* Creates a new file, only if it does not already exist. */
1903 /* If the file exists, it fails. */
1904 dwCreationDisposition = CREATE_NEW;
1905 }else if( flags & SQLITE_OPEN_CREATE ){
1906 /* Open existing file, or create if it doesn't exist */
drh153c62c2007-08-24 03:51:33 +00001907 dwCreationDisposition = OPEN_ALWAYS;
1908 }else{
shane68d405e2009-04-23 19:08:32 +00001909 /* Opens a file, only if it exists. */
drh153c62c2007-08-24 03:51:33 +00001910 dwCreationDisposition = OPEN_EXISTING;
1911 }
shane68d405e2009-04-23 19:08:32 +00001912 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
drh64c1ea62007-12-10 21:11:31 +00001913 if( flags & SQLITE_OPEN_DELETEONCLOSE ){
danielk197729bafea2008-06-26 10:41:19 +00001914#if SQLITE_OS_WINCE
drh0cd1ea52007-10-08 15:06:03 +00001915 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
shaned94b0552008-09-30 04:20:07 +00001916 isTemp = 1;
drh0cd1ea52007-10-08 15:06:03 +00001917#else
drh153c62c2007-08-24 03:51:33 +00001918 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
1919 | FILE_ATTRIBUTE_HIDDEN
1920 | FILE_FLAG_DELETE_ON_CLOSE;
drh0cd1ea52007-10-08 15:06:03 +00001921#endif
drh153c62c2007-08-24 03:51:33 +00001922 }else{
1923 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
1924 }
drh496936c2007-10-08 12:21:10 +00001925 /* Reports from the internet are that performance is always
1926 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
shaned94b0552008-09-30 04:20:07 +00001927#if SQLITE_OS_WINCE
drh496936c2007-10-08 12:21:10 +00001928 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
shaned94b0552008-09-30 04:20:07 +00001929#endif
drh153c62c2007-08-24 03:51:33 +00001930 if( isNT() ){
1931 h = CreateFileW((WCHAR*)zConverted,
1932 dwDesiredAccess,
1933 dwShareMode,
1934 NULL,
1935 dwCreationDisposition,
1936 dwFlagsAndAttributes,
1937 NULL
1938 );
shane891adea2008-10-22 16:55:47 +00001939/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1940** Since the ASCII version of these Windows API do not exist for WINCE,
1941** it's important to not reference them for WINCE builds.
1942*/
1943#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001944 }else{
drh153c62c2007-08-24 03:51:33 +00001945 h = CreateFileA((char*)zConverted,
1946 dwDesiredAccess,
1947 dwShareMode,
1948 NULL,
1949 dwCreationDisposition,
1950 dwFlagsAndAttributes,
1951 NULL
1952 );
shane891adea2008-10-22 16:55:47 +00001953#endif
drh153c62c2007-08-24 03:51:33 +00001954 }
shaneh50f64552010-05-12 17:14:59 +00001955 OSTRACE(("OPEN %d %s 0x%lx %s\n",
1956 h, zName, dwDesiredAccess,
1957 h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
drh153c62c2007-08-24 03:51:33 +00001958 if( h==INVALID_HANDLE_VALUE ){
drhe1843af2007-08-30 16:46:04 +00001959 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001960 if( flags & SQLITE_OPEN_READWRITE ){
drha1115772009-03-30 13:04:17 +00001961 return winOpen(pVfs, zName, id,
drh153c62c2007-08-24 03:51:33 +00001962 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
1963 }else{
drh9978c972010-02-23 17:36:32 +00001964 return SQLITE_CANTOPEN_BKPT;
drh153c62c2007-08-24 03:51:33 +00001965 }
1966 }
1967 if( pOutFlags ){
1968 if( flags & SQLITE_OPEN_READWRITE ){
1969 *pOutFlags = SQLITE_OPEN_READWRITE;
1970 }else{
1971 *pOutFlags = SQLITE_OPEN_READONLY;
1972 }
1973 }
1974 memset(pFile, 0, sizeof(*pFile));
1975 pFile->pMethod = &winIoMethod;
1976 pFile->h = h;
shane9db299f2009-01-30 05:59:10 +00001977 pFile->lastErrno = NO_ERROR;
drh83235212010-05-14 16:34:34 +00001978 pFile->pVfs = pVfs;
1979 pFile->pShm = 0;
1980 pFile->zPath = zName;
shane50daafc2009-03-05 05:54:55 +00001981 pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
danielk197729bafea2008-06-26 10:41:19 +00001982#if SQLITE_OS_WINCE
drh153c62c2007-08-24 03:51:33 +00001983 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
1984 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
drhaab2e6d2007-10-08 12:22:57 +00001985 && !winceCreateLock(zName, pFile)
drh153c62c2007-08-24 03:51:33 +00001986 ){
1987 CloseHandle(h);
drhb11caac2007-08-24 17:52:21 +00001988 free(zConverted);
drh9978c972010-02-23 17:36:32 +00001989 return SQLITE_CANTOPEN_BKPT;
drh153c62c2007-08-24 03:51:33 +00001990 }
drhfc3afb62007-10-09 15:36:10 +00001991 if( isTemp ){
drh153c62c2007-08-24 03:51:33 +00001992 pFile->zDeleteOnClose = zConverted;
1993 }else
1994#endif
1995 {
drhb11caac2007-08-24 17:52:21 +00001996 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001997 }
drhaf5f0402007-09-03 17:09:03 +00001998 OpenCounter(+1);
drh153c62c2007-08-24 03:51:33 +00001999 return SQLITE_OK;
2000}
2001
2002/*
2003** Delete the named file.
2004**
2005** Note that windows does not allow a file to be deleted if some other
2006** process has it open. Sometimes a virus scanner or indexing program
2007** will open a journal file shortly after it is created in order to do
shane3582c5a2008-07-31 01:34:34 +00002008** whatever it does. While this other process is holding the
drh153c62c2007-08-24 03:51:33 +00002009** file open, we will be unable to delete it. To work around this
2010** problem, we delay 100 milliseconds and try to delete again. Up
2011** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
2012** up and returning an error.
2013*/
drhf024f0b2007-11-07 01:19:07 +00002014#define MX_DELETION_ATTEMPTS 5
drh153c62c2007-08-24 03:51:33 +00002015static int winDelete(
2016 sqlite3_vfs *pVfs, /* Not used on win32 */
2017 const char *zFilename, /* Name of file to delete */
2018 int syncDir /* Not used on win32 */
2019){
2020 int cnt = 0;
shaned94b0552008-09-30 04:20:07 +00002021 DWORD rc;
drhea678832008-12-10 19:26:22 +00002022 DWORD error = 0;
drh153c62c2007-08-24 03:51:33 +00002023 void *zConverted = convertUtf8Filename(zFilename);
shane18e526c2008-12-10 22:30:24 +00002024 UNUSED_PARAMETER(pVfs);
2025 UNUSED_PARAMETER(syncDir);
drh153c62c2007-08-24 03:51:33 +00002026 if( zConverted==0 ){
2027 return SQLITE_NOMEM;
2028 }
2029 SimulateIOError(return SQLITE_IOERR_DELETE);
2030 if( isNT() ){
2031 do{
drhf024f0b2007-11-07 01:19:07 +00002032 DeleteFileW(zConverted);
shane3582c5a2008-07-31 01:34:34 +00002033 }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
2034 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00002035 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00002036 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00002037/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2038** Since the ASCII version of these Windows API do not exist for WINCE,
2039** it's important to not reference them for WINCE builds.
2040*/
2041#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00002042 }else{
drh153c62c2007-08-24 03:51:33 +00002043 do{
drhf024f0b2007-11-07 01:19:07 +00002044 DeleteFileA(zConverted);
shane3582c5a2008-07-31 01:34:34 +00002045 }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
2046 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00002047 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00002048 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00002049#endif
drh153c62c2007-08-24 03:51:33 +00002050 }
drhb11caac2007-08-24 17:52:21 +00002051 free(zConverted);
drh83235212010-05-14 16:34:34 +00002052 OSTRACE(("DELETE \"%s\" %s\n", zFilename,
2053 ( (rc==INVALID_FILE_ATTRIBUTES) && (error==ERROR_FILE_NOT_FOUND)) ?
2054 "ok" : "failed" ));
2055
shaned94b0552008-09-30 04:20:07 +00002056 return ( (rc == INVALID_FILE_ATTRIBUTES)
shane3582c5a2008-07-31 01:34:34 +00002057 && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
drh153c62c2007-08-24 03:51:33 +00002058}
2059
2060/*
2061** Check the existance and status of a file.
2062*/
2063static int winAccess(
2064 sqlite3_vfs *pVfs, /* Not used on win32 */
2065 const char *zFilename, /* Name of file to check */
danielk1977861f7452008-06-05 11:39:11 +00002066 int flags, /* Type of test to make on this file */
2067 int *pResOut /* OUT: Result */
drh153c62c2007-08-24 03:51:33 +00002068){
2069 DWORD attr;
drhea678832008-12-10 19:26:22 +00002070 int rc = 0;
drh153c62c2007-08-24 03:51:33 +00002071 void *zConverted = convertUtf8Filename(zFilename);
shane18e526c2008-12-10 22:30:24 +00002072 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00002073 if( zConverted==0 ){
2074 return SQLITE_NOMEM;
2075 }
2076 if( isNT() ){
2077 attr = GetFileAttributesW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00002078/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2079** Since the ASCII version of these Windows API do not exist for WINCE,
2080** it's important to not reference them for WINCE builds.
2081*/
2082#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00002083 }else{
drh153c62c2007-08-24 03:51:33 +00002084 attr = GetFileAttributesA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00002085#endif
drh153c62c2007-08-24 03:51:33 +00002086 }
drhb11caac2007-08-24 17:52:21 +00002087 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00002088 switch( flags ){
drh50d3f902007-08-27 21:10:36 +00002089 case SQLITE_ACCESS_READ:
drh153c62c2007-08-24 03:51:33 +00002090 case SQLITE_ACCESS_EXISTS:
shane820800d2008-07-22 05:32:03 +00002091 rc = attr!=INVALID_FILE_ATTRIBUTES;
drh153c62c2007-08-24 03:51:33 +00002092 break;
2093 case SQLITE_ACCESS_READWRITE:
2094 rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
2095 break;
drh153c62c2007-08-24 03:51:33 +00002096 default:
2097 assert(!"Invalid flags argument");
2098 }
danielk1977861f7452008-06-05 11:39:11 +00002099 *pResOut = rc;
2100 return SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00002101}
2102
2103
drh153c62c2007-08-24 03:51:33 +00002104/*
drh153c62c2007-08-24 03:51:33 +00002105** Turn a relative pathname into a full pathname. Write the full
2106** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
2107** bytes in size.
2108*/
2109static int winFullPathname(
danielk1977adfb9b02007-09-17 07:02:56 +00002110 sqlite3_vfs *pVfs, /* Pointer to vfs object */
2111 const char *zRelative, /* Possibly relative input path */
2112 int nFull, /* Size of output buffer in bytes */
2113 char *zFull /* Output buffer */
drh153c62c2007-08-24 03:51:33 +00002114){
drh1bd10f82008-12-10 21:19:56 +00002115
drh153c62c2007-08-24 03:51:33 +00002116#if defined(__CYGWIN__)
shane18e526c2008-12-10 22:30:24 +00002117 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00002118 cygwin_conv_to_full_win32_path(zRelative, zFull);
danielk1977076f1c02007-09-12 14:09:23 +00002119 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00002120#endif
2121
danielk197729bafea2008-06-26 10:41:19 +00002122#if SQLITE_OS_WINCE
shane18e526c2008-12-10 22:30:24 +00002123 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00002124 /* WinCE has no concept of a relative pathname, or so I am told. */
2125 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
drhe8256092007-10-09 15:20:39 +00002126 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00002127#endif
2128
danielk197729bafea2008-06-26 10:41:19 +00002129#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
drh153c62c2007-08-24 03:51:33 +00002130 int nByte;
2131 void *zConverted;
2132 char *zOut;
shane18e526c2008-12-10 22:30:24 +00002133 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00002134 zConverted = convertUtf8Filename(zRelative);
2135 if( isNT() ){
2136 WCHAR *zTemp;
2137 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00002138 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00002139 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00002140 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00002141 return SQLITE_NOMEM;
2142 }
2143 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00002144 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00002145 zOut = unicodeToUtf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00002146 free(zTemp);
shane891adea2008-10-22 16:55:47 +00002147/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2148** Since the ASCII version of these Windows API do not exist for WINCE,
2149** it's important to not reference them for WINCE builds.
2150*/
2151#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00002152 }else{
2153 char *zTemp;
2154 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00002155 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00002156 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00002157 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00002158 return SQLITE_NOMEM;
2159 }
2160 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00002161 free(zConverted);
drh1d298852008-11-18 19:18:52 +00002162 zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00002163 free(zTemp);
shane891adea2008-10-22 16:55:47 +00002164#endif
drh153c62c2007-08-24 03:51:33 +00002165 }
2166 if( zOut ){
drhb11caac2007-08-24 17:52:21 +00002167 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
2168 free(zOut);
drh153c62c2007-08-24 03:51:33 +00002169 return SQLITE_OK;
2170 }else{
2171 return SQLITE_NOMEM;
2172 }
2173#endif
2174}
2175
shane50daafc2009-03-05 05:54:55 +00002176/*
2177** Get the sector size of the device used to store
2178** file.
2179*/
2180static int getSectorSize(
2181 sqlite3_vfs *pVfs,
2182 const char *zRelative /* UTF-8 file name */
2183){
2184 DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
shane11bb41f2009-09-10 20:23:30 +00002185 /* GetDiskFreeSpace is not supported under WINCE */
2186#if SQLITE_OS_WINCE
2187 UNUSED_PARAMETER(pVfs);
2188 UNUSED_PARAMETER(zRelative);
2189#else
shane50daafc2009-03-05 05:54:55 +00002190 char zFullpath[MAX_PATH+1];
2191 int rc;
shane11bb41f2009-09-10 20:23:30 +00002192 DWORD dwRet = 0;
2193 DWORD dwDummy;
shane50daafc2009-03-05 05:54:55 +00002194
2195 /*
2196 ** We need to get the full path name of the file
2197 ** to get the drive letter to look up the sector
2198 ** size.
2199 */
2200 rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
2201 if( rc == SQLITE_OK )
2202 {
2203 void *zConverted = convertUtf8Filename(zFullpath);
2204 if( zConverted ){
2205 if( isNT() ){
shane50daafc2009-03-05 05:54:55 +00002206 /* trim path to just drive reference */
2207 WCHAR *p = zConverted;
shane7a8537b2009-04-15 14:36:25 +00002208 for(;*p;p++){
2209 if( *p == '\\' ){
2210 *p = '\0';
shane50daafc2009-03-05 05:54:55 +00002211 break;
2212 }
2213 }
2214 dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted,
chwa5dc7f72009-04-09 14:27:06 +00002215 &dwDummy,
shane50daafc2009-03-05 05:54:55 +00002216 &bytesPerSector,
chwa5dc7f72009-04-09 14:27:06 +00002217 &dwDummy,
2218 &dwDummy);
shane50daafc2009-03-05 05:54:55 +00002219 }else{
shane50daafc2009-03-05 05:54:55 +00002220 /* trim path to just drive reference */
shaneea598922009-10-21 02:00:47 +00002221 char *p = (char *)zConverted;
shane7a8537b2009-04-15 14:36:25 +00002222 for(;*p;p++){
2223 if( *p == '\\' ){
2224 *p = '\0';
shane50daafc2009-03-05 05:54:55 +00002225 break;
2226 }
2227 }
shaneea598922009-10-21 02:00:47 +00002228 dwRet = GetDiskFreeSpaceA((char*)zConverted,
chwa5dc7f72009-04-09 14:27:06 +00002229 &dwDummy,
shane50daafc2009-03-05 05:54:55 +00002230 &bytesPerSector,
chwa5dc7f72009-04-09 14:27:06 +00002231 &dwDummy,
2232 &dwDummy);
shane50daafc2009-03-05 05:54:55 +00002233 }
2234 free(zConverted);
2235 }
2236 if( !dwRet ){
2237 bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
2238 }
2239 }
shane11bb41f2009-09-10 20:23:30 +00002240#endif
shane50daafc2009-03-05 05:54:55 +00002241 return (int) bytesPerSector;
2242}
2243
drh153c62c2007-08-24 03:51:33 +00002244#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh761df872006-12-21 01:29:22 +00002245/*
2246** Interfaces for opening a shared library, finding entry points
2247** within the shared library, and closing the shared library.
2248*/
drh153c62c2007-08-24 03:51:33 +00002249/*
2250** Interfaces for opening a shared library, finding entry points
2251** within the shared library, and closing the shared library.
2252*/
2253static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
drh761df872006-12-21 01:29:22 +00002254 HANDLE h;
2255 void *zConverted = convertUtf8Filename(zFilename);
drh1bd10f82008-12-10 21:19:56 +00002256 UNUSED_PARAMETER(pVfs);
drh761df872006-12-21 01:29:22 +00002257 if( zConverted==0 ){
2258 return 0;
2259 }
2260 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00002261 h = LoadLibraryW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00002262/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
2263** Since the ASCII version of these Windows API do not exist for WINCE,
2264** it's important to not reference them for WINCE builds.
2265*/
2266#if SQLITE_OS_WINCE==0
drh761df872006-12-21 01:29:22 +00002267 }else{
drh584c0942006-12-21 03:20:40 +00002268 h = LoadLibraryA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00002269#endif
drh761df872006-12-21 01:29:22 +00002270 }
drhb11caac2007-08-24 17:52:21 +00002271 free(zConverted);
drh761df872006-12-21 01:29:22 +00002272 return (void*)h;
drh761df872006-12-21 01:29:22 +00002273}
drh153c62c2007-08-24 03:51:33 +00002274static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
drh1bd10f82008-12-10 21:19:56 +00002275 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00002276 getLastErrorMsg(nBuf, zBufOut);
drh153c62c2007-08-24 03:51:33 +00002277}
drh1875f7a2008-12-08 18:19:17 +00002278void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
drh1bd10f82008-12-10 21:19:56 +00002279 UNUSED_PARAMETER(pVfs);
danielk197729bafea2008-06-26 10:41:19 +00002280#if SQLITE_OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00002281 /* The GetProcAddressA() routine is only available on wince. */
drh1875f7a2008-12-08 18:19:17 +00002282 return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00002283#else
2284 /* All other windows platforms expect GetProcAddress() to take
2285 ** an Ansi string regardless of the _UNICODE setting */
drh1875f7a2008-12-08 18:19:17 +00002286 return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00002287#endif
drh761df872006-12-21 01:29:22 +00002288}
drh153c62c2007-08-24 03:51:33 +00002289void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh1bd10f82008-12-10 21:19:56 +00002290 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00002291 FreeLibrary((HANDLE)pHandle);
drh761df872006-12-21 01:29:22 +00002292}
drh153c62c2007-08-24 03:51:33 +00002293#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
2294 #define winDlOpen 0
2295 #define winDlError 0
2296 #define winDlSym 0
2297 #define winDlClose 0
2298#endif
2299
drh761df872006-12-21 01:29:22 +00002300
drh0ccebe72005-06-07 22:22:50 +00002301/*
drh153c62c2007-08-24 03:51:33 +00002302** Write up to nBuf bytes of randomness into zBuf.
drhbbd42a62004-05-22 17:41:58 +00002303*/
drh153c62c2007-08-24 03:51:33 +00002304static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drhd1a79312007-09-03 13:06:11 +00002305 int n = 0;
shanec7b7f1a2008-11-19 21:35:46 +00002306 UNUSED_PARAMETER(pVfs);
2307#if defined(SQLITE_TEST)
2308 n = nBuf;
2309 memset(zBuf, 0, nBuf);
2310#else
drh86742612007-09-05 17:06:03 +00002311 if( sizeof(SYSTEMTIME)<=nBuf-n ){
drhd1a79312007-09-03 13:06:11 +00002312 SYSTEMTIME x;
2313 GetSystemTime(&x);
2314 memcpy(&zBuf[n], &x, sizeof(x));
2315 n += sizeof(x);
drh153c62c2007-08-24 03:51:33 +00002316 }
drhd1a79312007-09-03 13:06:11 +00002317 if( sizeof(DWORD)<=nBuf-n ){
2318 DWORD pid = GetCurrentProcessId();
2319 memcpy(&zBuf[n], &pid, sizeof(pid));
2320 n += sizeof(pid);
2321 }
2322 if( sizeof(DWORD)<=nBuf-n ){
2323 DWORD cnt = GetTickCount();
2324 memcpy(&zBuf[n], &cnt, sizeof(cnt));
2325 n += sizeof(cnt);
2326 }
2327 if( sizeof(LARGE_INTEGER)<=nBuf-n ){
2328 LARGE_INTEGER i;
2329 QueryPerformanceCounter(&i);
2330 memcpy(&zBuf[n], &i, sizeof(i));
2331 n += sizeof(i);
2332 }
shanec7b7f1a2008-11-19 21:35:46 +00002333#endif
drhd1a79312007-09-03 13:06:11 +00002334 return n;
drhbbd42a62004-05-22 17:41:58 +00002335}
2336
drh153c62c2007-08-24 03:51:33 +00002337
drhbbd42a62004-05-22 17:41:58 +00002338/*
2339** Sleep for a little while. Return the amount of time slept.
2340*/
drh153c62c2007-08-24 03:51:33 +00002341static int winSleep(sqlite3_vfs *pVfs, int microsec){
2342 Sleep((microsec+999)/1000);
drh1bd10f82008-12-10 21:19:56 +00002343 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00002344 return ((microsec+999)/1000)*1000;
drhbbd42a62004-05-22 17:41:58 +00002345}
2346
2347/*
shaneh04882a92010-05-11 02:49:39 +00002348** The following variable, if set to a non-zero value, is interpreted as
2349** the number of seconds since 1970 and is used to set the result of
2350** sqlite3OsCurrentTime() during testing.
drhbbd42a62004-05-22 17:41:58 +00002351*/
2352#ifdef SQLITE_TEST
shaneh04882a92010-05-11 02:49:39 +00002353int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */
drhbbd42a62004-05-22 17:41:58 +00002354#endif
2355
2356/*
shaneh04882a92010-05-11 02:49:39 +00002357** Find the current time (in Universal Coordinated Time). Write into *piNow
2358** the current time and date as a Julian Day number times 86_400_000. In
2359** other words, write into *piNow the number of milliseconds since the Julian
2360** epoch of noon in Greenwich on November 24, 4714 B.C according to the
2361** proleptic Gregorian calendar.
2362**
2363** On success, return 0. Return 1 if the time and date cannot be found.
drhbbd42a62004-05-22 17:41:58 +00002364*/
shaneh04882a92010-05-11 02:49:39 +00002365static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
drhbbd42a62004-05-22 17:41:58 +00002366 /* FILETIME structure is a 64-bit value representing the number of
2367 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
2368 */
shaneh04882a92010-05-11 02:49:39 +00002369 FILETIME ft;
2370 static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
2371#ifdef SQLITE_TEST
2372 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
2373#endif
shaneb08a67a2009-03-31 03:41:56 +00002374 /* 2^32 - to avoid use of LL and warnings in gcc */
2375 static const sqlite3_int64 max32BitValue =
2376 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
drh5c905d62009-03-30 12:42:45 +00002377
danielk197729bafea2008-06-26 10:41:19 +00002378#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +00002379 SYSTEMTIME time;
2380 GetSystemTime(&time);
shane820800d2008-07-22 05:32:03 +00002381 /* if SystemTimeToFileTime() fails, it returns zero. */
2382 if (!SystemTimeToFileTime(&time,&ft)){
2383 return 1;
2384 }
drhcc78fea2006-01-06 16:17:05 +00002385#else
drhbbd42a62004-05-22 17:41:58 +00002386 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00002387#endif
shaneh04882a92010-05-11 02:49:39 +00002388
2389 *piNow = winFiletimeEpoch +
2390 ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
2391 (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)1000;
2392
drhbbd42a62004-05-22 17:41:58 +00002393#ifdef SQLITE_TEST
2394 if( sqlite3_current_time ){
shaneh04882a92010-05-11 02:49:39 +00002395 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
drhbbd42a62004-05-22 17:41:58 +00002396 }
2397#endif
shaneh04882a92010-05-11 02:49:39 +00002398 UNUSED_PARAMETER(pVfs);
drhbbd42a62004-05-22 17:41:58 +00002399 return 0;
2400}
2401
shane820800d2008-07-22 05:32:03 +00002402/*
shaneh04882a92010-05-11 02:49:39 +00002403** Find the current time (in Universal Coordinated Time). Write the
2404** current time and date as a Julian Day number into *prNow and
2405** return 0. Return 1 if the time and date cannot be found.
2406*/
2407int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
2408 int rc;
2409 sqlite3_int64 i;
2410 rc = winCurrentTimeInt64(pVfs, &i);
2411 if( !rc ){
2412 *prNow = i/86400000.0;
2413 }
2414 return rc;
2415}
2416
2417/*
shane820800d2008-07-22 05:32:03 +00002418** The idea is that this function works like a combination of
2419** GetLastError() and FormatMessage() on windows (or errno and
2420** strerror_r() on unix). After an error is returned by an OS
2421** function, SQLite calls this function with zBuf pointing to
2422** a buffer of nBuf bytes. The OS layer should populate the
2423** buffer with a nul-terminated UTF-8 encoded error message
shanebe217792009-03-05 04:20:31 +00002424** describing the last IO error to have occurred within the calling
shane820800d2008-07-22 05:32:03 +00002425** thread.
2426**
2427** If the error message is too large for the supplied buffer,
2428** it should be truncated. The return value of xGetLastError
2429** is zero if the error message fits in the buffer, or non-zero
2430** otherwise (if the message was truncated). If non-zero is returned,
2431** then it is not necessary to include the nul-terminator character
2432** in the output buffer.
2433**
2434** Not supplying an error message will have no adverse effect
2435** on SQLite. It is fine to have an implementation that never
2436** returns an error message:
2437**
2438** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
2439** assert(zBuf[0]=='\0');
2440** return 0;
2441** }
2442**
2443** However if an error message is supplied, it will be incorporated
2444** by sqlite into the error message available to the user using
2445** sqlite3_errmsg(), possibly making IO errors easier to debug.
2446*/
danielk1977bcb97fe2008-06-06 15:49:29 +00002447static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drh1bd10f82008-12-10 21:19:56 +00002448 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00002449 return getLastErrorMsg(nBuf, zBuf);
danielk1977bcb97fe2008-06-06 15:49:29 +00002450}
drhb4bc7052006-01-11 23:40:33 +00002451
shaneh04882a92010-05-11 02:49:39 +00002452
2453
drhb4bc7052006-01-11 23:40:33 +00002454/*
danielk1977c0fa4c52008-06-25 17:19:00 +00002455** Initialize and deinitialize the operating system interface.
danielk197713a68c32005-12-15 10:11:30 +00002456*/
danielk1977c0fa4c52008-06-25 17:19:00 +00002457int sqlite3_os_init(void){
drh153c62c2007-08-24 03:51:33 +00002458 static sqlite3_vfs winVfs = {
shaneh04882a92010-05-11 02:49:39 +00002459 2, /* iVersion */
2460 sizeof(winFile), /* szOsFile */
2461 MAX_PATH, /* mxPathname */
2462 0, /* pNext */
2463 "win32", /* zName */
2464 0, /* pAppData */
2465 winOpen, /* xOpen */
2466 winDelete, /* xDelete */
2467 winAccess, /* xAccess */
2468 winFullPathname, /* xFullPathname */
2469 winDlOpen, /* xDlOpen */
2470 winDlError, /* xDlError */
2471 winDlSym, /* xDlSym */
2472 winDlClose, /* xDlClose */
2473 winRandomness, /* xRandomness */
2474 winSleep, /* xSleep */
2475 winCurrentTime, /* xCurrentTime */
2476 winGetLastError, /* xGetLastError */
shaneh04882a92010-05-11 02:49:39 +00002477 0, /* xRename */
2478 winCurrentTimeInt64, /* xCurrentTimeInt64 */
drh153c62c2007-08-24 03:51:33 +00002479 };
dane1ab2192009-08-17 15:16:19 +00002480
danielk1977c0fa4c52008-06-25 17:19:00 +00002481 sqlite3_vfs_register(&winVfs, 1);
2482 return SQLITE_OK;
danielk197713a68c32005-12-15 10:11:30 +00002483}
danielk1977c0fa4c52008-06-25 17:19:00 +00002484int sqlite3_os_end(void){
2485 return SQLITE_OK;
2486}
drh40257ff2008-06-13 18:24:27 +00002487
danielk197729bafea2008-06-26 10:41:19 +00002488#endif /* SQLITE_OS_WIN */