blob: bd23a848d3e3de7d74723be8ff5fe449a332bced [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
79/*
drh72aead82006-01-23 15:54:25 +000080** WinCE lacks native support for file locking so we have to fake it
81** with some code of our own.
82*/
danielk197729bafea2008-06-26 10:41:19 +000083#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +000084typedef struct winceLock {
85 int nReaders; /* Number of reader locks obtained */
86 BOOL bPending; /* Indicates a pending lock has been obtained */
87 BOOL bReserved; /* Indicates a reserved lock has been obtained */
88 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
89} winceLock;
90#endif
91
92/*
drh153c62c2007-08-24 03:51:33 +000093** The winFile structure is a subclass of sqlite3_file* specific to the win32
drh054889e2005-11-30 03:20:31 +000094** portability layer.
drh9cbe6352005-11-29 03:13:21 +000095*/
drh054889e2005-11-30 03:20:31 +000096typedef struct winFile winFile;
97struct winFile {
drh153c62c2007-08-24 03:51:33 +000098 const sqlite3_io_methods *pMethod;/* Must be first */
drh9cbe6352005-11-29 03:13:21 +000099 HANDLE h; /* Handle for accessing the file */
100 unsigned char locktype; /* Type of lock currently held on this file */
101 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
shane9db299f2009-01-30 05:59:10 +0000102 DWORD lastErrno; /* The Windows errno from the last I/O error */
shane50daafc2009-03-05 05:54:55 +0000103 DWORD sectorSize; /* Sector size of the device file is on */
danielk197729bafea2008-06-26 10:41:19 +0000104#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +0000105 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
106 HANDLE hMutex; /* Mutex used to control access to shared lock */
107 HANDLE hShared; /* Shared memory segment used for locking */
108 winceLock local; /* Locks obtained by this instance of winFile */
109 winceLock *shared; /* Global shared lock memory for the file */
drhcc78fea2006-01-06 16:17:05 +0000110#endif
drh9cbe6352005-11-29 03:13:21 +0000111};
112
shane50daafc2009-03-05 05:54:55 +0000113/*
114** Forward prototypes.
115*/
116static int getSectorSize(
117 sqlite3_vfs *pVfs,
118 const char *zRelative /* UTF-8 file name */
119);
drh9cbe6352005-11-29 03:13:21 +0000120
drh9cbe6352005-11-29 03:13:21 +0000121/*
drhc0929982005-09-05 19:08:29 +0000122** The following variable is (normally) set once and never changes
123** thereafter. It records whether the operating system is Win95
124** or WinNT.
125**
126** 0: Operating system unknown.
127** 1: Operating system is Win95.
128** 2: Operating system is WinNT.
129**
130** In order to facilitate testing on a WinNT system, the test fixture
131** can manually set this value to 1 to emulate Win98 behavior.
132*/
drh153c62c2007-08-24 03:51:33 +0000133#ifdef SQLITE_TEST
drhc0929982005-09-05 19:08:29 +0000134int sqlite3_os_type = 0;
drh153c62c2007-08-24 03:51:33 +0000135#else
136static int sqlite3_os_type = 0;
137#endif
drhc0929982005-09-05 19:08:29 +0000138
139/*
drhcc78fea2006-01-06 16:17:05 +0000140** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
141** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +0000142**
143** Here is an interesting observation: Win95, Win98, and WinME lack
144** the LockFileEx() API. But we can still statically link against that
shane50daafc2009-03-05 05:54:55 +0000145** API as long as we don't call it when running Win95/98/ME. A call to
drhc0929982005-09-05 19:08:29 +0000146** this routine is used to determine if the host is Win95/98/ME or
147** WinNT/2K/XP so that we will know whether or not we can safely call
148** the LockFileEx() API.
149*/
danielk197729bafea2008-06-26 10:41:19 +0000150#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +0000151# define isNT() (1)
152#else
153 static int isNT(void){
154 if( sqlite3_os_type==0 ){
155 OSVERSIONINFO sInfo;
156 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
157 GetVersionEx(&sInfo);
158 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
159 }
160 return sqlite3_os_type==2;
drhc0929982005-09-05 19:08:29 +0000161 }
danielk197729bafea2008-06-26 10:41:19 +0000162#endif /* SQLITE_OS_WINCE */
drhcc78fea2006-01-06 16:17:05 +0000163
drhc0929982005-09-05 19:08:29 +0000164/*
drh584c0942006-12-21 03:20:40 +0000165** Convert a UTF-8 string to microsoft unicode (UTF-16?).
166**
drhb11caac2007-08-24 17:52:21 +0000167** Space to hold the returned string is obtained from malloc.
drhc0929982005-09-05 19:08:29 +0000168*/
169static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000170 int nChar;
drhc0929982005-09-05 19:08:29 +0000171 WCHAR *zWideFilename;
172
drhe3dd8bb2006-02-27 23:44:35 +0000173 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
drhb11caac2007-08-24 17:52:21 +0000174 zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000175 if( zWideFilename==0 ){
176 return 0;
177 }
drhe3dd8bb2006-02-27 23:44:35 +0000178 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
179 if( nChar==0 ){
drhb11caac2007-08-24 17:52:21 +0000180 free(zWideFilename);
drhc0929982005-09-05 19:08:29 +0000181 zWideFilename = 0;
182 }
183 return zWideFilename;
184}
185
186/*
drh584c0942006-12-21 03:20:40 +0000187** Convert microsoft unicode to UTF-8. Space to hold the returned string is
drhb11caac2007-08-24 17:52:21 +0000188** obtained from malloc().
drhc0929982005-09-05 19:08:29 +0000189*/
190static char *unicodeToUtf8(const WCHAR *zWideFilename){
191 int nByte;
192 char *zFilename;
193
194 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000195 zFilename = malloc( nByte );
drhc0929982005-09-05 19:08:29 +0000196 if( zFilename==0 ){
197 return 0;
198 }
199 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
200 0, 0);
201 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000202 free(zFilename);
drhc0929982005-09-05 19:08:29 +0000203 zFilename = 0;
204 }
205 return zFilename;
206}
207
drh371de5a2006-10-30 13:37:22 +0000208/*
drh584c0942006-12-21 03:20:40 +0000209** Convert an ansi string to microsoft unicode, based on the
210** current codepage settings for file apis.
211**
212** Space to hold the returned string is obtained
drhb11caac2007-08-24 17:52:21 +0000213** from malloc.
drh371de5a2006-10-30 13:37:22 +0000214*/
215static WCHAR *mbcsToUnicode(const char *zFilename){
216 int nByte;
217 WCHAR *zMbcsFilename;
drh584c0942006-12-21 03:20:40 +0000218 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000219
drh584c0942006-12-21 03:20:40 +0000220 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
drhb11caac2007-08-24 17:52:21 +0000221 zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
drh371de5a2006-10-30 13:37:22 +0000222 if( zMbcsFilename==0 ){
223 return 0;
224 }
drh584c0942006-12-21 03:20:40 +0000225 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
drh371de5a2006-10-30 13:37:22 +0000226 if( nByte==0 ){
drhb11caac2007-08-24 17:52:21 +0000227 free(zMbcsFilename);
drh371de5a2006-10-30 13:37:22 +0000228 zMbcsFilename = 0;
229 }
230 return zMbcsFilename;
231}
232
233/*
drh584c0942006-12-21 03:20:40 +0000234** Convert microsoft unicode to multibyte character string, based on the
235** user's Ansi codepage.
236**
237** Space to hold the returned string is obtained from
drhb11caac2007-08-24 17:52:21 +0000238** malloc().
drh371de5a2006-10-30 13:37:22 +0000239*/
240static char *unicodeToMbcs(const WCHAR *zWideFilename){
241 int nByte;
242 char *zFilename;
drh584c0942006-12-21 03:20:40 +0000243 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000244
drh584c0942006-12-21 03:20:40 +0000245 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000246 zFilename = malloc( nByte );
drh371de5a2006-10-30 13:37:22 +0000247 if( zFilename==0 ){
248 return 0;
249 }
drh584c0942006-12-21 03:20:40 +0000250 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
drh371de5a2006-10-30 13:37:22 +0000251 0, 0);
252 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000253 free(zFilename);
drh371de5a2006-10-30 13:37:22 +0000254 zFilename = 0;
255 }
256 return zFilename;
257}
258
259/*
260** Convert multibyte character string to UTF-8. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000261** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000262*/
drh1d298852008-11-18 19:18:52 +0000263char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
drh371de5a2006-10-30 13:37:22 +0000264 char *zFilenameUtf8;
265 WCHAR *zTmpWide;
266
267 zTmpWide = mbcsToUnicode(zFilename);
268 if( zTmpWide==0 ){
269 return 0;
270 }
271 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000272 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000273 return zFilenameUtf8;
274}
275
276/*
277** Convert UTF-8 to multibyte character string. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000278** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000279*/
280static char *utf8ToMbcs(const char *zFilename){
281 char *zFilenameMbcs;
282 WCHAR *zTmpWide;
283
284 zTmpWide = utf8ToUnicode(zFilename);
285 if( zTmpWide==0 ){
286 return 0;
287 }
288 zFilenameMbcs = unicodeToMbcs(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000289 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000290 return zFilenameMbcs;
291}
292
danielk197729bafea2008-06-26 10:41:19 +0000293#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +0000294/*************************************************************************
295** This section contains code for WinCE only.
296*/
297/*
298** WindowsCE does not have a localtime() function. So create a
299** substitute.
300*/
301#include <time.h>
302struct tm *__cdecl localtime(const time_t *t)
303{
304 static struct tm y;
305 FILETIME uTm, lTm;
306 SYSTEMTIME pTm;
drhc51250a2007-09-20 14:39:23 +0000307 sqlite3_int64 t64;
drh72aead82006-01-23 15:54:25 +0000308 t64 = *t;
309 t64 = (t64 + 11644473600)*10000000;
shane11bb41f2009-09-10 20:23:30 +0000310 uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
311 uTm.dwHighDateTime= (DWORD)(t64 >> 32);
drh72aead82006-01-23 15:54:25 +0000312 FileTimeToLocalFileTime(&uTm,&lTm);
313 FileTimeToSystemTime(&lTm,&pTm);
314 y.tm_year = pTm.wYear - 1900;
315 y.tm_mon = pTm.wMonth - 1;
316 y.tm_wday = pTm.wDayOfWeek;
317 y.tm_mday = pTm.wDay;
318 y.tm_hour = pTm.wHour;
319 y.tm_min = pTm.wMinute;
320 y.tm_sec = pTm.wSecond;
321 return &y;
322}
323
324/* This will never be called, but defined to make the code compile */
325#define GetTempPathA(a,b)
326
327#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
328#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
329#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
330
shane11bb41f2009-09-10 20:23:30 +0000331#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
drh72aead82006-01-23 15:54:25 +0000332
333/*
334** Acquire a lock on the handle h
335*/
336static void winceMutexAcquire(HANDLE h){
337 DWORD dwErr;
338 do {
339 dwErr = WaitForSingleObject(h, INFINITE);
340 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
341}
342/*
343** Release a lock acquired by winceMutexAcquire()
344*/
345#define winceMutexRelease(h) ReleaseMutex(h)
346
347/*
348** Create the mutex and shared memory used for locking in the file
349** descriptor pFile
350*/
351static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
352 WCHAR *zTok;
353 WCHAR *zName = utf8ToUnicode(zFilename);
354 BOOL bInit = TRUE;
355
356 /* Initialize the local lockdata */
357 ZeroMemory(&pFile->local, sizeof(pFile->local));
358
359 /* Replace the backslashes from the filename and lowercase it
360 ** to derive a mutex name. */
361 zTok = CharLowerW(zName);
362 for (;*zTok;zTok++){
363 if (*zTok == '\\') *zTok = '_';
364 }
365
366 /* Create/open the named mutex */
367 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
368 if (!pFile->hMutex){
shane9db299f2009-01-30 05:59:10 +0000369 pFile->lastErrno = GetLastError();
drhb11caac2007-08-24 17:52:21 +0000370 free(zName);
drh72aead82006-01-23 15:54:25 +0000371 return FALSE;
372 }
373
374 /* Acquire the mutex before continuing */
375 winceMutexAcquire(pFile->hMutex);
376
377 /* Since the names of named mutexes, semaphores, file mappings etc are
378 ** case-sensitive, take advantage of that by uppercasing the mutex name
379 ** and using that as the shared filemapping name.
380 */
381 CharUpperW(zName);
382 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
383 PAGE_READWRITE, 0, sizeof(winceLock),
384 zName);
385
386 /* Set a flag that indicates we're the first to create the memory so it
387 ** must be zero-initialized */
388 if (GetLastError() == ERROR_ALREADY_EXISTS){
389 bInit = FALSE;
390 }
391
drhb11caac2007-08-24 17:52:21 +0000392 free(zName);
drh72aead82006-01-23 15:54:25 +0000393
394 /* If we succeeded in making the shared memory handle, map it. */
395 if (pFile->hShared){
396 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
397 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
398 /* If mapping failed, close the shared memory handle and erase it */
399 if (!pFile->shared){
shane9db299f2009-01-30 05:59:10 +0000400 pFile->lastErrno = GetLastError();
drh72aead82006-01-23 15:54:25 +0000401 CloseHandle(pFile->hShared);
402 pFile->hShared = NULL;
403 }
404 }
405
406 /* If shared memory could not be created, then close the mutex and fail */
407 if (pFile->hShared == NULL){
408 winceMutexRelease(pFile->hMutex);
409 CloseHandle(pFile->hMutex);
410 pFile->hMutex = NULL;
411 return FALSE;
412 }
413
414 /* Initialize the shared memory if we're supposed to */
415 if (bInit) {
416 ZeroMemory(pFile->shared, sizeof(winceLock));
417 }
418
419 winceMutexRelease(pFile->hMutex);
420 return TRUE;
421}
422
423/*
424** Destroy the part of winFile that deals with wince locks
425*/
426static void winceDestroyLock(winFile *pFile){
427 if (pFile->hMutex){
428 /* Acquire the mutex */
429 winceMutexAcquire(pFile->hMutex);
430
431 /* The following blocks should probably assert in debug mode, but they
432 are to cleanup in case any locks remained open */
433 if (pFile->local.nReaders){
434 pFile->shared->nReaders --;
435 }
436 if (pFile->local.bReserved){
437 pFile->shared->bReserved = FALSE;
438 }
439 if (pFile->local.bPending){
440 pFile->shared->bPending = FALSE;
441 }
442 if (pFile->local.bExclusive){
443 pFile->shared->bExclusive = FALSE;
444 }
445
446 /* De-reference and close our copy of the shared memory handle */
447 UnmapViewOfFile(pFile->shared);
448 CloseHandle(pFile->hShared);
449
450 /* Done with the mutex */
451 winceMutexRelease(pFile->hMutex);
452 CloseHandle(pFile->hMutex);
453 pFile->hMutex = NULL;
454 }
455}
456
457/*
458** An implementation of the LockFile() API of windows for wince
459*/
460static BOOL winceLockFile(
461 HANDLE *phFile,
462 DWORD dwFileOffsetLow,
463 DWORD dwFileOffsetHigh,
464 DWORD nNumberOfBytesToLockLow,
465 DWORD nNumberOfBytesToLockHigh
466){
467 winFile *pFile = HANDLE_TO_WINFILE(phFile);
468 BOOL bReturn = FALSE;
469
shane11bb41f2009-09-10 20:23:30 +0000470 UNUSED_PARAMETER(dwFileOffsetHigh);
471 UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
472
drh72aead82006-01-23 15:54:25 +0000473 if (!pFile->hMutex) return TRUE;
474 winceMutexAcquire(pFile->hMutex);
475
476 /* Wanting an exclusive lock? */
shane11bb41f2009-09-10 20:23:30 +0000477 if (dwFileOffsetLow == (DWORD)SHARED_FIRST
478 && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
drh72aead82006-01-23 15:54:25 +0000479 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
480 pFile->shared->bExclusive = TRUE;
481 pFile->local.bExclusive = TRUE;
482 bReturn = TRUE;
483 }
484 }
485
486 /* Want a read-only lock? */
shane11bb41f2009-09-10 20:23:30 +0000487 else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
shane338ea3c2009-08-05 04:08:29 +0000488 nNumberOfBytesToLockLow == 1){
drh72aead82006-01-23 15:54:25 +0000489 if (pFile->shared->bExclusive == 0){
490 pFile->local.nReaders ++;
491 if (pFile->local.nReaders == 1){
492 pFile->shared->nReaders ++;
493 }
494 bReturn = TRUE;
495 }
496 }
497
498 /* Want a pending lock? */
shane11bb41f2009-09-10 20:23:30 +0000499 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
drh72aead82006-01-23 15:54:25 +0000500 /* If no pending lock has been acquired, then acquire it */
501 if (pFile->shared->bPending == 0) {
502 pFile->shared->bPending = TRUE;
503 pFile->local.bPending = TRUE;
504 bReturn = TRUE;
505 }
506 }
shane338ea3c2009-08-05 04:08:29 +0000507
drh72aead82006-01-23 15:54:25 +0000508 /* Want a reserved lock? */
shane11bb41f2009-09-10 20:23:30 +0000509 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
drh72aead82006-01-23 15:54:25 +0000510 if (pFile->shared->bReserved == 0) {
511 pFile->shared->bReserved = TRUE;
512 pFile->local.bReserved = TRUE;
513 bReturn = TRUE;
514 }
515 }
516
517 winceMutexRelease(pFile->hMutex);
518 return bReturn;
519}
520
521/*
522** An implementation of the UnlockFile API of windows for wince
523*/
524static BOOL winceUnlockFile(
525 HANDLE *phFile,
526 DWORD dwFileOffsetLow,
527 DWORD dwFileOffsetHigh,
528 DWORD nNumberOfBytesToUnlockLow,
529 DWORD nNumberOfBytesToUnlockHigh
530){
531 winFile *pFile = HANDLE_TO_WINFILE(phFile);
532 BOOL bReturn = FALSE;
533
shane11bb41f2009-09-10 20:23:30 +0000534 UNUSED_PARAMETER(dwFileOffsetHigh);
535 UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
536
drh72aead82006-01-23 15:54:25 +0000537 if (!pFile->hMutex) return TRUE;
538 winceMutexAcquire(pFile->hMutex);
539
540 /* Releasing a reader lock or an exclusive lock */
shane11bb41f2009-09-10 20:23:30 +0000541 if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
drh72aead82006-01-23 15:54:25 +0000542 /* Did we have an exclusive lock? */
543 if (pFile->local.bExclusive){
shane11bb41f2009-09-10 20:23:30 +0000544 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
drh72aead82006-01-23 15:54:25 +0000545 pFile->local.bExclusive = FALSE;
546 pFile->shared->bExclusive = FALSE;
547 bReturn = TRUE;
548 }
549
550 /* Did we just have a reader lock? */
551 else if (pFile->local.nReaders){
shane11bb41f2009-09-10 20:23:30 +0000552 assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
drh72aead82006-01-23 15:54:25 +0000553 pFile->local.nReaders --;
554 if (pFile->local.nReaders == 0)
555 {
556 pFile->shared->nReaders --;
557 }
558 bReturn = TRUE;
559 }
560 }
561
562 /* Releasing a pending lock */
shane11bb41f2009-09-10 20:23:30 +0000563 else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
drh72aead82006-01-23 15:54:25 +0000564 if (pFile->local.bPending){
565 pFile->local.bPending = FALSE;
566 pFile->shared->bPending = FALSE;
567 bReturn = TRUE;
568 }
569 }
570 /* Releasing a reserved lock */
shane11bb41f2009-09-10 20:23:30 +0000571 else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
drh72aead82006-01-23 15:54:25 +0000572 if (pFile->local.bReserved) {
573 pFile->local.bReserved = FALSE;
574 pFile->shared->bReserved = FALSE;
575 bReturn = TRUE;
576 }
577 }
578
579 winceMutexRelease(pFile->hMutex);
580 return bReturn;
581}
582
583/*
584** An implementation of the LockFileEx() API of windows for wince
585*/
586static BOOL winceLockFileEx(
587 HANDLE *phFile,
588 DWORD dwFlags,
589 DWORD dwReserved,
590 DWORD nNumberOfBytesToLockLow,
591 DWORD nNumberOfBytesToLockHigh,
592 LPOVERLAPPED lpOverlapped
593){
shane11bb41f2009-09-10 20:23:30 +0000594 UNUSED_PARAMETER(dwReserved);
595 UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
596
drh72aead82006-01-23 15:54:25 +0000597 /* If the caller wants a shared read lock, forward this call
598 ** to winceLockFile */
shane11bb41f2009-09-10 20:23:30 +0000599 if (lpOverlapped->Offset == (DWORD)SHARED_FIRST &&
drh72aead82006-01-23 15:54:25 +0000600 dwFlags == 1 &&
shane11bb41f2009-09-10 20:23:30 +0000601 nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
drh72aead82006-01-23 15:54:25 +0000602 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
603 }
604 return FALSE;
605}
606/*
607** End of the special code for wince
608*****************************************************************************/
danielk197729bafea2008-06-26 10:41:19 +0000609#endif /* SQLITE_OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000610
drh153c62c2007-08-24 03:51:33 +0000611/*****************************************************************************
612** The next group of routines implement the I/O methods specified
613** by the sqlite3_io_methods object.
614******************************************************************************/
drhbbd42a62004-05-22 17:41:58 +0000615
616/*
617** Close a file.
drh59e63a62006-06-04 23:31:48 +0000618**
619** It is reported that an attempt to close a handle might sometimes
620** fail. This is a very unreasonable result, but windows is notorious
621** for being unreasonable so I do not doubt that it might happen. If
622** the close fails, we pause for 100 milliseconds and try again. As
623** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
624** giving up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000625*/
drh59e63a62006-06-04 23:31:48 +0000626#define MX_CLOSE_ATTEMPT 3
drh153c62c2007-08-24 03:51:33 +0000627static int winClose(sqlite3_file *id){
628 int rc, cnt = 0;
629 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +0000630
631 assert( id!=0 );
drh153c62c2007-08-24 03:51:33 +0000632 OSTRACE2("CLOSE %d\n", pFile->h);
633 do{
634 rc = CloseHandle(pFile->h);
shaned94b0552008-09-30 04:20:07 +0000635 }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
danielk197729bafea2008-06-26 10:41:19 +0000636#if SQLITE_OS_WINCE
drhd641d512008-02-20 00:00:00 +0000637#define WINCE_DELETION_ATTEMPTS 3
drh153c62c2007-08-24 03:51:33 +0000638 winceDestroyLock(pFile);
drh7229ed42007-10-08 12:29:17 +0000639 if( pFile->zDeleteOnClose ){
drhd641d512008-02-20 00:00:00 +0000640 int cnt = 0;
641 while(
642 DeleteFileW(pFile->zDeleteOnClose)==0
643 && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
644 && cnt++ < WINCE_DELETION_ATTEMPTS
645 ){
646 Sleep(100); /* Wait a little before trying again */
647 }
drh7229ed42007-10-08 12:29:17 +0000648 free(pFile->zDeleteOnClose);
649 }
drhcc78fea2006-01-06 16:17:05 +0000650#endif
drh153c62c2007-08-24 03:51:33 +0000651 OpenCounter(-1);
drheb4fa522006-06-04 23:02:20 +0000652 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000653}
654
655/*
drh153c62c2007-08-24 03:51:33 +0000656** Some microsoft compilers lack this definition.
657*/
658#ifndef INVALID_SET_FILE_POINTER
659# define INVALID_SET_FILE_POINTER ((DWORD)-1)
660#endif
661
662/*
drhbbd42a62004-05-22 17:41:58 +0000663** Read data from a file into a buffer. Return SQLITE_OK if all
664** bytes were read successfully and SQLITE_IOERR if anything goes
665** wrong.
666*/
drh153c62c2007-08-24 03:51:33 +0000667static int winRead(
668 sqlite3_file *id, /* File to read from */
669 void *pBuf, /* Write content into this buffer */
670 int amt, /* Number of bytes to read */
671 sqlite3_int64 offset /* Begin reading at this offset */
672){
drh1bd10f82008-12-10 21:19:56 +0000673 LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
674 LONG lowerBits = (LONG)(offset & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000675 DWORD rc;
drh153c62c2007-08-24 03:51:33 +0000676 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000677 DWORD error;
shane50daafc2009-03-05 05:54:55 +0000678 DWORD got;
679
drh9cbe6352005-11-29 03:13:21 +0000680 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +0000681 SimulateIOError(return SQLITE_IOERR_READ);
drh153c62c2007-08-24 03:51:33 +0000682 OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
683 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
shane9db299f2009-01-30 05:59:10 +0000684 if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
685 pFile->lastErrno = error;
drh153c62c2007-08-24 03:51:33 +0000686 return SQLITE_FULL;
687 }
688 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
shane9db299f2009-01-30 05:59:10 +0000689 pFile->lastErrno = GetLastError();
drhaedd8922007-01-05 14:38:54 +0000690 return SQLITE_IOERR_READ;
drhbbd42a62004-05-22 17:41:58 +0000691 }
692 if( got==(DWORD)amt ){
693 return SQLITE_OK;
694 }else{
drh4c17c3f2008-11-07 00:06:18 +0000695 /* Unread parts of the buffer must be zero-filled */
drhbafda092007-01-03 23:36:22 +0000696 memset(&((char*)pBuf)[got], 0, amt-got);
drh551b7732006-11-06 21:20:25 +0000697 return SQLITE_IOERR_SHORT_READ;
drhbbd42a62004-05-22 17:41:58 +0000698 }
699}
700
701/*
702** Write data from a buffer into a file. Return SQLITE_OK on success
703** or some other error code on failure.
704*/
drh153c62c2007-08-24 03:51:33 +0000705static int winWrite(
706 sqlite3_file *id, /* File to write into */
707 const void *pBuf, /* The bytes to be written */
708 int amt, /* Number of bytes to write */
709 sqlite3_int64 offset /* Offset into the file to begin writing at */
710){
drh1bd10f82008-12-10 21:19:56 +0000711 LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
712 LONG lowerBits = (LONG)(offset & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000713 DWORD rc;
drh153c62c2007-08-24 03:51:33 +0000714 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000715 DWORD error;
shane50daafc2009-03-05 05:54:55 +0000716 DWORD wrote = 0;
717
drh9cbe6352005-11-29 03:13:21 +0000718 assert( id!=0 );
drh153c62c2007-08-24 03:51:33 +0000719 SimulateIOError(return SQLITE_IOERR_WRITE);
drh59685932006-09-14 13:47:11 +0000720 SimulateDiskfullError(return SQLITE_FULL);
drh153c62c2007-08-24 03:51:33 +0000721 OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
722 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
shane9db299f2009-01-30 05:59:10 +0000723 if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
724 pFile->lastErrno = error;
drh153c62c2007-08-24 03:51:33 +0000725 return SQLITE_FULL;
726 }
drh4c7f9412005-02-03 00:29:47 +0000727 assert( amt>0 );
drh153c62c2007-08-24 03:51:33 +0000728 while(
729 amt>0
730 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
731 && wrote>0
732 ){
drhbbd42a62004-05-22 17:41:58 +0000733 amt -= wrote;
734 pBuf = &((char*)pBuf)[wrote];
735 }
736 if( !rc || amt>(int)wrote ){
shane9db299f2009-01-30 05:59:10 +0000737 pFile->lastErrno = GetLastError();
drhbbd42a62004-05-22 17:41:58 +0000738 return SQLITE_FULL;
739 }
740 return SQLITE_OK;
741}
742
743/*
drh153c62c2007-08-24 03:51:33 +0000744** Truncate an open file to a specified size
drhbbdc2b92005-09-19 12:53:18 +0000745*/
drhc51250a2007-09-20 14:39:23 +0000746static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
drh1bd10f82008-12-10 21:19:56 +0000747 LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
748 LONG lowerBits = (LONG)(nByte & 0xffffffff);
shane50daafc2009-03-05 05:54:55 +0000749 DWORD rc;
drh153c62c2007-08-24 03:51:33 +0000750 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +0000751 DWORD error;
752
753 assert( id!=0 );
drh153c62c2007-08-24 03:51:33 +0000754 OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
755 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
shanea3465f22008-10-12 02:27:38 +0000756 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
shane50daafc2009-03-05 05:54:55 +0000757 if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
758 pFile->lastErrno = error;
759 return SQLITE_IOERR_TRUNCATE;
shanef5d335f2009-02-05 03:16:20 +0000760 }
shane50daafc2009-03-05 05:54:55 +0000761 /* SetEndOfFile will fail if nByte is negative */
762 if( !SetEndOfFile(pFile->h) ){
763 pFile->lastErrno = GetLastError();
764 return SQLITE_IOERR_TRUNCATE;
shanea3465f22008-10-12 02:27:38 +0000765 }
shane50daafc2009-03-05 05:54:55 +0000766 return SQLITE_OK;
drhbbd42a62004-05-22 17:41:58 +0000767}
768
drhdec6fae2007-09-03 17:02:50 +0000769#ifdef SQLITE_TEST
770/*
771** Count the number of fullsyncs and normal syncs. This is used to test
772** that syncs and fullsyncs are occuring at the right times.
773*/
774int sqlite3_sync_count = 0;
775int sqlite3_fullsync_count = 0;
776#endif
777
drhbbd42a62004-05-22 17:41:58 +0000778/*
779** Make sure all writes to a particular file are committed to disk.
780*/
drh153c62c2007-08-24 03:51:33 +0000781static int winSync(sqlite3_file *id, int flags){
shane18e526c2008-12-10 22:30:24 +0000782#ifndef SQLITE_NO_SYNC
drh153c62c2007-08-24 03:51:33 +0000783 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +0000784
785 assert( id!=0 );
shanefbd60f82009-02-04 03:59:25 +0000786 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
shane18e526c2008-12-10 22:30:24 +0000787#else
788 UNUSED_PARAMETER(id);
789#endif
shane7d3846a2008-12-11 02:58:26 +0000790#ifndef SQLITE_TEST
791 UNUSED_PARAMETER(flags);
792#else
drhdec6fae2007-09-03 17:02:50 +0000793 if( flags & SQLITE_SYNC_FULL ){
794 sqlite3_fullsync_count++;
795 }
796 sqlite3_sync_count++;
797#endif
shane84ca3832008-11-13 18:20:43 +0000798 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
799 ** no-op
800 */
801#ifdef SQLITE_NO_SYNC
802 return SQLITE_OK;
803#else
drh153c62c2007-08-24 03:51:33 +0000804 if( FlushFileBuffers(pFile->h) ){
drhbbd42a62004-05-22 17:41:58 +0000805 return SQLITE_OK;
806 }else{
shane9db299f2009-01-30 05:59:10 +0000807 pFile->lastErrno = GetLastError();
drhbbd42a62004-05-22 17:41:58 +0000808 return SQLITE_IOERR;
809 }
shane84ca3832008-11-13 18:20:43 +0000810#endif
drhbbd42a62004-05-22 17:41:58 +0000811}
812
813/*
drhbbd42a62004-05-22 17:41:58 +0000814** Determine the current size of a file in bytes
815*/
drh153c62c2007-08-24 03:51:33 +0000816static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
shane50daafc2009-03-05 05:54:55 +0000817 DWORD upperBits;
818 DWORD lowerBits;
drh153c62c2007-08-24 03:51:33 +0000819 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000820 DWORD error;
shane50daafc2009-03-05 05:54:55 +0000821
822 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +0000823 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh153c62c2007-08-24 03:51:33 +0000824 lowerBits = GetFileSize(pFile->h, &upperBits);
shane9db299f2009-01-30 05:59:10 +0000825 if( (lowerBits == INVALID_FILE_SIZE)
826 && ((error = GetLastError()) != NO_ERROR) )
827 {
828 pFile->lastErrno = error;
829 return SQLITE_IOERR_FSTAT;
830 }
drh153c62c2007-08-24 03:51:33 +0000831 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000832 return SQLITE_OK;
833}
834
835/*
drh602bbd32006-01-06 20:22:29 +0000836** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
837*/
838#ifndef LOCKFILE_FAIL_IMMEDIATELY
839# define LOCKFILE_FAIL_IMMEDIATELY 1
840#endif
841
842/*
drh9c105bb2004-10-02 20:38:28 +0000843** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000844** Different API routines are called depending on whether or not this
845** is Win95 or WinNT.
846*/
drh153c62c2007-08-24 03:51:33 +0000847static int getReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000848 int res;
849 if( isNT() ){
850 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000851 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000852 ovlp.OffsetHigh = 0;
853 ovlp.hEvent = 0;
drh153c62c2007-08-24 03:51:33 +0000854 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
855 0, SHARED_SIZE, 0, &ovlp);
shane891adea2008-10-22 16:55:47 +0000856/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
857*/
858#if SQLITE_OS_WINCE==0
drhbbd42a62004-05-22 17:41:58 +0000859 }else{
drh9c105bb2004-10-02 20:38:28 +0000860 int lk;
drh2fa18682008-03-19 14:15:34 +0000861 sqlite3_randomness(sizeof(lk), &lk);
drh1bd10f82008-12-10 21:19:56 +0000862 pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
drh153c62c2007-08-24 03:51:33 +0000863 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000864#endif
drh51c6d962004-06-06 00:42:25 +0000865 }
shane9db299f2009-01-30 05:59:10 +0000866 if( res == 0 ){
867 pFile->lastErrno = GetLastError();
868 }
drh51c6d962004-06-06 00:42:25 +0000869 return res;
870}
871
872/*
873** Undo a readlock
874*/
drh054889e2005-11-30 03:20:31 +0000875static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000876 int res;
877 if( isNT() ){
drh054889e2005-11-30 03:20:31 +0000878 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
shane891adea2008-10-22 16:55:47 +0000879/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
880*/
881#if SQLITE_OS_WINCE==0
drh51c6d962004-06-06 00:42:25 +0000882 }else{
drh054889e2005-11-30 03:20:31 +0000883 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000884#endif
drh51c6d962004-06-06 00:42:25 +0000885 }
shane9db299f2009-01-30 05:59:10 +0000886 if( res == 0 ){
887 pFile->lastErrno = GetLastError();
888 }
drh51c6d962004-06-06 00:42:25 +0000889 return res;
890}
891
tpoindex9a09a3c2004-12-20 19:01:32 +0000892/*
drhb3e04342004-06-08 00:47:47 +0000893** Lock the file with the lock specified by parameter locktype - one
894** of the following:
895**
896** (1) SHARED_LOCK
897** (2) RESERVED_LOCK
898** (3) PENDING_LOCK
899** (4) EXCLUSIVE_LOCK
900**
901** Sometimes when requesting one lock state, additional lock states
902** are inserted in between. The locking might fail on one of the later
903** transitions leaving the lock state different from what it started but
904** still short of its goal. The following chart shows the allowed
905** transitions and the inserted intermediate states:
906**
907** UNLOCKED -> SHARED
908** SHARED -> RESERVED
909** SHARED -> (PENDING) -> EXCLUSIVE
910** RESERVED -> (PENDING) -> EXCLUSIVE
911** PENDING -> EXCLUSIVE
912**
drh9c06c952005-11-26 00:25:00 +0000913** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +0000914** erases all locks at once and returns us immediately to locking level 0.
915** It is not possible to lower the locking level one step at a time. You
916** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000917*/
drh153c62c2007-08-24 03:51:33 +0000918static int winLock(sqlite3_file *id, int locktype){
drh51c6d962004-06-06 00:42:25 +0000919 int rc = SQLITE_OK; /* Return code from subroutines */
920 int res = 1; /* Result of a windows lock call */
drh153c62c2007-08-24 03:51:33 +0000921 int newLocktype; /* Set pFile->locktype to this value before exiting */
drhe54ca3f2004-06-07 01:52:14 +0000922 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +0000923 winFile *pFile = (winFile*)id;
shane9db299f2009-01-30 05:59:10 +0000924 DWORD error = NO_ERROR;
drh51c6d962004-06-06 00:42:25 +0000925
shane50daafc2009-03-05 05:54:55 +0000926 assert( id!=0 );
drh4f0c5872007-03-26 22:05:01 +0000927 OSTRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +0000928 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000929
930 /* If there is already a lock of this type or more restrictive on the
931 ** OsFile, do nothing. Don't use the end_lock: exit path, as
932 ** sqlite3OsEnterMutex() hasn't been called yet.
933 */
drh054889e2005-11-30 03:20:31 +0000934 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +0000935 return SQLITE_OK;
936 }
937
drhb3e04342004-06-08 00:47:47 +0000938 /* Make sure the locking sequence is correct
939 */
drh054889e2005-11-30 03:20:31 +0000940 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000941 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +0000942 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000943
drh51c6d962004-06-06 00:42:25 +0000944 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
945 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
946 ** the PENDING_LOCK byte is temporary.
947 */
drh054889e2005-11-30 03:20:31 +0000948 newLocktype = pFile->locktype;
shane9db299f2009-01-30 05:59:10 +0000949 if( (pFile->locktype==NO_LOCK)
950 || ( (locktype==EXCLUSIVE_LOCK)
951 && (pFile->locktype==RESERVED_LOCK))
drhe54ca3f2004-06-07 01:52:14 +0000952 ){
drhb3e04342004-06-08 00:47:47 +0000953 int cnt = 3;
drh054889e2005-11-30 03:20:31 +0000954 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000955 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000956 ** held by another reader process who will release it momentarily.
957 */
drh4f0c5872007-03-26 22:05:01 +0000958 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000959 Sleep(1);
960 }
drhe54ca3f2004-06-07 01:52:14 +0000961 gotPendingLock = res;
shane9db299f2009-01-30 05:59:10 +0000962 if( !res ){
963 error = GetLastError();
964 }
drh51c6d962004-06-06 00:42:25 +0000965 }
966
967 /* Acquire a shared lock
968 */
drhb3e04342004-06-08 00:47:47 +0000969 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000970 assert( pFile->locktype==NO_LOCK );
971 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000972 if( res ){
973 newLocktype = SHARED_LOCK;
shane9db299f2009-01-30 05:59:10 +0000974 }else{
975 error = GetLastError();
drh51c6d962004-06-06 00:42:25 +0000976 }
977 }
978
979 /* Acquire a RESERVED lock
980 */
drhb3e04342004-06-08 00:47:47 +0000981 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000982 assert( pFile->locktype==SHARED_LOCK );
983 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +0000984 if( res ){
985 newLocktype = RESERVED_LOCK;
shane9db299f2009-01-30 05:59:10 +0000986 }else{
987 error = GetLastError();
drhe54ca3f2004-06-07 01:52:14 +0000988 }
989 }
990
991 /* Acquire a PENDING lock
992 */
drhb3e04342004-06-08 00:47:47 +0000993 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000994 newLocktype = PENDING_LOCK;
995 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000996 }
997
998 /* Acquire an EXCLUSIVE lock
999 */
drhe54ca3f2004-06-07 01:52:14 +00001000 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001001 assert( pFile->locktype>=SHARED_LOCK );
1002 res = unlockReadLock(pFile);
drh4f0c5872007-03-26 22:05:01 +00001003 OSTRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +00001004 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +00001005 if( res ){
1006 newLocktype = EXCLUSIVE_LOCK;
1007 }else{
shane9db299f2009-01-30 05:59:10 +00001008 error = GetLastError();
1009 OSTRACE2("error-code = %d\n", error);
drh8fea1282007-05-14 12:12:11 +00001010 getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +00001011 }
1012 }
1013
1014 /* If we are holding a PENDING lock that ought to be released, then
1015 ** release it now.
1016 */
drhb3e04342004-06-08 00:47:47 +00001017 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001018 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001019 }
1020
1021 /* Update the state of the lock has held in the file descriptor then
1022 ** return the appropriate result code.
1023 */
1024 if( res ){
drh51c6d962004-06-06 00:42:25 +00001025 rc = SQLITE_OK;
1026 }else{
drh4f0c5872007-03-26 22:05:01 +00001027 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +00001028 locktype, newLocktype);
shane9db299f2009-01-30 05:59:10 +00001029 pFile->lastErrno = error;
drh51c6d962004-06-06 00:42:25 +00001030 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +00001031 }
drh1bd10f82008-12-10 21:19:56 +00001032 pFile->locktype = (u8)newLocktype;
drhbbd42a62004-05-22 17:41:58 +00001033 return rc;
1034}
1035
1036/*
drh51c6d962004-06-06 00:42:25 +00001037** This routine checks if there is a RESERVED lock held on the specified
1038** file by this or any other process. If such a lock is held, return
1039** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +00001040*/
danielk1977861f7452008-06-05 11:39:11 +00001041static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
drhbbd42a62004-05-22 17:41:58 +00001042 int rc;
drh054889e2005-11-30 03:20:31 +00001043 winFile *pFile = (winFile*)id;
shane50daafc2009-03-05 05:54:55 +00001044
1045 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +00001046 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +00001047 rc = 1;
drh4f0c5872007-03-26 22:05:01 +00001048 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001049 }else{
drh054889e2005-11-30 03:20:31 +00001050 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001051 if( rc ){
drh054889e2005-11-30 03:20:31 +00001052 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +00001053 }
drh2ac3ee92004-06-07 16:27:46 +00001054 rc = !rc;
drh4f0c5872007-03-26 22:05:01 +00001055 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001056 }
danielk1977861f7452008-06-05 11:39:11 +00001057 *pResOut = rc;
1058 return SQLITE_OK;
drhbbd42a62004-05-22 17:41:58 +00001059}
1060
1061/*
drha6abd042004-06-09 17:37:22 +00001062** Lower the locking level on file descriptor id to locktype. locktype
1063** must be either NO_LOCK or SHARED_LOCK.
1064**
1065** If the locking level of the file descriptor is already at or below
1066** the requested locking level, this routine is a no-op.
1067**
drh9c105bb2004-10-02 20:38:28 +00001068** It is not possible for this routine to fail if the second argument
1069** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1070** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +00001071*/
drh153c62c2007-08-24 03:51:33 +00001072static int winUnlock(sqlite3_file *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001073 int type;
drh054889e2005-11-30 03:20:31 +00001074 winFile *pFile = (winFile*)id;
drh153c62c2007-08-24 03:51:33 +00001075 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001076 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001077 assert( locktype<=SHARED_LOCK );
drh4f0c5872007-03-26 22:05:01 +00001078 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
drh054889e2005-11-30 03:20:31 +00001079 pFile->locktype, pFile->sharedLockByte);
1080 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001081 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001082 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1083 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001084 /* This should never happen. We should always be able to
1085 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +00001086 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +00001087 }
drhbbd42a62004-05-22 17:41:58 +00001088 }
drhe54ca3f2004-06-07 01:52:14 +00001089 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001090 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001091 }
drh9c105bb2004-10-02 20:38:28 +00001092 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001093 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001094 }
drhb3e04342004-06-08 00:47:47 +00001095 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001096 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001097 }
drh1bd10f82008-12-10 21:19:56 +00001098 pFile->locktype = (u8)locktype;
drh9c105bb2004-10-02 20:38:28 +00001099 return rc;
drhbbd42a62004-05-22 17:41:58 +00001100}
1101
1102/*
drh9e33c2c2007-08-31 18:34:59 +00001103** Control and query of the open file handle.
drh0ccebe72005-06-07 22:22:50 +00001104*/
drh9e33c2c2007-08-31 18:34:59 +00001105static int winFileControl(sqlite3_file *id, int op, void *pArg){
1106 switch( op ){
1107 case SQLITE_FCNTL_LOCKSTATE: {
1108 *(int*)pArg = ((winFile*)id)->locktype;
1109 return SQLITE_OK;
1110 }
shane9db299f2009-01-30 05:59:10 +00001111 case SQLITE_LAST_ERRNO: {
1112 *(int*)pArg = (int)((winFile*)id)->lastErrno;
1113 return SQLITE_OK;
1114 }
drh9e33c2c2007-08-31 18:34:59 +00001115 }
drh153c62c2007-08-24 03:51:33 +00001116 return SQLITE_ERROR;
drh9cbe6352005-11-29 03:13:21 +00001117}
1118
1119/*
danielk1977a3d4c882007-03-23 10:08:38 +00001120** Return the sector size in bytes of the underlying block device for
1121** the specified file. This is almost always 512 bytes, but may be
1122** larger for some devices.
1123**
1124** SQLite code assumes this function cannot fail. It also assumes that
1125** if two files are created in the same file-system directory (i.e.
drh85b623f2007-12-13 21:54:09 +00001126** a database and its journal file) that the sector size will be the
danielk1977a3d4c882007-03-23 10:08:38 +00001127** same for both.
1128*/
drh153c62c2007-08-24 03:51:33 +00001129static int winSectorSize(sqlite3_file *id){
shane50daafc2009-03-05 05:54:55 +00001130 assert( id!=0 );
1131 return (int)(((winFile*)id)->sectorSize);
danielk1977a3d4c882007-03-23 10:08:38 +00001132}
1133
1134/*
drh153c62c2007-08-24 03:51:33 +00001135** Return a vector of device characteristics.
drh9c06c952005-11-26 00:25:00 +00001136*/
drh153c62c2007-08-24 03:51:33 +00001137static int winDeviceCharacteristics(sqlite3_file *id){
shane18e526c2008-12-10 22:30:24 +00001138 UNUSED_PARAMETER(id);
drh153c62c2007-08-24 03:51:33 +00001139 return 0;
1140}
1141
1142/*
1143** This vector defines all the methods that can operate on an
1144** sqlite3_file for win32.
1145*/
1146static const sqlite3_io_methods winIoMethod = {
1147 1, /* iVersion */
drh9c06c952005-11-26 00:25:00 +00001148 winClose,
1149 winRead,
1150 winWrite,
drh9c06c952005-11-26 00:25:00 +00001151 winTruncate,
drh054889e2005-11-30 03:20:31 +00001152 winSync,
drh054889e2005-11-30 03:20:31 +00001153 winFileSize,
1154 winLock,
1155 winUnlock,
drh054889e2005-11-30 03:20:31 +00001156 winCheckReservedLock,
drhcc6bb3e2007-08-31 16:11:35 +00001157 winFileControl,
danielk1977a3d4c882007-03-23 10:08:38 +00001158 winSectorSize,
drh153c62c2007-08-24 03:51:33 +00001159 winDeviceCharacteristics
drh9c06c952005-11-26 00:25:00 +00001160};
1161
drh153c62c2007-08-24 03:51:33 +00001162/***************************************************************************
1163** Here ends the I/O methods that form the sqlite3_io_methods object.
1164**
1165** The next block of code implements the VFS methods.
1166****************************************************************************/
1167
drh054889e2005-11-30 03:20:31 +00001168/*
drh153c62c2007-08-24 03:51:33 +00001169** Convert a UTF-8 filename into whatever form the underlying
1170** operating system wants filenames in. Space to hold the result
drhb11caac2007-08-24 17:52:21 +00001171** is obtained from malloc and must be freed by the calling
drh153c62c2007-08-24 03:51:33 +00001172** function.
drh054889e2005-11-30 03:20:31 +00001173*/
drh153c62c2007-08-24 03:51:33 +00001174static void *convertUtf8Filename(const char *zFilename){
1175 void *zConverted = 0;
1176 if( isNT() ){
1177 zConverted = utf8ToUnicode(zFilename);
shane891adea2008-10-22 16:55:47 +00001178/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1179*/
1180#if SQLITE_OS_WINCE==0
drh054889e2005-11-30 03:20:31 +00001181 }else{
drh153c62c2007-08-24 03:51:33 +00001182 zConverted = utf8ToMbcs(zFilename);
shane891adea2008-10-22 16:55:47 +00001183#endif
drh054889e2005-11-30 03:20:31 +00001184 }
drh153c62c2007-08-24 03:51:33 +00001185 /* caller will handle out of memory */
1186 return zConverted;
1187}
1188
1189/*
danielk197717b90b52008-06-06 11:11:25 +00001190** Create a temporary file name in zBuf. zBuf must be big enough to
1191** hold at pVfs->mxPathname characters.
1192*/
1193static int getTempname(int nBuf, char *zBuf){
1194 static char zChars[] =
1195 "abcdefghijklmnopqrstuvwxyz"
1196 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1197 "0123456789";
shane3582c5a2008-07-31 01:34:34 +00001198 size_t i, j;
danielk197717b90b52008-06-06 11:11:25 +00001199 char zTempPath[MAX_PATH+1];
1200 if( sqlite3_temp_directory ){
1201 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1202 }else if( isNT() ){
1203 char *zMulti;
1204 WCHAR zWidePath[MAX_PATH];
1205 GetTempPathW(MAX_PATH-30, zWidePath);
1206 zMulti = unicodeToUtf8(zWidePath);
1207 if( zMulti ){
1208 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1209 free(zMulti);
1210 }else{
1211 return SQLITE_NOMEM;
1212 }
shane891adea2008-10-22 16:55:47 +00001213/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1214** Since the ASCII version of these Windows API do not exist for WINCE,
1215** it's important to not reference them for WINCE builds.
1216*/
1217#if SQLITE_OS_WINCE==0
danielk197717b90b52008-06-06 11:11:25 +00001218 }else{
1219 char *zUtf8;
1220 char zMbcsPath[MAX_PATH];
1221 GetTempPathA(MAX_PATH-30, zMbcsPath);
drh1d298852008-11-18 19:18:52 +00001222 zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
danielk197717b90b52008-06-06 11:11:25 +00001223 if( zUtf8 ){
1224 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1225 free(zUtf8);
1226 }else{
1227 return SQLITE_NOMEM;
1228 }
shane891adea2008-10-22 16:55:47 +00001229#endif
danielk197717b90b52008-06-06 11:11:25 +00001230 }
drhea678832008-12-10 19:26:22 +00001231 for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
danielk197717b90b52008-06-06 11:11:25 +00001232 zTempPath[i] = 0;
1233 sqlite3_snprintf(nBuf-30, zBuf,
1234 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
drhea678832008-12-10 19:26:22 +00001235 j = sqlite3Strlen30(zBuf);
danielk197717b90b52008-06-06 11:11:25 +00001236 sqlite3_randomness(20, &zBuf[j]);
1237 for(i=0; i<20; i++, j++){
1238 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1239 }
1240 zBuf[j] = 0;
1241 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
1242 return SQLITE_OK;
1243}
1244
shane820800d2008-07-22 05:32:03 +00001245/*
1246** The return value of getLastErrorMsg
1247** is zero if the error message fits in the buffer, or non-zero
1248** otherwise (if the message was truncated).
1249*/
1250static int getLastErrorMsg(int nBuf, char *zBuf){
shane820800d2008-07-22 05:32:03 +00001251 /* FormatMessage returns 0 on failure. Otherwise it
1252 ** returns the number of TCHARs written to the output
1253 ** buffer, excluding the terminating null char.
1254 */
shaneea598922009-10-21 02:00:47 +00001255 DWORD error = GetLastError();
1256 DWORD dwLen = 0;
shanef639c402009-11-03 19:42:30 +00001257 char *zOut = 0;
shane820800d2008-07-22 05:32:03 +00001258
shaneea598922009-10-21 02:00:47 +00001259 if( isNT() ){
1260 WCHAR *zTempWide = NULL;
1261 dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1262 NULL,
1263 error,
1264 0,
1265 (LPWSTR) &zTempWide,
1266 0,
1267 0);
1268 if( dwLen > 0 ){
1269 /* allocate a buffer and convert to UTF8 */
1270 zOut = unicodeToUtf8(zTempWide);
1271 /* free the system buffer allocated by FormatMessage */
1272 LocalFree(zTempWide);
1273 }
1274/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1275** Since the ASCII version of these Windows API do not exist for WINCE,
1276** it's important to not reference them for WINCE builds.
1277*/
1278#if SQLITE_OS_WINCE==0
1279 }else{
1280 char *zTemp = NULL;
1281 dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
1282 NULL,
1283 error,
1284 0,
1285 (LPSTR) &zTemp,
1286 0,
1287 0);
1288 if( dwLen > 0 ){
1289 /* allocate a buffer and convert to UTF8 */
1290 zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
1291 /* free the system buffer allocated by FormatMessage */
1292 LocalFree(zTemp);
1293 }
1294#endif
1295 }
1296 if( 0 == dwLen ){
1297 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
1298 }else{
1299 /* copy a maximum of nBuf chars to output buffer */
1300 sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
1301 /* free the UTF8 buffer */
1302 free(zOut);
1303 }
shane820800d2008-07-22 05:32:03 +00001304 return 0;
1305}
1306
danielk197717b90b52008-06-06 11:11:25 +00001307/*
drh153c62c2007-08-24 03:51:33 +00001308** Open a file.
1309*/
1310static int winOpen(
1311 sqlite3_vfs *pVfs, /* Not used */
1312 const char *zName, /* Name of the file (UTF-8) */
1313 sqlite3_file *id, /* Write the SQLite file handle here */
1314 int flags, /* Open mode flags */
1315 int *pOutFlags /* Status return flags */
1316){
1317 HANDLE h;
1318 DWORD dwDesiredAccess;
1319 DWORD dwShareMode;
1320 DWORD dwCreationDisposition;
1321 DWORD dwFlagsAndAttributes = 0;
shaned94b0552008-09-30 04:20:07 +00001322#if SQLITE_OS_WINCE
1323 int isTemp = 0;
1324#endif
drh153c62c2007-08-24 03:51:33 +00001325 winFile *pFile = (winFile*)id;
danielk197717b90b52008-06-06 11:11:25 +00001326 void *zConverted; /* Filename in OS encoding */
1327 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
1328 char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */
1329
shane50daafc2009-03-05 05:54:55 +00001330 assert( id!=0 );
shane18e526c2008-12-10 22:30:24 +00001331 UNUSED_PARAMETER(pVfs);
1332
danielk197717b90b52008-06-06 11:11:25 +00001333 /* If the second argument to this function is NULL, generate a
1334 ** temporary file name to use
1335 */
1336 if( !zUtf8Name ){
1337 int rc = getTempname(MAX_PATH+1, zTmpname);
1338 if( rc!=SQLITE_OK ){
1339 return rc;
1340 }
1341 zUtf8Name = zTmpname;
1342 }
1343
1344 /* Convert the filename to the system encoding. */
1345 zConverted = convertUtf8Filename(zUtf8Name);
drh153c62c2007-08-24 03:51:33 +00001346 if( zConverted==0 ){
1347 return SQLITE_NOMEM;
1348 }
1349
1350 if( flags & SQLITE_OPEN_READWRITE ){
1351 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1352 }else{
1353 dwDesiredAccess = GENERIC_READ;
1354 }
shane68d405e2009-04-23 19:08:32 +00001355 /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
1356 ** created. SQLite doesn't use it to indicate "exclusive access"
1357 ** as it is usually understood.
1358 */
1359 assert(!(flags & SQLITE_OPEN_EXCLUSIVE) || (flags & SQLITE_OPEN_CREATE));
1360 if( flags & SQLITE_OPEN_EXCLUSIVE ){
1361 /* Creates a new file, only if it does not already exist. */
1362 /* If the file exists, it fails. */
1363 dwCreationDisposition = CREATE_NEW;
1364 }else if( flags & SQLITE_OPEN_CREATE ){
1365 /* Open existing file, or create if it doesn't exist */
drh153c62c2007-08-24 03:51:33 +00001366 dwCreationDisposition = OPEN_ALWAYS;
1367 }else{
shane68d405e2009-04-23 19:08:32 +00001368 /* Opens a file, only if it exists. */
drh153c62c2007-08-24 03:51:33 +00001369 dwCreationDisposition = OPEN_EXISTING;
1370 }
shane68d405e2009-04-23 19:08:32 +00001371 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
drh64c1ea62007-12-10 21:11:31 +00001372 if( flags & SQLITE_OPEN_DELETEONCLOSE ){
danielk197729bafea2008-06-26 10:41:19 +00001373#if SQLITE_OS_WINCE
drh0cd1ea52007-10-08 15:06:03 +00001374 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
shaned94b0552008-09-30 04:20:07 +00001375 isTemp = 1;
drh0cd1ea52007-10-08 15:06:03 +00001376#else
drh153c62c2007-08-24 03:51:33 +00001377 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
1378 | FILE_ATTRIBUTE_HIDDEN
1379 | FILE_FLAG_DELETE_ON_CLOSE;
drh0cd1ea52007-10-08 15:06:03 +00001380#endif
drh153c62c2007-08-24 03:51:33 +00001381 }else{
1382 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
1383 }
drh496936c2007-10-08 12:21:10 +00001384 /* Reports from the internet are that performance is always
1385 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
shaned94b0552008-09-30 04:20:07 +00001386#if SQLITE_OS_WINCE
drh496936c2007-10-08 12:21:10 +00001387 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
shaned94b0552008-09-30 04:20:07 +00001388#endif
drh153c62c2007-08-24 03:51:33 +00001389 if( isNT() ){
1390 h = CreateFileW((WCHAR*)zConverted,
1391 dwDesiredAccess,
1392 dwShareMode,
1393 NULL,
1394 dwCreationDisposition,
1395 dwFlagsAndAttributes,
1396 NULL
1397 );
shane891adea2008-10-22 16:55:47 +00001398/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1399** Since the ASCII version of these Windows API do not exist for WINCE,
1400** it's important to not reference them for WINCE builds.
1401*/
1402#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001403 }else{
drh153c62c2007-08-24 03:51:33 +00001404 h = CreateFileA((char*)zConverted,
1405 dwDesiredAccess,
1406 dwShareMode,
1407 NULL,
1408 dwCreationDisposition,
1409 dwFlagsAndAttributes,
1410 NULL
1411 );
shane891adea2008-10-22 16:55:47 +00001412#endif
drh153c62c2007-08-24 03:51:33 +00001413 }
1414 if( h==INVALID_HANDLE_VALUE ){
drhe1843af2007-08-30 16:46:04 +00001415 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001416 if( flags & SQLITE_OPEN_READWRITE ){
drha1115772009-03-30 13:04:17 +00001417 return winOpen(pVfs, zName, id,
drh153c62c2007-08-24 03:51:33 +00001418 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
1419 }else{
1420 return SQLITE_CANTOPEN;
1421 }
1422 }
1423 if( pOutFlags ){
1424 if( flags & SQLITE_OPEN_READWRITE ){
1425 *pOutFlags = SQLITE_OPEN_READWRITE;
1426 }else{
1427 *pOutFlags = SQLITE_OPEN_READONLY;
1428 }
1429 }
1430 memset(pFile, 0, sizeof(*pFile));
1431 pFile->pMethod = &winIoMethod;
1432 pFile->h = h;
shane9db299f2009-01-30 05:59:10 +00001433 pFile->lastErrno = NO_ERROR;
shane50daafc2009-03-05 05:54:55 +00001434 pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
danielk197729bafea2008-06-26 10:41:19 +00001435#if SQLITE_OS_WINCE
drh153c62c2007-08-24 03:51:33 +00001436 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
1437 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
drhaab2e6d2007-10-08 12:22:57 +00001438 && !winceCreateLock(zName, pFile)
drh153c62c2007-08-24 03:51:33 +00001439 ){
1440 CloseHandle(h);
drhb11caac2007-08-24 17:52:21 +00001441 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001442 return SQLITE_CANTOPEN;
1443 }
drhfc3afb62007-10-09 15:36:10 +00001444 if( isTemp ){
drh153c62c2007-08-24 03:51:33 +00001445 pFile->zDeleteOnClose = zConverted;
1446 }else
1447#endif
1448 {
drhb11caac2007-08-24 17:52:21 +00001449 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001450 }
drhaf5f0402007-09-03 17:09:03 +00001451 OpenCounter(+1);
drh153c62c2007-08-24 03:51:33 +00001452 return SQLITE_OK;
1453}
1454
1455/*
1456** Delete the named file.
1457**
1458** Note that windows does not allow a file to be deleted if some other
1459** process has it open. Sometimes a virus scanner or indexing program
1460** will open a journal file shortly after it is created in order to do
shane3582c5a2008-07-31 01:34:34 +00001461** whatever it does. While this other process is holding the
drh153c62c2007-08-24 03:51:33 +00001462** file open, we will be unable to delete it. To work around this
1463** problem, we delay 100 milliseconds and try to delete again. Up
1464** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
1465** up and returning an error.
1466*/
drhf024f0b2007-11-07 01:19:07 +00001467#define MX_DELETION_ATTEMPTS 5
drh153c62c2007-08-24 03:51:33 +00001468static int winDelete(
1469 sqlite3_vfs *pVfs, /* Not used on win32 */
1470 const char *zFilename, /* Name of file to delete */
1471 int syncDir /* Not used on win32 */
1472){
1473 int cnt = 0;
shaned94b0552008-09-30 04:20:07 +00001474 DWORD rc;
drhea678832008-12-10 19:26:22 +00001475 DWORD error = 0;
drh153c62c2007-08-24 03:51:33 +00001476 void *zConverted = convertUtf8Filename(zFilename);
shane18e526c2008-12-10 22:30:24 +00001477 UNUSED_PARAMETER(pVfs);
1478 UNUSED_PARAMETER(syncDir);
drh153c62c2007-08-24 03:51:33 +00001479 if( zConverted==0 ){
1480 return SQLITE_NOMEM;
1481 }
1482 SimulateIOError(return SQLITE_IOERR_DELETE);
1483 if( isNT() ){
1484 do{
drhf024f0b2007-11-07 01:19:07 +00001485 DeleteFileW(zConverted);
shane3582c5a2008-07-31 01:34:34 +00001486 }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
1487 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00001488 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00001489 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00001490/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1491** Since the ASCII version of these Windows API do not exist for WINCE,
1492** it's important to not reference them for WINCE builds.
1493*/
1494#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001495 }else{
drh153c62c2007-08-24 03:51:33 +00001496 do{
drhf024f0b2007-11-07 01:19:07 +00001497 DeleteFileA(zConverted);
shane3582c5a2008-07-31 01:34:34 +00001498 }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
1499 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00001500 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00001501 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00001502#endif
drh153c62c2007-08-24 03:51:33 +00001503 }
drhb11caac2007-08-24 17:52:21 +00001504 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001505 OSTRACE2("DELETE \"%s\"\n", zFilename);
shaned94b0552008-09-30 04:20:07 +00001506 return ( (rc == INVALID_FILE_ATTRIBUTES)
shane3582c5a2008-07-31 01:34:34 +00001507 && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
drh153c62c2007-08-24 03:51:33 +00001508}
1509
1510/*
1511** Check the existance and status of a file.
1512*/
1513static int winAccess(
1514 sqlite3_vfs *pVfs, /* Not used on win32 */
1515 const char *zFilename, /* Name of file to check */
danielk1977861f7452008-06-05 11:39:11 +00001516 int flags, /* Type of test to make on this file */
1517 int *pResOut /* OUT: Result */
drh153c62c2007-08-24 03:51:33 +00001518){
1519 DWORD attr;
drhea678832008-12-10 19:26:22 +00001520 int rc = 0;
drh153c62c2007-08-24 03:51:33 +00001521 void *zConverted = convertUtf8Filename(zFilename);
shane18e526c2008-12-10 22:30:24 +00001522 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001523 if( zConverted==0 ){
1524 return SQLITE_NOMEM;
1525 }
1526 if( isNT() ){
1527 attr = GetFileAttributesW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00001528/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1529** Since the ASCII version of these Windows API do not exist for WINCE,
1530** it's important to not reference them for WINCE builds.
1531*/
1532#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001533 }else{
drh153c62c2007-08-24 03:51:33 +00001534 attr = GetFileAttributesA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00001535#endif
drh153c62c2007-08-24 03:51:33 +00001536 }
drhb11caac2007-08-24 17:52:21 +00001537 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001538 switch( flags ){
drh50d3f902007-08-27 21:10:36 +00001539 case SQLITE_ACCESS_READ:
drh153c62c2007-08-24 03:51:33 +00001540 case SQLITE_ACCESS_EXISTS:
shane820800d2008-07-22 05:32:03 +00001541 rc = attr!=INVALID_FILE_ATTRIBUTES;
drh153c62c2007-08-24 03:51:33 +00001542 break;
1543 case SQLITE_ACCESS_READWRITE:
1544 rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
1545 break;
drh153c62c2007-08-24 03:51:33 +00001546 default:
1547 assert(!"Invalid flags argument");
1548 }
danielk1977861f7452008-06-05 11:39:11 +00001549 *pResOut = rc;
1550 return SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001551}
1552
1553
drh153c62c2007-08-24 03:51:33 +00001554/*
drh153c62c2007-08-24 03:51:33 +00001555** Turn a relative pathname into a full pathname. Write the full
1556** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
1557** bytes in size.
1558*/
1559static int winFullPathname(
danielk1977adfb9b02007-09-17 07:02:56 +00001560 sqlite3_vfs *pVfs, /* Pointer to vfs object */
1561 const char *zRelative, /* Possibly relative input path */
1562 int nFull, /* Size of output buffer in bytes */
1563 char *zFull /* Output buffer */
drh153c62c2007-08-24 03:51:33 +00001564){
drh1bd10f82008-12-10 21:19:56 +00001565
drh153c62c2007-08-24 03:51:33 +00001566#if defined(__CYGWIN__)
shane18e526c2008-12-10 22:30:24 +00001567 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00001568 cygwin_conv_to_full_win32_path(zRelative, zFull);
danielk1977076f1c02007-09-12 14:09:23 +00001569 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001570#endif
1571
danielk197729bafea2008-06-26 10:41:19 +00001572#if SQLITE_OS_WINCE
shane18e526c2008-12-10 22:30:24 +00001573 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00001574 /* WinCE has no concept of a relative pathname, or so I am told. */
1575 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
drhe8256092007-10-09 15:20:39 +00001576 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001577#endif
1578
danielk197729bafea2008-06-26 10:41:19 +00001579#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
drh153c62c2007-08-24 03:51:33 +00001580 int nByte;
1581 void *zConverted;
1582 char *zOut;
shane18e526c2008-12-10 22:30:24 +00001583 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00001584 zConverted = convertUtf8Filename(zRelative);
1585 if( isNT() ){
1586 WCHAR *zTemp;
1587 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001588 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001589 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001590 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001591 return SQLITE_NOMEM;
1592 }
1593 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001594 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001595 zOut = unicodeToUtf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001596 free(zTemp);
shane891adea2008-10-22 16:55:47 +00001597/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1598** Since the ASCII version of these Windows API do not exist for WINCE,
1599** it's important to not reference them for WINCE builds.
1600*/
1601#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001602 }else{
1603 char *zTemp;
1604 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001605 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001606 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001607 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001608 return SQLITE_NOMEM;
1609 }
1610 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001611 free(zConverted);
drh1d298852008-11-18 19:18:52 +00001612 zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001613 free(zTemp);
shane891adea2008-10-22 16:55:47 +00001614#endif
drh153c62c2007-08-24 03:51:33 +00001615 }
1616 if( zOut ){
drhb11caac2007-08-24 17:52:21 +00001617 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
1618 free(zOut);
drh153c62c2007-08-24 03:51:33 +00001619 return SQLITE_OK;
1620 }else{
1621 return SQLITE_NOMEM;
1622 }
1623#endif
1624}
1625
shane50daafc2009-03-05 05:54:55 +00001626/*
1627** Get the sector size of the device used to store
1628** file.
1629*/
1630static int getSectorSize(
1631 sqlite3_vfs *pVfs,
1632 const char *zRelative /* UTF-8 file name */
1633){
1634 DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
shane11bb41f2009-09-10 20:23:30 +00001635 /* GetDiskFreeSpace is not supported under WINCE */
1636#if SQLITE_OS_WINCE
1637 UNUSED_PARAMETER(pVfs);
1638 UNUSED_PARAMETER(zRelative);
1639#else
shane50daafc2009-03-05 05:54:55 +00001640 char zFullpath[MAX_PATH+1];
1641 int rc;
shane11bb41f2009-09-10 20:23:30 +00001642 DWORD dwRet = 0;
1643 DWORD dwDummy;
shane50daafc2009-03-05 05:54:55 +00001644
1645 /*
1646 ** We need to get the full path name of the file
1647 ** to get the drive letter to look up the sector
1648 ** size.
1649 */
1650 rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
1651 if( rc == SQLITE_OK )
1652 {
1653 void *zConverted = convertUtf8Filename(zFullpath);
1654 if( zConverted ){
1655 if( isNT() ){
shane50daafc2009-03-05 05:54:55 +00001656 /* trim path to just drive reference */
1657 WCHAR *p = zConverted;
shane7a8537b2009-04-15 14:36:25 +00001658 for(;*p;p++){
1659 if( *p == '\\' ){
1660 *p = '\0';
shane50daafc2009-03-05 05:54:55 +00001661 break;
1662 }
1663 }
1664 dwRet = GetDiskFreeSpaceW((WCHAR*)zConverted,
chwa5dc7f72009-04-09 14:27:06 +00001665 &dwDummy,
shane50daafc2009-03-05 05:54:55 +00001666 &bytesPerSector,
chwa5dc7f72009-04-09 14:27:06 +00001667 &dwDummy,
1668 &dwDummy);
shane50daafc2009-03-05 05:54:55 +00001669 }else{
shane50daafc2009-03-05 05:54:55 +00001670 /* trim path to just drive reference */
shaneea598922009-10-21 02:00:47 +00001671 char *p = (char *)zConverted;
shane7a8537b2009-04-15 14:36:25 +00001672 for(;*p;p++){
1673 if( *p == '\\' ){
1674 *p = '\0';
shane50daafc2009-03-05 05:54:55 +00001675 break;
1676 }
1677 }
shaneea598922009-10-21 02:00:47 +00001678 dwRet = GetDiskFreeSpaceA((char*)zConverted,
chwa5dc7f72009-04-09 14:27:06 +00001679 &dwDummy,
shane50daafc2009-03-05 05:54:55 +00001680 &bytesPerSector,
chwa5dc7f72009-04-09 14:27:06 +00001681 &dwDummy,
1682 &dwDummy);
shane50daafc2009-03-05 05:54:55 +00001683 }
1684 free(zConverted);
1685 }
1686 if( !dwRet ){
1687 bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
1688 }
1689 }
shane11bb41f2009-09-10 20:23:30 +00001690#endif
shane50daafc2009-03-05 05:54:55 +00001691 return (int) bytesPerSector;
1692}
1693
drh153c62c2007-08-24 03:51:33 +00001694#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh761df872006-12-21 01:29:22 +00001695/*
1696** Interfaces for opening a shared library, finding entry points
1697** within the shared library, and closing the shared library.
1698*/
drh153c62c2007-08-24 03:51:33 +00001699/*
1700** Interfaces for opening a shared library, finding entry points
1701** within the shared library, and closing the shared library.
1702*/
1703static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
drh761df872006-12-21 01:29:22 +00001704 HANDLE h;
1705 void *zConverted = convertUtf8Filename(zFilename);
drh1bd10f82008-12-10 21:19:56 +00001706 UNUSED_PARAMETER(pVfs);
drh761df872006-12-21 01:29:22 +00001707 if( zConverted==0 ){
1708 return 0;
1709 }
1710 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00001711 h = LoadLibraryW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00001712/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1713** Since the ASCII version of these Windows API do not exist for WINCE,
1714** it's important to not reference them for WINCE builds.
1715*/
1716#if SQLITE_OS_WINCE==0
drh761df872006-12-21 01:29:22 +00001717 }else{
drh584c0942006-12-21 03:20:40 +00001718 h = LoadLibraryA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00001719#endif
drh761df872006-12-21 01:29:22 +00001720 }
drhb11caac2007-08-24 17:52:21 +00001721 free(zConverted);
drh761df872006-12-21 01:29:22 +00001722 return (void*)h;
drh761df872006-12-21 01:29:22 +00001723}
drh153c62c2007-08-24 03:51:33 +00001724static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
drh1bd10f82008-12-10 21:19:56 +00001725 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00001726 getLastErrorMsg(nBuf, zBufOut);
drh153c62c2007-08-24 03:51:33 +00001727}
drh1875f7a2008-12-08 18:19:17 +00001728void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
drh1bd10f82008-12-10 21:19:56 +00001729 UNUSED_PARAMETER(pVfs);
danielk197729bafea2008-06-26 10:41:19 +00001730#if SQLITE_OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00001731 /* The GetProcAddressA() routine is only available on wince. */
drh1875f7a2008-12-08 18:19:17 +00001732 return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001733#else
1734 /* All other windows platforms expect GetProcAddress() to take
1735 ** an Ansi string regardless of the _UNICODE setting */
drh1875f7a2008-12-08 18:19:17 +00001736 return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001737#endif
drh761df872006-12-21 01:29:22 +00001738}
drh153c62c2007-08-24 03:51:33 +00001739void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh1bd10f82008-12-10 21:19:56 +00001740 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001741 FreeLibrary((HANDLE)pHandle);
drh761df872006-12-21 01:29:22 +00001742}
drh153c62c2007-08-24 03:51:33 +00001743#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
1744 #define winDlOpen 0
1745 #define winDlError 0
1746 #define winDlSym 0
1747 #define winDlClose 0
1748#endif
1749
drh761df872006-12-21 01:29:22 +00001750
drh0ccebe72005-06-07 22:22:50 +00001751/*
drh153c62c2007-08-24 03:51:33 +00001752** Write up to nBuf bytes of randomness into zBuf.
drhbbd42a62004-05-22 17:41:58 +00001753*/
drh153c62c2007-08-24 03:51:33 +00001754static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drhd1a79312007-09-03 13:06:11 +00001755 int n = 0;
shanec7b7f1a2008-11-19 21:35:46 +00001756 UNUSED_PARAMETER(pVfs);
1757#if defined(SQLITE_TEST)
1758 n = nBuf;
1759 memset(zBuf, 0, nBuf);
1760#else
drh86742612007-09-05 17:06:03 +00001761 if( sizeof(SYSTEMTIME)<=nBuf-n ){
drhd1a79312007-09-03 13:06:11 +00001762 SYSTEMTIME x;
1763 GetSystemTime(&x);
1764 memcpy(&zBuf[n], &x, sizeof(x));
1765 n += sizeof(x);
drh153c62c2007-08-24 03:51:33 +00001766 }
drhd1a79312007-09-03 13:06:11 +00001767 if( sizeof(DWORD)<=nBuf-n ){
1768 DWORD pid = GetCurrentProcessId();
1769 memcpy(&zBuf[n], &pid, sizeof(pid));
1770 n += sizeof(pid);
1771 }
1772 if( sizeof(DWORD)<=nBuf-n ){
1773 DWORD cnt = GetTickCount();
1774 memcpy(&zBuf[n], &cnt, sizeof(cnt));
1775 n += sizeof(cnt);
1776 }
1777 if( sizeof(LARGE_INTEGER)<=nBuf-n ){
1778 LARGE_INTEGER i;
1779 QueryPerformanceCounter(&i);
1780 memcpy(&zBuf[n], &i, sizeof(i));
1781 n += sizeof(i);
1782 }
shanec7b7f1a2008-11-19 21:35:46 +00001783#endif
drhd1a79312007-09-03 13:06:11 +00001784 return n;
drhbbd42a62004-05-22 17:41:58 +00001785}
1786
drh153c62c2007-08-24 03:51:33 +00001787
drhbbd42a62004-05-22 17:41:58 +00001788/*
1789** Sleep for a little while. Return the amount of time slept.
1790*/
drh153c62c2007-08-24 03:51:33 +00001791static int winSleep(sqlite3_vfs *pVfs, int microsec){
1792 Sleep((microsec+999)/1000);
drh1bd10f82008-12-10 21:19:56 +00001793 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001794 return ((microsec+999)/1000)*1000;
drhbbd42a62004-05-22 17:41:58 +00001795}
1796
1797/*
drhbbd42a62004-05-22 17:41:58 +00001798** The following variable, if set to a non-zero value, becomes the result
1799** returned from sqlite3OsCurrentTime(). This is used for testing.
1800*/
1801#ifdef SQLITE_TEST
1802int sqlite3_current_time = 0;
1803#endif
1804
1805/*
1806** Find the current time (in Universal Coordinated Time). Write the
1807** current time and date as a Julian Day number into *prNow and
1808** return 0. Return 1 if the time and date cannot be found.
1809*/
drh153c62c2007-08-24 03:51:33 +00001810int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001811 FILETIME ft;
1812 /* FILETIME structure is a 64-bit value representing the number of
1813 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1814 */
drh5c905d62009-03-30 12:42:45 +00001815 sqlite3_int64 timeW; /* Whole days */
1816 sqlite3_int64 timeF; /* Fractional Days */
1817
1818 /* Number of 100-nanosecond intervals in a single day */
1819 static const sqlite3_int64 ntuPerDay =
1820 10000000*(sqlite3_int64)86400;
1821
1822 /* Number of 100-nanosecond intervals in half of a day */
1823 static const sqlite3_int64 ntuPerHalfDay =
1824 10000000*(sqlite3_int64)43200;
1825
shaneb08a67a2009-03-31 03:41:56 +00001826 /* 2^32 - to avoid use of LL and warnings in gcc */
1827 static const sqlite3_int64 max32BitValue =
1828 (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
drh5c905d62009-03-30 12:42:45 +00001829
danielk197729bafea2008-06-26 10:41:19 +00001830#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +00001831 SYSTEMTIME time;
1832 GetSystemTime(&time);
shane820800d2008-07-22 05:32:03 +00001833 /* if SystemTimeToFileTime() fails, it returns zero. */
1834 if (!SystemTimeToFileTime(&time,&ft)){
1835 return 1;
1836 }
drhcc78fea2006-01-06 16:17:05 +00001837#else
drhbbd42a62004-05-22 17:41:58 +00001838 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001839#endif
drh1bd10f82008-12-10 21:19:56 +00001840 UNUSED_PARAMETER(pVfs);
shaneb08a67a2009-03-31 03:41:56 +00001841 timeW = (((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite3_int64)ft.dwLowDateTime;
drh5c905d62009-03-30 12:42:45 +00001842 timeF = timeW % ntuPerDay; /* fractional days (100-nanoseconds) */
1843 timeW = timeW / ntuPerDay; /* whole days */
1844 timeW = timeW + 2305813; /* add whole days (from 2305813.5) */
1845 timeF = timeF + ntuPerHalfDay; /* add half a day (from 2305813.5) */
1846 timeW = timeW + (timeF/ntuPerDay); /* add whole day if half day made one */
1847 timeF = timeF % ntuPerDay; /* compute new fractional days */
1848 *prNow = (double)timeW + ((double)timeF / (double)ntuPerDay);
drhbbd42a62004-05-22 17:41:58 +00001849#ifdef SQLITE_TEST
1850 if( sqlite3_current_time ){
shanefbd60f82009-02-04 03:59:25 +00001851 *prNow = ((double)sqlite3_current_time + (double)43200) / (double)86400 + (double)2440587;
drhbbd42a62004-05-22 17:41:58 +00001852 }
1853#endif
1854 return 0;
1855}
1856
shane820800d2008-07-22 05:32:03 +00001857/*
1858** The idea is that this function works like a combination of
1859** GetLastError() and FormatMessage() on windows (or errno and
1860** strerror_r() on unix). After an error is returned by an OS
1861** function, SQLite calls this function with zBuf pointing to
1862** a buffer of nBuf bytes. The OS layer should populate the
1863** buffer with a nul-terminated UTF-8 encoded error message
shanebe217792009-03-05 04:20:31 +00001864** describing the last IO error to have occurred within the calling
shane820800d2008-07-22 05:32:03 +00001865** thread.
1866**
1867** If the error message is too large for the supplied buffer,
1868** it should be truncated. The return value of xGetLastError
1869** is zero if the error message fits in the buffer, or non-zero
1870** otherwise (if the message was truncated). If non-zero is returned,
1871** then it is not necessary to include the nul-terminator character
1872** in the output buffer.
1873**
1874** Not supplying an error message will have no adverse effect
1875** on SQLite. It is fine to have an implementation that never
1876** returns an error message:
1877**
1878** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
1879** assert(zBuf[0]=='\0');
1880** return 0;
1881** }
1882**
1883** However if an error message is supplied, it will be incorporated
1884** by sqlite into the error message available to the user using
1885** sqlite3_errmsg(), possibly making IO errors easier to debug.
1886*/
danielk1977bcb97fe2008-06-06 15:49:29 +00001887static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drh1bd10f82008-12-10 21:19:56 +00001888 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00001889 return getLastErrorMsg(nBuf, zBuf);
danielk1977bcb97fe2008-06-06 15:49:29 +00001890}
drhb4bc7052006-01-11 23:40:33 +00001891
1892/*
danielk1977c0fa4c52008-06-25 17:19:00 +00001893** Initialize and deinitialize the operating system interface.
danielk197713a68c32005-12-15 10:11:30 +00001894*/
danielk1977c0fa4c52008-06-25 17:19:00 +00001895int sqlite3_os_init(void){
drh153c62c2007-08-24 03:51:33 +00001896 static sqlite3_vfs winVfs = {
1897 1, /* iVersion */
1898 sizeof(winFile), /* szOsFile */
1899 MAX_PATH, /* mxPathname */
drh153c62c2007-08-24 03:51:33 +00001900 0, /* pNext */
1901 "win32", /* zName */
1902 0, /* pAppData */
danielk1977bcb97fe2008-06-06 15:49:29 +00001903
drh153c62c2007-08-24 03:51:33 +00001904 winOpen, /* xOpen */
1905 winDelete, /* xDelete */
1906 winAccess, /* xAccess */
drh153c62c2007-08-24 03:51:33 +00001907 winFullPathname, /* xFullPathname */
1908 winDlOpen, /* xDlOpen */
1909 winDlError, /* xDlError */
1910 winDlSym, /* xDlSym */
1911 winDlClose, /* xDlClose */
1912 winRandomness, /* xRandomness */
1913 winSleep, /* xSleep */
danielk1977bcb97fe2008-06-06 15:49:29 +00001914 winCurrentTime, /* xCurrentTime */
1915 winGetLastError /* xGetLastError */
drh153c62c2007-08-24 03:51:33 +00001916 };
dane1ab2192009-08-17 15:16:19 +00001917
danielk1977c0fa4c52008-06-25 17:19:00 +00001918 sqlite3_vfs_register(&winVfs, 1);
1919 return SQLITE_OK;
danielk197713a68c32005-12-15 10:11:30 +00001920}
danielk1977c0fa4c52008-06-25 17:19:00 +00001921int sqlite3_os_end(void){
1922 return SQLITE_OK;
1923}
drh40257ff2008-06-13 18:24:27 +00001924
danielk197729bafea2008-06-26 10:41:19 +00001925#endif /* SQLITE_OS_WIN */