blob: c26f702952d8355e5ccc459534c8c6e92e8ef975 [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.
danielk1977822a5162008-05-16 04:51:54 +000014**
shane18e526c2008-12-10 22:30:24 +000015** $Id: os_win.c,v 1.144 2008/12/10 22:30:25 shane Exp $
drhbbd42a62004-05-22 17:41:58 +000016*/
drhbbd42a62004-05-22 17:41:58 +000017#include "sqliteInt.h"
danielk197729bafea2008-06-26 10:41:19 +000018#if SQLITE_OS_WIN /* This file is used for windows only */
drhbbd42a62004-05-22 17:41:58 +000019
drhb11caac2007-08-24 17:52:21 +000020
21/*
22** A Note About Memory Allocation:
23**
24** This driver uses malloc()/free() directly rather than going through
25** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers
26** are designed for use on embedded systems where memory is scarce and
27** malloc failures happen frequently. Win32 does not typically run on
28** embedded systems, and when it does the developers normally have bigger
29** problems to worry about than running out of memory. So there is not
30** a compelling need to use the wrappers.
31**
32** But there is a good reason to not use the wrappers. If we use the
33** wrappers then we will get simulated malloc() failures within this
34** driver. And that causes all kinds of problems for our tests. We
35** could enhance SQLite to deal with simulated malloc failures within
36** the OS driver, but the code to deal with those failure would not
37** be exercised on Linux (which does not need to malloc() in the driver)
38** and so we would have difficulty writing coverage tests for that
39** code. Better to leave the code out, we think.
40**
41** The point of this discussion is as follows: When creating a new
42** OS layer for an embedded system, if you use this file as an example,
43** avoid the use of malloc()/free(). Those routines work ok on windows
44** desktops but not so well in embedded systems.
45*/
46
drhbbd42a62004-05-22 17:41:58 +000047#include <winbase.h>
48
drh09bf0e82005-03-21 00:36:08 +000049#ifdef __CYGWIN__
50# include <sys/cygwin.h>
51#endif
52
drhbbd42a62004-05-22 17:41:58 +000053/*
54** Macros used to determine whether or not to use threads.
55*/
56#if defined(THREADSAFE) && THREADSAFE
57# define SQLITE_W32_THREADS 1
58#endif
59
60/*
61** Include code that is common to all os_*.c files
62*/
63#include "os_common.h"
64
65/*
shane171fa292008-09-01 22:15:18 +000066** Some microsoft compilers lack this definition.
67*/
68#ifndef INVALID_FILE_ATTRIBUTES
69# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
70#endif
71
72/*
drhcc78fea2006-01-06 16:17:05 +000073** Determine if we are dealing with WindowsCE - which has a much
74** reduced API.
75*/
shane891adea2008-10-22 16:55:47 +000076#if SQLITE_OS_WINCE
drhd2832bf2007-01-10 18:56:15 +000077# define AreFileApisANSI() 1
drhcc78fea2006-01-06 16:17:05 +000078#endif
79
80/*
drh72aead82006-01-23 15:54:25 +000081** WinCE lacks native support for file locking so we have to fake it
82** with some code of our own.
83*/
danielk197729bafea2008-06-26 10:41:19 +000084#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +000085typedef struct winceLock {
86 int nReaders; /* Number of reader locks obtained */
87 BOOL bPending; /* Indicates a pending lock has been obtained */
88 BOOL bReserved; /* Indicates a reserved lock has been obtained */
89 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
90} winceLock;
91#endif
92
93/*
drh153c62c2007-08-24 03:51:33 +000094** The winFile structure is a subclass of sqlite3_file* specific to the win32
drh054889e2005-11-30 03:20:31 +000095** portability layer.
drh9cbe6352005-11-29 03:13:21 +000096*/
drh054889e2005-11-30 03:20:31 +000097typedef struct winFile winFile;
98struct winFile {
drh153c62c2007-08-24 03:51:33 +000099 const sqlite3_io_methods *pMethod;/* Must be first */
drh9cbe6352005-11-29 03:13:21 +0000100 HANDLE h; /* Handle for accessing the file */
101 unsigned char locktype; /* Type of lock currently held on this file */
102 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
danielk197729bafea2008-06-26 10:41:19 +0000103#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +0000104 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
105 HANDLE hMutex; /* Mutex used to control access to shared lock */
106 HANDLE hShared; /* Shared memory segment used for locking */
107 winceLock local; /* Locks obtained by this instance of winFile */
108 winceLock *shared; /* Global shared lock memory for the file */
drhcc78fea2006-01-06 16:17:05 +0000109#endif
drh9cbe6352005-11-29 03:13:21 +0000110};
111
112
drh9cbe6352005-11-29 03:13:21 +0000113/*
drhc0929982005-09-05 19:08:29 +0000114** The following variable is (normally) set once and never changes
115** thereafter. It records whether the operating system is Win95
116** or WinNT.
117**
118** 0: Operating system unknown.
119** 1: Operating system is Win95.
120** 2: Operating system is WinNT.
121**
122** In order to facilitate testing on a WinNT system, the test fixture
123** can manually set this value to 1 to emulate Win98 behavior.
124*/
drh153c62c2007-08-24 03:51:33 +0000125#ifdef SQLITE_TEST
drhc0929982005-09-05 19:08:29 +0000126int sqlite3_os_type = 0;
drh153c62c2007-08-24 03:51:33 +0000127#else
128static int sqlite3_os_type = 0;
129#endif
drhc0929982005-09-05 19:08:29 +0000130
131/*
drhcc78fea2006-01-06 16:17:05 +0000132** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
133** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +0000134**
135** Here is an interesting observation: Win95, Win98, and WinME lack
136** the LockFileEx() API. But we can still statically link against that
137** API as long as we don't call it win running Win95/98/ME. A call to
138** this routine is used to determine if the host is Win95/98/ME or
139** WinNT/2K/XP so that we will know whether or not we can safely call
140** the LockFileEx() API.
141*/
danielk197729bafea2008-06-26 10:41:19 +0000142#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +0000143# define isNT() (1)
144#else
145 static int isNT(void){
146 if( sqlite3_os_type==0 ){
147 OSVERSIONINFO sInfo;
148 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
149 GetVersionEx(&sInfo);
150 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
151 }
152 return sqlite3_os_type==2;
drhc0929982005-09-05 19:08:29 +0000153 }
danielk197729bafea2008-06-26 10:41:19 +0000154#endif /* SQLITE_OS_WINCE */
drhcc78fea2006-01-06 16:17:05 +0000155
drhc0929982005-09-05 19:08:29 +0000156/*
drh584c0942006-12-21 03:20:40 +0000157** Convert a UTF-8 string to microsoft unicode (UTF-16?).
158**
drhb11caac2007-08-24 17:52:21 +0000159** Space to hold the returned string is obtained from malloc.
drhc0929982005-09-05 19:08:29 +0000160*/
161static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000162 int nChar;
drhc0929982005-09-05 19:08:29 +0000163 WCHAR *zWideFilename;
164
drhe3dd8bb2006-02-27 23:44:35 +0000165 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
drhb11caac2007-08-24 17:52:21 +0000166 zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000167 if( zWideFilename==0 ){
168 return 0;
169 }
drhe3dd8bb2006-02-27 23:44:35 +0000170 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
171 if( nChar==0 ){
drhb11caac2007-08-24 17:52:21 +0000172 free(zWideFilename);
drhc0929982005-09-05 19:08:29 +0000173 zWideFilename = 0;
174 }
175 return zWideFilename;
176}
177
178/*
drh584c0942006-12-21 03:20:40 +0000179** Convert microsoft unicode to UTF-8. Space to hold the returned string is
drhb11caac2007-08-24 17:52:21 +0000180** obtained from malloc().
drhc0929982005-09-05 19:08:29 +0000181*/
182static char *unicodeToUtf8(const WCHAR *zWideFilename){
183 int nByte;
184 char *zFilename;
185
186 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000187 zFilename = malloc( nByte );
drhc0929982005-09-05 19:08:29 +0000188 if( zFilename==0 ){
189 return 0;
190 }
191 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
192 0, 0);
193 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000194 free(zFilename);
drhc0929982005-09-05 19:08:29 +0000195 zFilename = 0;
196 }
197 return zFilename;
198}
199
drh371de5a2006-10-30 13:37:22 +0000200/*
drh584c0942006-12-21 03:20:40 +0000201** Convert an ansi string to microsoft unicode, based on the
202** current codepage settings for file apis.
203**
204** Space to hold the returned string is obtained
drhb11caac2007-08-24 17:52:21 +0000205** from malloc.
drh371de5a2006-10-30 13:37:22 +0000206*/
207static WCHAR *mbcsToUnicode(const char *zFilename){
208 int nByte;
209 WCHAR *zMbcsFilename;
drh584c0942006-12-21 03:20:40 +0000210 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000211
drh584c0942006-12-21 03:20:40 +0000212 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
drhb11caac2007-08-24 17:52:21 +0000213 zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
drh371de5a2006-10-30 13:37:22 +0000214 if( zMbcsFilename==0 ){
215 return 0;
216 }
drh584c0942006-12-21 03:20:40 +0000217 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
drh371de5a2006-10-30 13:37:22 +0000218 if( nByte==0 ){
drhb11caac2007-08-24 17:52:21 +0000219 free(zMbcsFilename);
drh371de5a2006-10-30 13:37:22 +0000220 zMbcsFilename = 0;
221 }
222 return zMbcsFilename;
223}
224
225/*
drh584c0942006-12-21 03:20:40 +0000226** Convert microsoft unicode to multibyte character string, based on the
227** user's Ansi codepage.
228**
229** Space to hold the returned string is obtained from
drhb11caac2007-08-24 17:52:21 +0000230** malloc().
drh371de5a2006-10-30 13:37:22 +0000231*/
232static char *unicodeToMbcs(const WCHAR *zWideFilename){
233 int nByte;
234 char *zFilename;
drh584c0942006-12-21 03:20:40 +0000235 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000236
drh584c0942006-12-21 03:20:40 +0000237 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000238 zFilename = malloc( nByte );
drh371de5a2006-10-30 13:37:22 +0000239 if( zFilename==0 ){
240 return 0;
241 }
drh584c0942006-12-21 03:20:40 +0000242 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
drh371de5a2006-10-30 13:37:22 +0000243 0, 0);
244 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000245 free(zFilename);
drh371de5a2006-10-30 13:37:22 +0000246 zFilename = 0;
247 }
248 return zFilename;
249}
250
251/*
252** Convert multibyte character string to UTF-8. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000253** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000254*/
drh1d298852008-11-18 19:18:52 +0000255char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
drh371de5a2006-10-30 13:37:22 +0000256 char *zFilenameUtf8;
257 WCHAR *zTmpWide;
258
259 zTmpWide = mbcsToUnicode(zFilename);
260 if( zTmpWide==0 ){
261 return 0;
262 }
263 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000264 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000265 return zFilenameUtf8;
266}
267
268/*
269** Convert UTF-8 to multibyte character string. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000270** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000271*/
272static char *utf8ToMbcs(const char *zFilename){
273 char *zFilenameMbcs;
274 WCHAR *zTmpWide;
275
276 zTmpWide = utf8ToUnicode(zFilename);
277 if( zTmpWide==0 ){
278 return 0;
279 }
280 zFilenameMbcs = unicodeToMbcs(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000281 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000282 return zFilenameMbcs;
283}
284
danielk197729bafea2008-06-26 10:41:19 +0000285#if SQLITE_OS_WINCE
drh72aead82006-01-23 15:54:25 +0000286/*************************************************************************
287** This section contains code for WinCE only.
288*/
289/*
290** WindowsCE does not have a localtime() function. So create a
291** substitute.
292*/
293#include <time.h>
294struct tm *__cdecl localtime(const time_t *t)
295{
296 static struct tm y;
297 FILETIME uTm, lTm;
298 SYSTEMTIME pTm;
drhc51250a2007-09-20 14:39:23 +0000299 sqlite3_int64 t64;
drh72aead82006-01-23 15:54:25 +0000300 t64 = *t;
301 t64 = (t64 + 11644473600)*10000000;
302 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
303 uTm.dwHighDateTime= t64 >> 32;
304 FileTimeToLocalFileTime(&uTm,&lTm);
305 FileTimeToSystemTime(&lTm,&pTm);
306 y.tm_year = pTm.wYear - 1900;
307 y.tm_mon = pTm.wMonth - 1;
308 y.tm_wday = pTm.wDayOfWeek;
309 y.tm_mday = pTm.wDay;
310 y.tm_hour = pTm.wHour;
311 y.tm_min = pTm.wMinute;
312 y.tm_sec = pTm.wSecond;
313 return &y;
314}
315
316/* This will never be called, but defined to make the code compile */
317#define GetTempPathA(a,b)
318
319#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
320#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
321#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
322
323#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
324
325/*
326** Acquire a lock on the handle h
327*/
328static void winceMutexAcquire(HANDLE h){
329 DWORD dwErr;
330 do {
331 dwErr = WaitForSingleObject(h, INFINITE);
332 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
333}
334/*
335** Release a lock acquired by winceMutexAcquire()
336*/
337#define winceMutexRelease(h) ReleaseMutex(h)
338
339/*
340** Create the mutex and shared memory used for locking in the file
341** descriptor pFile
342*/
343static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
344 WCHAR *zTok;
345 WCHAR *zName = utf8ToUnicode(zFilename);
346 BOOL bInit = TRUE;
347
348 /* Initialize the local lockdata */
349 ZeroMemory(&pFile->local, sizeof(pFile->local));
350
351 /* Replace the backslashes from the filename and lowercase it
352 ** to derive a mutex name. */
353 zTok = CharLowerW(zName);
354 for (;*zTok;zTok++){
355 if (*zTok == '\\') *zTok = '_';
356 }
357
358 /* Create/open the named mutex */
359 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
360 if (!pFile->hMutex){
drhb11caac2007-08-24 17:52:21 +0000361 free(zName);
drh72aead82006-01-23 15:54:25 +0000362 return FALSE;
363 }
364
365 /* Acquire the mutex before continuing */
366 winceMutexAcquire(pFile->hMutex);
367
368 /* Since the names of named mutexes, semaphores, file mappings etc are
369 ** case-sensitive, take advantage of that by uppercasing the mutex name
370 ** and using that as the shared filemapping name.
371 */
372 CharUpperW(zName);
373 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
374 PAGE_READWRITE, 0, sizeof(winceLock),
375 zName);
376
377 /* Set a flag that indicates we're the first to create the memory so it
378 ** must be zero-initialized */
379 if (GetLastError() == ERROR_ALREADY_EXISTS){
380 bInit = FALSE;
381 }
382
drhb11caac2007-08-24 17:52:21 +0000383 free(zName);
drh72aead82006-01-23 15:54:25 +0000384
385 /* If we succeeded in making the shared memory handle, map it. */
386 if (pFile->hShared){
387 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
388 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
389 /* If mapping failed, close the shared memory handle and erase it */
390 if (!pFile->shared){
391 CloseHandle(pFile->hShared);
392 pFile->hShared = NULL;
393 }
394 }
395
396 /* If shared memory could not be created, then close the mutex and fail */
397 if (pFile->hShared == NULL){
398 winceMutexRelease(pFile->hMutex);
399 CloseHandle(pFile->hMutex);
400 pFile->hMutex = NULL;
401 return FALSE;
402 }
403
404 /* Initialize the shared memory if we're supposed to */
405 if (bInit) {
406 ZeroMemory(pFile->shared, sizeof(winceLock));
407 }
408
409 winceMutexRelease(pFile->hMutex);
410 return TRUE;
411}
412
413/*
414** Destroy the part of winFile that deals with wince locks
415*/
416static void winceDestroyLock(winFile *pFile){
417 if (pFile->hMutex){
418 /* Acquire the mutex */
419 winceMutexAcquire(pFile->hMutex);
420
421 /* The following blocks should probably assert in debug mode, but they
422 are to cleanup in case any locks remained open */
423 if (pFile->local.nReaders){
424 pFile->shared->nReaders --;
425 }
426 if (pFile->local.bReserved){
427 pFile->shared->bReserved = FALSE;
428 }
429 if (pFile->local.bPending){
430 pFile->shared->bPending = FALSE;
431 }
432 if (pFile->local.bExclusive){
433 pFile->shared->bExclusive = FALSE;
434 }
435
436 /* De-reference and close our copy of the shared memory handle */
437 UnmapViewOfFile(pFile->shared);
438 CloseHandle(pFile->hShared);
439
440 /* Done with the mutex */
441 winceMutexRelease(pFile->hMutex);
442 CloseHandle(pFile->hMutex);
443 pFile->hMutex = NULL;
444 }
445}
446
447/*
448** An implementation of the LockFile() API of windows for wince
449*/
450static BOOL winceLockFile(
451 HANDLE *phFile,
452 DWORD dwFileOffsetLow,
453 DWORD dwFileOffsetHigh,
454 DWORD nNumberOfBytesToLockLow,
455 DWORD nNumberOfBytesToLockHigh
456){
457 winFile *pFile = HANDLE_TO_WINFILE(phFile);
458 BOOL bReturn = FALSE;
459
460 if (!pFile->hMutex) return TRUE;
461 winceMutexAcquire(pFile->hMutex);
462
463 /* Wanting an exclusive lock? */
464 if (dwFileOffsetLow == SHARED_FIRST
465 && nNumberOfBytesToLockLow == SHARED_SIZE){
466 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
467 pFile->shared->bExclusive = TRUE;
468 pFile->local.bExclusive = TRUE;
469 bReturn = TRUE;
470 }
471 }
472
473 /* Want a read-only lock? */
474 else if ((dwFileOffsetLow >= SHARED_FIRST &&
475 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
476 nNumberOfBytesToLockLow == 1){
477 if (pFile->shared->bExclusive == 0){
478 pFile->local.nReaders ++;
479 if (pFile->local.nReaders == 1){
480 pFile->shared->nReaders ++;
481 }
482 bReturn = TRUE;
483 }
484 }
485
486 /* Want a pending lock? */
487 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
488 /* If no pending lock has been acquired, then acquire it */
489 if (pFile->shared->bPending == 0) {
490 pFile->shared->bPending = TRUE;
491 pFile->local.bPending = TRUE;
492 bReturn = TRUE;
493 }
494 }
495 /* Want a reserved lock? */
496 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
497 if (pFile->shared->bReserved == 0) {
498 pFile->shared->bReserved = TRUE;
499 pFile->local.bReserved = TRUE;
500 bReturn = TRUE;
501 }
502 }
503
504 winceMutexRelease(pFile->hMutex);
505 return bReturn;
506}
507
508/*
509** An implementation of the UnlockFile API of windows for wince
510*/
511static BOOL winceUnlockFile(
512 HANDLE *phFile,
513 DWORD dwFileOffsetLow,
514 DWORD dwFileOffsetHigh,
515 DWORD nNumberOfBytesToUnlockLow,
516 DWORD nNumberOfBytesToUnlockHigh
517){
518 winFile *pFile = HANDLE_TO_WINFILE(phFile);
519 BOOL bReturn = FALSE;
520
521 if (!pFile->hMutex) return TRUE;
522 winceMutexAcquire(pFile->hMutex);
523
524 /* Releasing a reader lock or an exclusive lock */
525 if (dwFileOffsetLow >= SHARED_FIRST &&
526 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
527 /* Did we have an exclusive lock? */
528 if (pFile->local.bExclusive){
529 pFile->local.bExclusive = FALSE;
530 pFile->shared->bExclusive = FALSE;
531 bReturn = TRUE;
532 }
533
534 /* Did we just have a reader lock? */
535 else if (pFile->local.nReaders){
536 pFile->local.nReaders --;
537 if (pFile->local.nReaders == 0)
538 {
539 pFile->shared->nReaders --;
540 }
541 bReturn = TRUE;
542 }
543 }
544
545 /* Releasing a pending lock */
546 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
547 if (pFile->local.bPending){
548 pFile->local.bPending = FALSE;
549 pFile->shared->bPending = FALSE;
550 bReturn = TRUE;
551 }
552 }
553 /* Releasing a reserved lock */
554 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
555 if (pFile->local.bReserved) {
556 pFile->local.bReserved = FALSE;
557 pFile->shared->bReserved = FALSE;
558 bReturn = TRUE;
559 }
560 }
561
562 winceMutexRelease(pFile->hMutex);
563 return bReturn;
564}
565
566/*
567** An implementation of the LockFileEx() API of windows for wince
568*/
569static BOOL winceLockFileEx(
570 HANDLE *phFile,
571 DWORD dwFlags,
572 DWORD dwReserved,
573 DWORD nNumberOfBytesToLockLow,
574 DWORD nNumberOfBytesToLockHigh,
575 LPOVERLAPPED lpOverlapped
576){
577 /* If the caller wants a shared read lock, forward this call
578 ** to winceLockFile */
579 if (lpOverlapped->Offset == SHARED_FIRST &&
580 dwFlags == 1 &&
581 nNumberOfBytesToLockLow == SHARED_SIZE){
582 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
583 }
584 return FALSE;
585}
586/*
587** End of the special code for wince
588*****************************************************************************/
danielk197729bafea2008-06-26 10:41:19 +0000589#endif /* SQLITE_OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000590
drh153c62c2007-08-24 03:51:33 +0000591/*****************************************************************************
592** The next group of routines implement the I/O methods specified
593** by the sqlite3_io_methods object.
594******************************************************************************/
drhbbd42a62004-05-22 17:41:58 +0000595
596/*
597** Close a file.
drh59e63a62006-06-04 23:31:48 +0000598**
599** It is reported that an attempt to close a handle might sometimes
600** fail. This is a very unreasonable result, but windows is notorious
601** for being unreasonable so I do not doubt that it might happen. If
602** the close fails, we pause for 100 milliseconds and try again. As
603** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
604** giving up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000605*/
drh59e63a62006-06-04 23:31:48 +0000606#define MX_CLOSE_ATTEMPT 3
drh153c62c2007-08-24 03:51:33 +0000607static int winClose(sqlite3_file *id){
608 int rc, cnt = 0;
609 winFile *pFile = (winFile*)id;
610 OSTRACE2("CLOSE %d\n", pFile->h);
611 do{
612 rc = CloseHandle(pFile->h);
shaned94b0552008-09-30 04:20:07 +0000613 }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
danielk197729bafea2008-06-26 10:41:19 +0000614#if SQLITE_OS_WINCE
drhd641d512008-02-20 00:00:00 +0000615#define WINCE_DELETION_ATTEMPTS 3
drh153c62c2007-08-24 03:51:33 +0000616 winceDestroyLock(pFile);
drh7229ed42007-10-08 12:29:17 +0000617 if( pFile->zDeleteOnClose ){
drhd641d512008-02-20 00:00:00 +0000618 int cnt = 0;
619 while(
620 DeleteFileW(pFile->zDeleteOnClose)==0
621 && GetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
622 && cnt++ < WINCE_DELETION_ATTEMPTS
623 ){
624 Sleep(100); /* Wait a little before trying again */
625 }
drh7229ed42007-10-08 12:29:17 +0000626 free(pFile->zDeleteOnClose);
627 }
drhcc78fea2006-01-06 16:17:05 +0000628#endif
drh153c62c2007-08-24 03:51:33 +0000629 OpenCounter(-1);
drheb4fa522006-06-04 23:02:20 +0000630 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000631}
632
633/*
drh153c62c2007-08-24 03:51:33 +0000634** Some microsoft compilers lack this definition.
635*/
636#ifndef INVALID_SET_FILE_POINTER
637# define INVALID_SET_FILE_POINTER ((DWORD)-1)
638#endif
639
640/*
drhbbd42a62004-05-22 17:41:58 +0000641** Read data from a file into a buffer. Return SQLITE_OK if all
642** bytes were read successfully and SQLITE_IOERR if anything goes
643** wrong.
644*/
drh153c62c2007-08-24 03:51:33 +0000645static int winRead(
646 sqlite3_file *id, /* File to read from */
647 void *pBuf, /* Write content into this buffer */
648 int amt, /* Number of bytes to read */
649 sqlite3_int64 offset /* Begin reading at this offset */
650){
drh1bd10f82008-12-10 21:19:56 +0000651 LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
652 LONG lowerBits = (LONG)(offset & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000653 DWORD rc;
drhbbd42a62004-05-22 17:41:58 +0000654 DWORD got;
drh153c62c2007-08-24 03:51:33 +0000655 winFile *pFile = (winFile*)id;
drh9cbe6352005-11-29 03:13:21 +0000656 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +0000657 SimulateIOError(return SQLITE_IOERR_READ);
drh153c62c2007-08-24 03:51:33 +0000658 OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
659 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
660 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
661 return SQLITE_FULL;
662 }
663 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
drhaedd8922007-01-05 14:38:54 +0000664 return SQLITE_IOERR_READ;
drhbbd42a62004-05-22 17:41:58 +0000665 }
666 if( got==(DWORD)amt ){
667 return SQLITE_OK;
668 }else{
drh4c17c3f2008-11-07 00:06:18 +0000669 /* Unread parts of the buffer must be zero-filled */
drhbafda092007-01-03 23:36:22 +0000670 memset(&((char*)pBuf)[got], 0, amt-got);
drh551b7732006-11-06 21:20:25 +0000671 return SQLITE_IOERR_SHORT_READ;
drhbbd42a62004-05-22 17:41:58 +0000672 }
673}
674
675/*
676** Write data from a buffer into a file. Return SQLITE_OK on success
677** or some other error code on failure.
678*/
drh153c62c2007-08-24 03:51:33 +0000679static int winWrite(
680 sqlite3_file *id, /* File to write into */
681 const void *pBuf, /* The bytes to be written */
682 int amt, /* Number of bytes to write */
683 sqlite3_int64 offset /* Offset into the file to begin writing at */
684){
drh1bd10f82008-12-10 21:19:56 +0000685 LONG upperBits = (LONG)((offset>>32) & 0x7fffffff);
686 LONG lowerBits = (LONG)(offset & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000687 DWORD rc;
drhea678832008-12-10 19:26:22 +0000688 DWORD wrote = 0;
drh153c62c2007-08-24 03:51:33 +0000689 winFile *pFile = (winFile*)id;
drh9cbe6352005-11-29 03:13:21 +0000690 assert( id!=0 );
drh153c62c2007-08-24 03:51:33 +0000691 SimulateIOError(return SQLITE_IOERR_WRITE);
drh59685932006-09-14 13:47:11 +0000692 SimulateDiskfullError(return SQLITE_FULL);
drh153c62c2007-08-24 03:51:33 +0000693 OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
694 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
695 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
696 return SQLITE_FULL;
697 }
drh4c7f9412005-02-03 00:29:47 +0000698 assert( amt>0 );
drh153c62c2007-08-24 03:51:33 +0000699 while(
700 amt>0
701 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
702 && wrote>0
703 ){
drhbbd42a62004-05-22 17:41:58 +0000704 amt -= wrote;
705 pBuf = &((char*)pBuf)[wrote];
706 }
707 if( !rc || amt>(int)wrote ){
708 return SQLITE_FULL;
709 }
710 return SQLITE_OK;
711}
712
713/*
drh153c62c2007-08-24 03:51:33 +0000714** Truncate an open file to a specified size
drhbbdc2b92005-09-19 12:53:18 +0000715*/
drhc51250a2007-09-20 14:39:23 +0000716static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
shanea3465f22008-10-12 02:27:38 +0000717 DWORD rc;
drh1bd10f82008-12-10 21:19:56 +0000718 LONG upperBits = (LONG)((nByte>>32) & 0x7fffffff);
719 LONG lowerBits = (LONG)(nByte & 0xffffffff);
drh153c62c2007-08-24 03:51:33 +0000720 winFile *pFile = (winFile*)id;
721 OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
722 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
shanea3465f22008-10-12 02:27:38 +0000723 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
724 if( INVALID_SET_FILE_POINTER != rc ){
725 /* SetEndOfFile will fail if nByte is negative */
726 if( SetEndOfFile(pFile->h) ){
727 return SQLITE_OK;
728 }
729 }
730 return SQLITE_IOERR_TRUNCATE;
drhbbd42a62004-05-22 17:41:58 +0000731}
732
drhdec6fae2007-09-03 17:02:50 +0000733#ifdef SQLITE_TEST
734/*
735** Count the number of fullsyncs and normal syncs. This is used to test
736** that syncs and fullsyncs are occuring at the right times.
737*/
738int sqlite3_sync_count = 0;
739int sqlite3_fullsync_count = 0;
740#endif
741
drhbbd42a62004-05-22 17:41:58 +0000742/*
743** Make sure all writes to a particular file are committed to disk.
744*/
drh153c62c2007-08-24 03:51:33 +0000745static int winSync(sqlite3_file *id, int flags){
shane18e526c2008-12-10 22:30:24 +0000746#ifndef SQLITE_NO_SYNC
drh153c62c2007-08-24 03:51:33 +0000747 winFile *pFile = (winFile*)id;
shane18e526c2008-12-10 22:30:24 +0000748#else
749 UNUSED_PARAMETER(id);
750#endif
drh153c62c2007-08-24 03:51:33 +0000751 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
drhdec6fae2007-09-03 17:02:50 +0000752#ifdef SQLITE_TEST
753 if( flags & SQLITE_SYNC_FULL ){
754 sqlite3_fullsync_count++;
755 }
756 sqlite3_sync_count++;
757#endif
shane84ca3832008-11-13 18:20:43 +0000758 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
759 ** no-op
760 */
761#ifdef SQLITE_NO_SYNC
762 return SQLITE_OK;
763#else
drh153c62c2007-08-24 03:51:33 +0000764 if( FlushFileBuffers(pFile->h) ){
drhbbd42a62004-05-22 17:41:58 +0000765 return SQLITE_OK;
766 }else{
767 return SQLITE_IOERR;
768 }
shane84ca3832008-11-13 18:20:43 +0000769#endif
drhbbd42a62004-05-22 17:41:58 +0000770}
771
772/*
drhbbd42a62004-05-22 17:41:58 +0000773** Determine the current size of a file in bytes
774*/
drh153c62c2007-08-24 03:51:33 +0000775static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
776 winFile *pFile = (winFile*)id;
drhbbd42a62004-05-22 17:41:58 +0000777 DWORD upperBits, lowerBits;
drh9cce7102007-01-09 17:18:19 +0000778 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh153c62c2007-08-24 03:51:33 +0000779 lowerBits = GetFileSize(pFile->h, &upperBits);
780 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000781 return SQLITE_OK;
782}
783
784/*
drh602bbd32006-01-06 20:22:29 +0000785** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
786*/
787#ifndef LOCKFILE_FAIL_IMMEDIATELY
788# define LOCKFILE_FAIL_IMMEDIATELY 1
789#endif
790
791/*
drh9c105bb2004-10-02 20:38:28 +0000792** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000793** Different API routines are called depending on whether or not this
794** is Win95 or WinNT.
795*/
drh153c62c2007-08-24 03:51:33 +0000796static int getReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000797 int res;
798 if( isNT() ){
799 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000800 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000801 ovlp.OffsetHigh = 0;
802 ovlp.hEvent = 0;
drh153c62c2007-08-24 03:51:33 +0000803 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
804 0, SHARED_SIZE, 0, &ovlp);
shane891adea2008-10-22 16:55:47 +0000805/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
806*/
807#if SQLITE_OS_WINCE==0
drhbbd42a62004-05-22 17:41:58 +0000808 }else{
drh9c105bb2004-10-02 20:38:28 +0000809 int lk;
drh2fa18682008-03-19 14:15:34 +0000810 sqlite3_randomness(sizeof(lk), &lk);
drh1bd10f82008-12-10 21:19:56 +0000811 pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
drh153c62c2007-08-24 03:51:33 +0000812 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000813#endif
drh51c6d962004-06-06 00:42:25 +0000814 }
815 return res;
816}
817
818/*
819** Undo a readlock
820*/
drh054889e2005-11-30 03:20:31 +0000821static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000822 int res;
823 if( isNT() ){
drh054889e2005-11-30 03:20:31 +0000824 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
shane891adea2008-10-22 16:55:47 +0000825/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
826*/
827#if SQLITE_OS_WINCE==0
drh51c6d962004-06-06 00:42:25 +0000828 }else{
drh054889e2005-11-30 03:20:31 +0000829 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000830#endif
drh51c6d962004-06-06 00:42:25 +0000831 }
832 return res;
833}
834
tpoindex9a09a3c2004-12-20 19:01:32 +0000835/*
drhb3e04342004-06-08 00:47:47 +0000836** Lock the file with the lock specified by parameter locktype - one
837** of the following:
838**
839** (1) SHARED_LOCK
840** (2) RESERVED_LOCK
841** (3) PENDING_LOCK
842** (4) EXCLUSIVE_LOCK
843**
844** Sometimes when requesting one lock state, additional lock states
845** are inserted in between. The locking might fail on one of the later
846** transitions leaving the lock state different from what it started but
847** still short of its goal. The following chart shows the allowed
848** transitions and the inserted intermediate states:
849**
850** UNLOCKED -> SHARED
851** SHARED -> RESERVED
852** SHARED -> (PENDING) -> EXCLUSIVE
853** RESERVED -> (PENDING) -> EXCLUSIVE
854** PENDING -> EXCLUSIVE
855**
drh9c06c952005-11-26 00:25:00 +0000856** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +0000857** erases all locks at once and returns us immediately to locking level 0.
858** It is not possible to lower the locking level one step at a time. You
859** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000860*/
drh153c62c2007-08-24 03:51:33 +0000861static int winLock(sqlite3_file *id, int locktype){
drh51c6d962004-06-06 00:42:25 +0000862 int rc = SQLITE_OK; /* Return code from subroutines */
863 int res = 1; /* Result of a windows lock call */
drh153c62c2007-08-24 03:51:33 +0000864 int newLocktype; /* Set pFile->locktype to this value before exiting */
drhe54ca3f2004-06-07 01:52:14 +0000865 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +0000866 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +0000867
drh054889e2005-11-30 03:20:31 +0000868 assert( pFile!=0 );
drh4f0c5872007-03-26 22:05:01 +0000869 OSTRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +0000870 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000871
872 /* If there is already a lock of this type or more restrictive on the
873 ** OsFile, do nothing. Don't use the end_lock: exit path, as
874 ** sqlite3OsEnterMutex() hasn't been called yet.
875 */
drh054889e2005-11-30 03:20:31 +0000876 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +0000877 return SQLITE_OK;
878 }
879
drhb3e04342004-06-08 00:47:47 +0000880 /* Make sure the locking sequence is correct
881 */
drh054889e2005-11-30 03:20:31 +0000882 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000883 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +0000884 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000885
drh51c6d962004-06-06 00:42:25 +0000886 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
887 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
888 ** the PENDING_LOCK byte is temporary.
889 */
drh054889e2005-11-30 03:20:31 +0000890 newLocktype = pFile->locktype;
891 if( pFile->locktype==NO_LOCK
892 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +0000893 ){
drhb3e04342004-06-08 00:47:47 +0000894 int cnt = 3;
drh054889e2005-11-30 03:20:31 +0000895 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000896 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000897 ** held by another reader process who will release it momentarily.
898 */
drh4f0c5872007-03-26 22:05:01 +0000899 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000900 Sleep(1);
901 }
drhe54ca3f2004-06-07 01:52:14 +0000902 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +0000903 }
904
905 /* Acquire a shared lock
906 */
drhb3e04342004-06-08 00:47:47 +0000907 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000908 assert( pFile->locktype==NO_LOCK );
909 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000910 if( res ){
911 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +0000912 }
913 }
914
915 /* Acquire a RESERVED lock
916 */
drhb3e04342004-06-08 00:47:47 +0000917 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000918 assert( pFile->locktype==SHARED_LOCK );
919 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +0000920 if( res ){
921 newLocktype = RESERVED_LOCK;
922 }
923 }
924
925 /* Acquire a PENDING lock
926 */
drhb3e04342004-06-08 00:47:47 +0000927 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000928 newLocktype = PENDING_LOCK;
929 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000930 }
931
932 /* Acquire an EXCLUSIVE lock
933 */
drhe54ca3f2004-06-07 01:52:14 +0000934 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000935 assert( pFile->locktype>=SHARED_LOCK );
936 res = unlockReadLock(pFile);
drh4f0c5872007-03-26 22:05:01 +0000937 OSTRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +0000938 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +0000939 if( res ){
940 newLocktype = EXCLUSIVE_LOCK;
941 }else{
drh4f0c5872007-03-26 22:05:01 +0000942 OSTRACE2("error-code = %d\n", GetLastError());
drh8fea1282007-05-14 12:12:11 +0000943 getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000944 }
945 }
946
947 /* If we are holding a PENDING lock that ought to be released, then
948 ** release it now.
949 */
drhb3e04342004-06-08 00:47:47 +0000950 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000951 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000952 }
953
954 /* Update the state of the lock has held in the file descriptor then
955 ** return the appropriate result code.
956 */
957 if( res ){
drh51c6d962004-06-06 00:42:25 +0000958 rc = SQLITE_OK;
959 }else{
drh4f0c5872007-03-26 22:05:01 +0000960 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +0000961 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +0000962 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +0000963 }
drh1bd10f82008-12-10 21:19:56 +0000964 pFile->locktype = (u8)newLocktype;
drhbbd42a62004-05-22 17:41:58 +0000965 return rc;
966}
967
968/*
drh51c6d962004-06-06 00:42:25 +0000969** This routine checks if there is a RESERVED lock held on the specified
970** file by this or any other process. If such a lock is held, return
971** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +0000972*/
danielk1977861f7452008-06-05 11:39:11 +0000973static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
drhbbd42a62004-05-22 17:41:58 +0000974 int rc;
drh054889e2005-11-30 03:20:31 +0000975 winFile *pFile = (winFile*)id;
976 assert( pFile!=0 );
977 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000978 rc = 1;
drh4f0c5872007-03-26 22:05:01 +0000979 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000980 }else{
drh054889e2005-11-30 03:20:31 +0000981 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000982 if( rc ){
drh054889e2005-11-30 03:20:31 +0000983 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000984 }
drh2ac3ee92004-06-07 16:27:46 +0000985 rc = !rc;
drh4f0c5872007-03-26 22:05:01 +0000986 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000987 }
danielk1977861f7452008-06-05 11:39:11 +0000988 *pResOut = rc;
989 return SQLITE_OK;
drhbbd42a62004-05-22 17:41:58 +0000990}
991
992/*
drha6abd042004-06-09 17:37:22 +0000993** Lower the locking level on file descriptor id to locktype. locktype
994** must be either NO_LOCK or SHARED_LOCK.
995**
996** If the locking level of the file descriptor is already at or below
997** the requested locking level, this routine is a no-op.
998**
drh9c105bb2004-10-02 20:38:28 +0000999** It is not possible for this routine to fail if the second argument
1000** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1001** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +00001002*/
drh153c62c2007-08-24 03:51:33 +00001003static int winUnlock(sqlite3_file *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001004 int type;
drh054889e2005-11-30 03:20:31 +00001005 winFile *pFile = (winFile*)id;
drh153c62c2007-08-24 03:51:33 +00001006 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001007 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001008 assert( locktype<=SHARED_LOCK );
drh4f0c5872007-03-26 22:05:01 +00001009 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
drh054889e2005-11-30 03:20:31 +00001010 pFile->locktype, pFile->sharedLockByte);
1011 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001012 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001013 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1014 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001015 /* This should never happen. We should always be able to
1016 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +00001017 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +00001018 }
drhbbd42a62004-05-22 17:41:58 +00001019 }
drhe54ca3f2004-06-07 01:52:14 +00001020 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001021 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001022 }
drh9c105bb2004-10-02 20:38:28 +00001023 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001024 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001025 }
drhb3e04342004-06-08 00:47:47 +00001026 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001027 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001028 }
drh1bd10f82008-12-10 21:19:56 +00001029 pFile->locktype = (u8)locktype;
drh9c105bb2004-10-02 20:38:28 +00001030 return rc;
drhbbd42a62004-05-22 17:41:58 +00001031}
1032
1033/*
drh9e33c2c2007-08-31 18:34:59 +00001034** Control and query of the open file handle.
drh0ccebe72005-06-07 22:22:50 +00001035*/
drh9e33c2c2007-08-31 18:34:59 +00001036static int winFileControl(sqlite3_file *id, int op, void *pArg){
1037 switch( op ){
1038 case SQLITE_FCNTL_LOCKSTATE: {
1039 *(int*)pArg = ((winFile*)id)->locktype;
1040 return SQLITE_OK;
1041 }
1042 }
drh153c62c2007-08-24 03:51:33 +00001043 return SQLITE_ERROR;
drh9cbe6352005-11-29 03:13:21 +00001044}
1045
1046/*
danielk1977a3d4c882007-03-23 10:08:38 +00001047** Return the sector size in bytes of the underlying block device for
1048** the specified file. This is almost always 512 bytes, but may be
1049** larger for some devices.
1050**
1051** SQLite code assumes this function cannot fail. It also assumes that
1052** if two files are created in the same file-system directory (i.e.
drh85b623f2007-12-13 21:54:09 +00001053** a database and its journal file) that the sector size will be the
danielk1977a3d4c882007-03-23 10:08:38 +00001054** same for both.
1055*/
drh153c62c2007-08-24 03:51:33 +00001056static int winSectorSize(sqlite3_file *id){
shane18e526c2008-12-10 22:30:24 +00001057 UNUSED_PARAMETER(id);
drh3ceeb752007-03-29 18:19:52 +00001058 return SQLITE_DEFAULT_SECTOR_SIZE;
danielk1977a3d4c882007-03-23 10:08:38 +00001059}
1060
1061/*
drh153c62c2007-08-24 03:51:33 +00001062** Return a vector of device characteristics.
drh9c06c952005-11-26 00:25:00 +00001063*/
drh153c62c2007-08-24 03:51:33 +00001064static int winDeviceCharacteristics(sqlite3_file *id){
shane18e526c2008-12-10 22:30:24 +00001065 UNUSED_PARAMETER(id);
drh153c62c2007-08-24 03:51:33 +00001066 return 0;
1067}
1068
1069/*
1070** This vector defines all the methods that can operate on an
1071** sqlite3_file for win32.
1072*/
1073static const sqlite3_io_methods winIoMethod = {
1074 1, /* iVersion */
drh9c06c952005-11-26 00:25:00 +00001075 winClose,
1076 winRead,
1077 winWrite,
drh9c06c952005-11-26 00:25:00 +00001078 winTruncate,
drh054889e2005-11-30 03:20:31 +00001079 winSync,
drh054889e2005-11-30 03:20:31 +00001080 winFileSize,
1081 winLock,
1082 winUnlock,
drh054889e2005-11-30 03:20:31 +00001083 winCheckReservedLock,
drhcc6bb3e2007-08-31 16:11:35 +00001084 winFileControl,
danielk1977a3d4c882007-03-23 10:08:38 +00001085 winSectorSize,
drh153c62c2007-08-24 03:51:33 +00001086 winDeviceCharacteristics
drh9c06c952005-11-26 00:25:00 +00001087};
1088
drh153c62c2007-08-24 03:51:33 +00001089/***************************************************************************
1090** Here ends the I/O methods that form the sqlite3_io_methods object.
1091**
1092** The next block of code implements the VFS methods.
1093****************************************************************************/
1094
drh054889e2005-11-30 03:20:31 +00001095/*
drh153c62c2007-08-24 03:51:33 +00001096** Convert a UTF-8 filename into whatever form the underlying
1097** operating system wants filenames in. Space to hold the result
drhb11caac2007-08-24 17:52:21 +00001098** is obtained from malloc and must be freed by the calling
drh153c62c2007-08-24 03:51:33 +00001099** function.
drh054889e2005-11-30 03:20:31 +00001100*/
drh153c62c2007-08-24 03:51:33 +00001101static void *convertUtf8Filename(const char *zFilename){
1102 void *zConverted = 0;
1103 if( isNT() ){
1104 zConverted = utf8ToUnicode(zFilename);
shane891adea2008-10-22 16:55:47 +00001105/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1106*/
1107#if SQLITE_OS_WINCE==0
drh054889e2005-11-30 03:20:31 +00001108 }else{
drh153c62c2007-08-24 03:51:33 +00001109 zConverted = utf8ToMbcs(zFilename);
shane891adea2008-10-22 16:55:47 +00001110#endif
drh054889e2005-11-30 03:20:31 +00001111 }
drh153c62c2007-08-24 03:51:33 +00001112 /* caller will handle out of memory */
1113 return zConverted;
1114}
1115
1116/*
danielk197717b90b52008-06-06 11:11:25 +00001117** Create a temporary file name in zBuf. zBuf must be big enough to
1118** hold at pVfs->mxPathname characters.
1119*/
1120static int getTempname(int nBuf, char *zBuf){
1121 static char zChars[] =
1122 "abcdefghijklmnopqrstuvwxyz"
1123 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1124 "0123456789";
shane3582c5a2008-07-31 01:34:34 +00001125 size_t i, j;
danielk197717b90b52008-06-06 11:11:25 +00001126 char zTempPath[MAX_PATH+1];
1127 if( sqlite3_temp_directory ){
1128 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1129 }else if( isNT() ){
1130 char *zMulti;
1131 WCHAR zWidePath[MAX_PATH];
1132 GetTempPathW(MAX_PATH-30, zWidePath);
1133 zMulti = unicodeToUtf8(zWidePath);
1134 if( zMulti ){
1135 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1136 free(zMulti);
1137 }else{
1138 return SQLITE_NOMEM;
1139 }
shane891adea2008-10-22 16:55:47 +00001140/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1141** Since the ASCII version of these Windows API do not exist for WINCE,
1142** it's important to not reference them for WINCE builds.
1143*/
1144#if SQLITE_OS_WINCE==0
danielk197717b90b52008-06-06 11:11:25 +00001145 }else{
1146 char *zUtf8;
1147 char zMbcsPath[MAX_PATH];
1148 GetTempPathA(MAX_PATH-30, zMbcsPath);
drh1d298852008-11-18 19:18:52 +00001149 zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
danielk197717b90b52008-06-06 11:11:25 +00001150 if( zUtf8 ){
1151 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1152 free(zUtf8);
1153 }else{
1154 return SQLITE_NOMEM;
1155 }
shane891adea2008-10-22 16:55:47 +00001156#endif
danielk197717b90b52008-06-06 11:11:25 +00001157 }
drhea678832008-12-10 19:26:22 +00001158 for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
danielk197717b90b52008-06-06 11:11:25 +00001159 zTempPath[i] = 0;
1160 sqlite3_snprintf(nBuf-30, zBuf,
1161 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
drhea678832008-12-10 19:26:22 +00001162 j = sqlite3Strlen30(zBuf);
danielk197717b90b52008-06-06 11:11:25 +00001163 sqlite3_randomness(20, &zBuf[j]);
1164 for(i=0; i<20; i++, j++){
1165 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1166 }
1167 zBuf[j] = 0;
1168 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
1169 return SQLITE_OK;
1170}
1171
shane820800d2008-07-22 05:32:03 +00001172/*
1173** The return value of getLastErrorMsg
1174** is zero if the error message fits in the buffer, or non-zero
1175** otherwise (if the message was truncated).
1176*/
1177static int getLastErrorMsg(int nBuf, char *zBuf){
1178 DWORD error = GetLastError();
1179
1180#if SQLITE_OS_WINCE
1181 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
1182#else
1183 /* FormatMessage returns 0 on failure. Otherwise it
1184 ** returns the number of TCHARs written to the output
1185 ** buffer, excluding the terminating null char.
1186 */
1187 if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
1188 NULL,
1189 error,
1190 0,
1191 zBuf,
1192 nBuf-1,
1193 0))
1194 {
1195 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
1196 }
1197#endif
1198
1199 return 0;
1200}
1201
danielk197717b90b52008-06-06 11:11:25 +00001202
1203/*
drh153c62c2007-08-24 03:51:33 +00001204** Open a file.
1205*/
1206static int winOpen(
1207 sqlite3_vfs *pVfs, /* Not used */
1208 const char *zName, /* Name of the file (UTF-8) */
1209 sqlite3_file *id, /* Write the SQLite file handle here */
1210 int flags, /* Open mode flags */
1211 int *pOutFlags /* Status return flags */
1212){
1213 HANDLE h;
1214 DWORD dwDesiredAccess;
1215 DWORD dwShareMode;
1216 DWORD dwCreationDisposition;
1217 DWORD dwFlagsAndAttributes = 0;
shaned94b0552008-09-30 04:20:07 +00001218#if SQLITE_OS_WINCE
1219 int isTemp = 0;
1220#endif
drh153c62c2007-08-24 03:51:33 +00001221 winFile *pFile = (winFile*)id;
danielk197717b90b52008-06-06 11:11:25 +00001222 void *zConverted; /* Filename in OS encoding */
1223 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
1224 char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */
1225
shane18e526c2008-12-10 22:30:24 +00001226 UNUSED_PARAMETER(pVfs);
1227
danielk197717b90b52008-06-06 11:11:25 +00001228 /* If the second argument to this function is NULL, generate a
1229 ** temporary file name to use
1230 */
1231 if( !zUtf8Name ){
1232 int rc = getTempname(MAX_PATH+1, zTmpname);
1233 if( rc!=SQLITE_OK ){
1234 return rc;
1235 }
1236 zUtf8Name = zTmpname;
1237 }
1238
1239 /* Convert the filename to the system encoding. */
1240 zConverted = convertUtf8Filename(zUtf8Name);
drh153c62c2007-08-24 03:51:33 +00001241 if( zConverted==0 ){
1242 return SQLITE_NOMEM;
1243 }
1244
1245 if( flags & SQLITE_OPEN_READWRITE ){
1246 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1247 }else{
1248 dwDesiredAccess = GENERIC_READ;
1249 }
1250 if( flags & SQLITE_OPEN_CREATE ){
1251 dwCreationDisposition = OPEN_ALWAYS;
1252 }else{
1253 dwCreationDisposition = OPEN_EXISTING;
1254 }
1255 if( flags & SQLITE_OPEN_MAIN_DB ){
1256 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1257 }else{
1258 dwShareMode = 0;
1259 }
drh64c1ea62007-12-10 21:11:31 +00001260 if( flags & SQLITE_OPEN_DELETEONCLOSE ){
danielk197729bafea2008-06-26 10:41:19 +00001261#if SQLITE_OS_WINCE
drh0cd1ea52007-10-08 15:06:03 +00001262 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
shaned94b0552008-09-30 04:20:07 +00001263 isTemp = 1;
drh0cd1ea52007-10-08 15:06:03 +00001264#else
drh153c62c2007-08-24 03:51:33 +00001265 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
1266 | FILE_ATTRIBUTE_HIDDEN
1267 | FILE_FLAG_DELETE_ON_CLOSE;
drh0cd1ea52007-10-08 15:06:03 +00001268#endif
drh153c62c2007-08-24 03:51:33 +00001269 }else{
1270 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
1271 }
drh496936c2007-10-08 12:21:10 +00001272 /* Reports from the internet are that performance is always
1273 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
shaned94b0552008-09-30 04:20:07 +00001274#if SQLITE_OS_WINCE
drh496936c2007-10-08 12:21:10 +00001275 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
shaned94b0552008-09-30 04:20:07 +00001276#endif
drh153c62c2007-08-24 03:51:33 +00001277 if( isNT() ){
1278 h = CreateFileW((WCHAR*)zConverted,
1279 dwDesiredAccess,
1280 dwShareMode,
1281 NULL,
1282 dwCreationDisposition,
1283 dwFlagsAndAttributes,
1284 NULL
1285 );
shane891adea2008-10-22 16:55:47 +00001286/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1287** Since the ASCII version of these Windows API do not exist for WINCE,
1288** it's important to not reference them for WINCE builds.
1289*/
1290#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001291 }else{
drh153c62c2007-08-24 03:51:33 +00001292 h = CreateFileA((char*)zConverted,
1293 dwDesiredAccess,
1294 dwShareMode,
1295 NULL,
1296 dwCreationDisposition,
1297 dwFlagsAndAttributes,
1298 NULL
1299 );
shane891adea2008-10-22 16:55:47 +00001300#endif
drh153c62c2007-08-24 03:51:33 +00001301 }
1302 if( h==INVALID_HANDLE_VALUE ){
drhe1843af2007-08-30 16:46:04 +00001303 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001304 if( flags & SQLITE_OPEN_READWRITE ){
drh153c62c2007-08-24 03:51:33 +00001305 return winOpen(0, zName, id,
1306 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
1307 }else{
1308 return SQLITE_CANTOPEN;
1309 }
1310 }
1311 if( pOutFlags ){
1312 if( flags & SQLITE_OPEN_READWRITE ){
1313 *pOutFlags = SQLITE_OPEN_READWRITE;
1314 }else{
1315 *pOutFlags = SQLITE_OPEN_READONLY;
1316 }
1317 }
1318 memset(pFile, 0, sizeof(*pFile));
1319 pFile->pMethod = &winIoMethod;
1320 pFile->h = h;
danielk197729bafea2008-06-26 10:41:19 +00001321#if SQLITE_OS_WINCE
drh153c62c2007-08-24 03:51:33 +00001322 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
1323 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
drhaab2e6d2007-10-08 12:22:57 +00001324 && !winceCreateLock(zName, pFile)
drh153c62c2007-08-24 03:51:33 +00001325 ){
1326 CloseHandle(h);
drhb11caac2007-08-24 17:52:21 +00001327 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001328 return SQLITE_CANTOPEN;
1329 }
drhfc3afb62007-10-09 15:36:10 +00001330 if( isTemp ){
drh153c62c2007-08-24 03:51:33 +00001331 pFile->zDeleteOnClose = zConverted;
1332 }else
1333#endif
1334 {
drhb11caac2007-08-24 17:52:21 +00001335 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001336 }
drhaf5f0402007-09-03 17:09:03 +00001337 OpenCounter(+1);
drh153c62c2007-08-24 03:51:33 +00001338 return SQLITE_OK;
1339}
1340
1341/*
1342** Delete the named file.
1343**
1344** Note that windows does not allow a file to be deleted if some other
1345** process has it open. Sometimes a virus scanner or indexing program
1346** will open a journal file shortly after it is created in order to do
shane3582c5a2008-07-31 01:34:34 +00001347** whatever it does. While this other process is holding the
drh153c62c2007-08-24 03:51:33 +00001348** file open, we will be unable to delete it. To work around this
1349** problem, we delay 100 milliseconds and try to delete again. Up
1350** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
1351** up and returning an error.
1352*/
drhf024f0b2007-11-07 01:19:07 +00001353#define MX_DELETION_ATTEMPTS 5
drh153c62c2007-08-24 03:51:33 +00001354static int winDelete(
1355 sqlite3_vfs *pVfs, /* Not used on win32 */
1356 const char *zFilename, /* Name of file to delete */
1357 int syncDir /* Not used on win32 */
1358){
1359 int cnt = 0;
shaned94b0552008-09-30 04:20:07 +00001360 DWORD rc;
drhea678832008-12-10 19:26:22 +00001361 DWORD error = 0;
drh153c62c2007-08-24 03:51:33 +00001362 void *zConverted = convertUtf8Filename(zFilename);
shane18e526c2008-12-10 22:30:24 +00001363 UNUSED_PARAMETER(pVfs);
1364 UNUSED_PARAMETER(syncDir);
drh153c62c2007-08-24 03:51:33 +00001365 if( zConverted==0 ){
1366 return SQLITE_NOMEM;
1367 }
1368 SimulateIOError(return SQLITE_IOERR_DELETE);
1369 if( isNT() ){
1370 do{
drhf024f0b2007-11-07 01:19:07 +00001371 DeleteFileW(zConverted);
shane3582c5a2008-07-31 01:34:34 +00001372 }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
1373 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00001374 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00001375 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00001376/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1377** Since the ASCII version of these Windows API do not exist for WINCE,
1378** it's important to not reference them for WINCE builds.
1379*/
1380#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001381 }else{
drh153c62c2007-08-24 03:51:33 +00001382 do{
drhf024f0b2007-11-07 01:19:07 +00001383 DeleteFileA(zConverted);
shane3582c5a2008-07-31 01:34:34 +00001384 }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
1385 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00001386 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00001387 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00001388#endif
drh153c62c2007-08-24 03:51:33 +00001389 }
drhb11caac2007-08-24 17:52:21 +00001390 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001391 OSTRACE2("DELETE \"%s\"\n", zFilename);
shaned94b0552008-09-30 04:20:07 +00001392 return ( (rc == INVALID_FILE_ATTRIBUTES)
shane3582c5a2008-07-31 01:34:34 +00001393 && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
drh153c62c2007-08-24 03:51:33 +00001394}
1395
1396/*
1397** Check the existance and status of a file.
1398*/
1399static int winAccess(
1400 sqlite3_vfs *pVfs, /* Not used on win32 */
1401 const char *zFilename, /* Name of file to check */
danielk1977861f7452008-06-05 11:39:11 +00001402 int flags, /* Type of test to make on this file */
1403 int *pResOut /* OUT: Result */
drh153c62c2007-08-24 03:51:33 +00001404){
1405 DWORD attr;
drhea678832008-12-10 19:26:22 +00001406 int rc = 0;
drh153c62c2007-08-24 03:51:33 +00001407 void *zConverted = convertUtf8Filename(zFilename);
shane18e526c2008-12-10 22:30:24 +00001408 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001409 if( zConverted==0 ){
1410 return SQLITE_NOMEM;
1411 }
1412 if( isNT() ){
1413 attr = GetFileAttributesW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00001414/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1415** Since the ASCII version of these Windows API do not exist for WINCE,
1416** it's important to not reference them for WINCE builds.
1417*/
1418#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001419 }else{
drh153c62c2007-08-24 03:51:33 +00001420 attr = GetFileAttributesA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00001421#endif
drh153c62c2007-08-24 03:51:33 +00001422 }
drhb11caac2007-08-24 17:52:21 +00001423 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001424 switch( flags ){
drh50d3f902007-08-27 21:10:36 +00001425 case SQLITE_ACCESS_READ:
drh153c62c2007-08-24 03:51:33 +00001426 case SQLITE_ACCESS_EXISTS:
shane820800d2008-07-22 05:32:03 +00001427 rc = attr!=INVALID_FILE_ATTRIBUTES;
drh153c62c2007-08-24 03:51:33 +00001428 break;
1429 case SQLITE_ACCESS_READWRITE:
1430 rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
1431 break;
drh153c62c2007-08-24 03:51:33 +00001432 default:
1433 assert(!"Invalid flags argument");
1434 }
danielk1977861f7452008-06-05 11:39:11 +00001435 *pResOut = rc;
1436 return SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001437}
1438
1439
drh153c62c2007-08-24 03:51:33 +00001440/*
drh153c62c2007-08-24 03:51:33 +00001441** Turn a relative pathname into a full pathname. Write the full
1442** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
1443** bytes in size.
1444*/
1445static int winFullPathname(
danielk1977adfb9b02007-09-17 07:02:56 +00001446 sqlite3_vfs *pVfs, /* Pointer to vfs object */
1447 const char *zRelative, /* Possibly relative input path */
1448 int nFull, /* Size of output buffer in bytes */
1449 char *zFull /* Output buffer */
drh153c62c2007-08-24 03:51:33 +00001450){
drh1bd10f82008-12-10 21:19:56 +00001451
drh153c62c2007-08-24 03:51:33 +00001452#if defined(__CYGWIN__)
shane18e526c2008-12-10 22:30:24 +00001453 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00001454 cygwin_conv_to_full_win32_path(zRelative, zFull);
danielk1977076f1c02007-09-12 14:09:23 +00001455 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001456#endif
1457
danielk197729bafea2008-06-26 10:41:19 +00001458#if SQLITE_OS_WINCE
shane18e526c2008-12-10 22:30:24 +00001459 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00001460 /* WinCE has no concept of a relative pathname, or so I am told. */
1461 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
drhe8256092007-10-09 15:20:39 +00001462 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001463#endif
1464
danielk197729bafea2008-06-26 10:41:19 +00001465#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
drh153c62c2007-08-24 03:51:33 +00001466 int nByte;
1467 void *zConverted;
1468 char *zOut;
shane18e526c2008-12-10 22:30:24 +00001469 UNUSED_PARAMETER(nFull);
drh153c62c2007-08-24 03:51:33 +00001470 zConverted = convertUtf8Filename(zRelative);
1471 if( isNT() ){
1472 WCHAR *zTemp;
1473 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001474 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001475 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001476 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001477 return SQLITE_NOMEM;
1478 }
1479 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001480 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001481 zOut = unicodeToUtf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001482 free(zTemp);
shane891adea2008-10-22 16:55:47 +00001483/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1484** Since the ASCII version of these Windows API do not exist for WINCE,
1485** it's important to not reference them for WINCE builds.
1486*/
1487#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001488 }else{
1489 char *zTemp;
1490 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001491 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001492 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001493 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001494 return SQLITE_NOMEM;
1495 }
1496 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001497 free(zConverted);
drh1d298852008-11-18 19:18:52 +00001498 zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001499 free(zTemp);
shane891adea2008-10-22 16:55:47 +00001500#endif
drh153c62c2007-08-24 03:51:33 +00001501 }
1502 if( zOut ){
drhb11caac2007-08-24 17:52:21 +00001503 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
1504 free(zOut);
drh153c62c2007-08-24 03:51:33 +00001505 return SQLITE_OK;
1506 }else{
1507 return SQLITE_NOMEM;
1508 }
1509#endif
1510}
1511
1512#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh761df872006-12-21 01:29:22 +00001513/*
1514** Interfaces for opening a shared library, finding entry points
1515** within the shared library, and closing the shared library.
1516*/
drh153c62c2007-08-24 03:51:33 +00001517/*
1518** Interfaces for opening a shared library, finding entry points
1519** within the shared library, and closing the shared library.
1520*/
1521static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
drh761df872006-12-21 01:29:22 +00001522 HANDLE h;
1523 void *zConverted = convertUtf8Filename(zFilename);
drh1bd10f82008-12-10 21:19:56 +00001524 UNUSED_PARAMETER(pVfs);
drh761df872006-12-21 01:29:22 +00001525 if( zConverted==0 ){
1526 return 0;
1527 }
1528 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00001529 h = LoadLibraryW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00001530/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1531** Since the ASCII version of these Windows API do not exist for WINCE,
1532** it's important to not reference them for WINCE builds.
1533*/
1534#if SQLITE_OS_WINCE==0
drh761df872006-12-21 01:29:22 +00001535 }else{
drh584c0942006-12-21 03:20:40 +00001536 h = LoadLibraryA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00001537#endif
drh761df872006-12-21 01:29:22 +00001538 }
drhb11caac2007-08-24 17:52:21 +00001539 free(zConverted);
drh761df872006-12-21 01:29:22 +00001540 return (void*)h;
drh761df872006-12-21 01:29:22 +00001541}
drh153c62c2007-08-24 03:51:33 +00001542static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
drh1bd10f82008-12-10 21:19:56 +00001543 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00001544 getLastErrorMsg(nBuf, zBufOut);
drh153c62c2007-08-24 03:51:33 +00001545}
drh1875f7a2008-12-08 18:19:17 +00001546void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
drh1bd10f82008-12-10 21:19:56 +00001547 UNUSED_PARAMETER(pVfs);
danielk197729bafea2008-06-26 10:41:19 +00001548#if SQLITE_OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00001549 /* The GetProcAddressA() routine is only available on wince. */
drh1875f7a2008-12-08 18:19:17 +00001550 return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001551#else
1552 /* All other windows platforms expect GetProcAddress() to take
1553 ** an Ansi string regardless of the _UNICODE setting */
drh1875f7a2008-12-08 18:19:17 +00001554 return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001555#endif
drh761df872006-12-21 01:29:22 +00001556}
drh153c62c2007-08-24 03:51:33 +00001557void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh1bd10f82008-12-10 21:19:56 +00001558 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001559 FreeLibrary((HANDLE)pHandle);
drh761df872006-12-21 01:29:22 +00001560}
drh153c62c2007-08-24 03:51:33 +00001561#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
1562 #define winDlOpen 0
1563 #define winDlError 0
1564 #define winDlSym 0
1565 #define winDlClose 0
1566#endif
1567
drh761df872006-12-21 01:29:22 +00001568
drh0ccebe72005-06-07 22:22:50 +00001569/*
drh153c62c2007-08-24 03:51:33 +00001570** Write up to nBuf bytes of randomness into zBuf.
drhbbd42a62004-05-22 17:41:58 +00001571*/
drh153c62c2007-08-24 03:51:33 +00001572static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drhd1a79312007-09-03 13:06:11 +00001573 int n = 0;
shanec7b7f1a2008-11-19 21:35:46 +00001574 UNUSED_PARAMETER(pVfs);
1575#if defined(SQLITE_TEST)
1576 n = nBuf;
1577 memset(zBuf, 0, nBuf);
1578#else
drh86742612007-09-05 17:06:03 +00001579 if( sizeof(SYSTEMTIME)<=nBuf-n ){
drhd1a79312007-09-03 13:06:11 +00001580 SYSTEMTIME x;
1581 GetSystemTime(&x);
1582 memcpy(&zBuf[n], &x, sizeof(x));
1583 n += sizeof(x);
drh153c62c2007-08-24 03:51:33 +00001584 }
drhd1a79312007-09-03 13:06:11 +00001585 if( sizeof(DWORD)<=nBuf-n ){
1586 DWORD pid = GetCurrentProcessId();
1587 memcpy(&zBuf[n], &pid, sizeof(pid));
1588 n += sizeof(pid);
1589 }
1590 if( sizeof(DWORD)<=nBuf-n ){
1591 DWORD cnt = GetTickCount();
1592 memcpy(&zBuf[n], &cnt, sizeof(cnt));
1593 n += sizeof(cnt);
1594 }
1595 if( sizeof(LARGE_INTEGER)<=nBuf-n ){
1596 LARGE_INTEGER i;
1597 QueryPerformanceCounter(&i);
1598 memcpy(&zBuf[n], &i, sizeof(i));
1599 n += sizeof(i);
1600 }
shanec7b7f1a2008-11-19 21:35:46 +00001601#endif
drhd1a79312007-09-03 13:06:11 +00001602 return n;
drhbbd42a62004-05-22 17:41:58 +00001603}
1604
drh153c62c2007-08-24 03:51:33 +00001605
drhbbd42a62004-05-22 17:41:58 +00001606/*
1607** Sleep for a little while. Return the amount of time slept.
1608*/
drh153c62c2007-08-24 03:51:33 +00001609static int winSleep(sqlite3_vfs *pVfs, int microsec){
1610 Sleep((microsec+999)/1000);
drh1bd10f82008-12-10 21:19:56 +00001611 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001612 return ((microsec+999)/1000)*1000;
drhbbd42a62004-05-22 17:41:58 +00001613}
1614
1615/*
drhbbd42a62004-05-22 17:41:58 +00001616** The following variable, if set to a non-zero value, becomes the result
1617** returned from sqlite3OsCurrentTime(). This is used for testing.
1618*/
1619#ifdef SQLITE_TEST
1620int sqlite3_current_time = 0;
1621#endif
1622
1623/*
1624** Find the current time (in Universal Coordinated Time). Write the
1625** current time and date as a Julian Day number into *prNow and
1626** return 0. Return 1 if the time and date cannot be found.
1627*/
drh153c62c2007-08-24 03:51:33 +00001628int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001629 FILETIME ft;
1630 /* FILETIME structure is a 64-bit value representing the number of
1631 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1632 */
1633 double now;
danielk197729bafea2008-06-26 10:41:19 +00001634#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +00001635 SYSTEMTIME time;
1636 GetSystemTime(&time);
shane820800d2008-07-22 05:32:03 +00001637 /* if SystemTimeToFileTime() fails, it returns zero. */
1638 if (!SystemTimeToFileTime(&time,&ft)){
1639 return 1;
1640 }
drhcc78fea2006-01-06 16:17:05 +00001641#else
drhbbd42a62004-05-22 17:41:58 +00001642 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001643#endif
drh1bd10f82008-12-10 21:19:56 +00001644 UNUSED_PARAMETER(pVfs);
drhbbd42a62004-05-22 17:41:58 +00001645 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1646 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1647#ifdef SQLITE_TEST
1648 if( sqlite3_current_time ){
1649 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1650 }
1651#endif
1652 return 0;
1653}
1654
shane820800d2008-07-22 05:32:03 +00001655/*
1656** The idea is that this function works like a combination of
1657** GetLastError() and FormatMessage() on windows (or errno and
1658** strerror_r() on unix). After an error is returned by an OS
1659** function, SQLite calls this function with zBuf pointing to
1660** a buffer of nBuf bytes. The OS layer should populate the
1661** buffer with a nul-terminated UTF-8 encoded error message
1662** describing the last IO error to have occured within the calling
1663** thread.
1664**
1665** If the error message is too large for the supplied buffer,
1666** it should be truncated. The return value of xGetLastError
1667** is zero if the error message fits in the buffer, or non-zero
1668** otherwise (if the message was truncated). If non-zero is returned,
1669** then it is not necessary to include the nul-terminator character
1670** in the output buffer.
1671**
1672** Not supplying an error message will have no adverse effect
1673** on SQLite. It is fine to have an implementation that never
1674** returns an error message:
1675**
1676** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
1677** assert(zBuf[0]=='\0');
1678** return 0;
1679** }
1680**
1681** However if an error message is supplied, it will be incorporated
1682** by sqlite into the error message available to the user using
1683** sqlite3_errmsg(), possibly making IO errors easier to debug.
1684*/
danielk1977bcb97fe2008-06-06 15:49:29 +00001685static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drh1bd10f82008-12-10 21:19:56 +00001686 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00001687 return getLastErrorMsg(nBuf, zBuf);
danielk1977bcb97fe2008-06-06 15:49:29 +00001688}
drhb4bc7052006-01-11 23:40:33 +00001689
1690/*
danielk1977c0fa4c52008-06-25 17:19:00 +00001691** Initialize and deinitialize the operating system interface.
danielk197713a68c32005-12-15 10:11:30 +00001692*/
danielk1977c0fa4c52008-06-25 17:19:00 +00001693int sqlite3_os_init(void){
drh153c62c2007-08-24 03:51:33 +00001694 static sqlite3_vfs winVfs = {
1695 1, /* iVersion */
1696 sizeof(winFile), /* szOsFile */
1697 MAX_PATH, /* mxPathname */
drh153c62c2007-08-24 03:51:33 +00001698 0, /* pNext */
1699 "win32", /* zName */
1700 0, /* pAppData */
danielk1977bcb97fe2008-06-06 15:49:29 +00001701
drh153c62c2007-08-24 03:51:33 +00001702 winOpen, /* xOpen */
1703 winDelete, /* xDelete */
1704 winAccess, /* xAccess */
drh153c62c2007-08-24 03:51:33 +00001705 winFullPathname, /* xFullPathname */
1706 winDlOpen, /* xDlOpen */
1707 winDlError, /* xDlError */
1708 winDlSym, /* xDlSym */
1709 winDlClose, /* xDlClose */
1710 winRandomness, /* xRandomness */
1711 winSleep, /* xSleep */
danielk1977bcb97fe2008-06-06 15:49:29 +00001712 winCurrentTime, /* xCurrentTime */
1713 winGetLastError /* xGetLastError */
drh153c62c2007-08-24 03:51:33 +00001714 };
danielk1977c0fa4c52008-06-25 17:19:00 +00001715 sqlite3_vfs_register(&winVfs, 1);
1716 return SQLITE_OK;
danielk197713a68c32005-12-15 10:11:30 +00001717}
danielk1977c0fa4c52008-06-25 17:19:00 +00001718int sqlite3_os_end(void){
1719 return SQLITE_OK;
1720}
drh40257ff2008-06-13 18:24:27 +00001721
danielk197729bafea2008-06-26 10:41:19 +00001722#endif /* SQLITE_OS_WIN */