blob: 90791c7920b5aaa0ad6ac37c4c1d7d2ddb35872e [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**
drh1bd10f82008-12-10 21:19:56 +000015** $Id: os_win.c,v 1.143 2008/12/10 21:19:57 drh 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){
746 winFile *pFile = (winFile*)id;
747 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
drhdec6fae2007-09-03 17:02:50 +0000748#ifdef SQLITE_TEST
749 if( flags & SQLITE_SYNC_FULL ){
750 sqlite3_fullsync_count++;
751 }
752 sqlite3_sync_count++;
753#endif
shane84ca3832008-11-13 18:20:43 +0000754 /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
755 ** no-op
756 */
757#ifdef SQLITE_NO_SYNC
758 return SQLITE_OK;
759#else
drh153c62c2007-08-24 03:51:33 +0000760 if( FlushFileBuffers(pFile->h) ){
drhbbd42a62004-05-22 17:41:58 +0000761 return SQLITE_OK;
762 }else{
763 return SQLITE_IOERR;
764 }
shane84ca3832008-11-13 18:20:43 +0000765#endif
drhbbd42a62004-05-22 17:41:58 +0000766}
767
768/*
drhbbd42a62004-05-22 17:41:58 +0000769** Determine the current size of a file in bytes
770*/
drh153c62c2007-08-24 03:51:33 +0000771static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
772 winFile *pFile = (winFile*)id;
drhbbd42a62004-05-22 17:41:58 +0000773 DWORD upperBits, lowerBits;
drh9cce7102007-01-09 17:18:19 +0000774 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh153c62c2007-08-24 03:51:33 +0000775 lowerBits = GetFileSize(pFile->h, &upperBits);
776 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000777 return SQLITE_OK;
778}
779
780/*
drh602bbd32006-01-06 20:22:29 +0000781** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
782*/
783#ifndef LOCKFILE_FAIL_IMMEDIATELY
784# define LOCKFILE_FAIL_IMMEDIATELY 1
785#endif
786
787/*
drh9c105bb2004-10-02 20:38:28 +0000788** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000789** Different API routines are called depending on whether or not this
790** is Win95 or WinNT.
791*/
drh153c62c2007-08-24 03:51:33 +0000792static int getReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000793 int res;
794 if( isNT() ){
795 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000796 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000797 ovlp.OffsetHigh = 0;
798 ovlp.hEvent = 0;
drh153c62c2007-08-24 03:51:33 +0000799 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
800 0, SHARED_SIZE, 0, &ovlp);
shane891adea2008-10-22 16:55:47 +0000801/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
802*/
803#if SQLITE_OS_WINCE==0
drhbbd42a62004-05-22 17:41:58 +0000804 }else{
drh9c105bb2004-10-02 20:38:28 +0000805 int lk;
drh2fa18682008-03-19 14:15:34 +0000806 sqlite3_randomness(sizeof(lk), &lk);
drh1bd10f82008-12-10 21:19:56 +0000807 pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
drh153c62c2007-08-24 03:51:33 +0000808 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000809#endif
drh51c6d962004-06-06 00:42:25 +0000810 }
811 return res;
812}
813
814/*
815** Undo a readlock
816*/
drh054889e2005-11-30 03:20:31 +0000817static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000818 int res;
819 if( isNT() ){
drh054889e2005-11-30 03:20:31 +0000820 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
shane891adea2008-10-22 16:55:47 +0000821/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
822*/
823#if SQLITE_OS_WINCE==0
drh51c6d962004-06-06 00:42:25 +0000824 }else{
drh054889e2005-11-30 03:20:31 +0000825 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
shane891adea2008-10-22 16:55:47 +0000826#endif
drh51c6d962004-06-06 00:42:25 +0000827 }
828 return res;
829}
830
tpoindex9a09a3c2004-12-20 19:01:32 +0000831/*
drhb3e04342004-06-08 00:47:47 +0000832** Lock the file with the lock specified by parameter locktype - one
833** of the following:
834**
835** (1) SHARED_LOCK
836** (2) RESERVED_LOCK
837** (3) PENDING_LOCK
838** (4) EXCLUSIVE_LOCK
839**
840** Sometimes when requesting one lock state, additional lock states
841** are inserted in between. The locking might fail on one of the later
842** transitions leaving the lock state different from what it started but
843** still short of its goal. The following chart shows the allowed
844** transitions and the inserted intermediate states:
845**
846** UNLOCKED -> SHARED
847** SHARED -> RESERVED
848** SHARED -> (PENDING) -> EXCLUSIVE
849** RESERVED -> (PENDING) -> EXCLUSIVE
850** PENDING -> EXCLUSIVE
851**
drh9c06c952005-11-26 00:25:00 +0000852** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +0000853** erases all locks at once and returns us immediately to locking level 0.
854** It is not possible to lower the locking level one step at a time. You
855** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000856*/
drh153c62c2007-08-24 03:51:33 +0000857static int winLock(sqlite3_file *id, int locktype){
drh51c6d962004-06-06 00:42:25 +0000858 int rc = SQLITE_OK; /* Return code from subroutines */
859 int res = 1; /* Result of a windows lock call */
drh153c62c2007-08-24 03:51:33 +0000860 int newLocktype; /* Set pFile->locktype to this value before exiting */
drhe54ca3f2004-06-07 01:52:14 +0000861 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +0000862 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +0000863
drh054889e2005-11-30 03:20:31 +0000864 assert( pFile!=0 );
drh4f0c5872007-03-26 22:05:01 +0000865 OSTRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +0000866 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000867
868 /* If there is already a lock of this type or more restrictive on the
869 ** OsFile, do nothing. Don't use the end_lock: exit path, as
870 ** sqlite3OsEnterMutex() hasn't been called yet.
871 */
drh054889e2005-11-30 03:20:31 +0000872 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +0000873 return SQLITE_OK;
874 }
875
drhb3e04342004-06-08 00:47:47 +0000876 /* Make sure the locking sequence is correct
877 */
drh054889e2005-11-30 03:20:31 +0000878 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000879 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +0000880 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000881
drh51c6d962004-06-06 00:42:25 +0000882 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
883 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
884 ** the PENDING_LOCK byte is temporary.
885 */
drh054889e2005-11-30 03:20:31 +0000886 newLocktype = pFile->locktype;
887 if( pFile->locktype==NO_LOCK
888 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +0000889 ){
drhb3e04342004-06-08 00:47:47 +0000890 int cnt = 3;
drh054889e2005-11-30 03:20:31 +0000891 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000892 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000893 ** held by another reader process who will release it momentarily.
894 */
drh4f0c5872007-03-26 22:05:01 +0000895 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000896 Sleep(1);
897 }
drhe54ca3f2004-06-07 01:52:14 +0000898 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +0000899 }
900
901 /* Acquire a shared lock
902 */
drhb3e04342004-06-08 00:47:47 +0000903 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000904 assert( pFile->locktype==NO_LOCK );
905 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000906 if( res ){
907 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +0000908 }
909 }
910
911 /* Acquire a RESERVED lock
912 */
drhb3e04342004-06-08 00:47:47 +0000913 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000914 assert( pFile->locktype==SHARED_LOCK );
915 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +0000916 if( res ){
917 newLocktype = RESERVED_LOCK;
918 }
919 }
920
921 /* Acquire a PENDING lock
922 */
drhb3e04342004-06-08 00:47:47 +0000923 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000924 newLocktype = PENDING_LOCK;
925 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000926 }
927
928 /* Acquire an EXCLUSIVE lock
929 */
drhe54ca3f2004-06-07 01:52:14 +0000930 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000931 assert( pFile->locktype>=SHARED_LOCK );
932 res = unlockReadLock(pFile);
drh4f0c5872007-03-26 22:05:01 +0000933 OSTRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +0000934 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +0000935 if( res ){
936 newLocktype = EXCLUSIVE_LOCK;
937 }else{
drh4f0c5872007-03-26 22:05:01 +0000938 OSTRACE2("error-code = %d\n", GetLastError());
drh8fea1282007-05-14 12:12:11 +0000939 getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000940 }
941 }
942
943 /* If we are holding a PENDING lock that ought to be released, then
944 ** release it now.
945 */
drhb3e04342004-06-08 00:47:47 +0000946 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000947 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000948 }
949
950 /* Update the state of the lock has held in the file descriptor then
951 ** return the appropriate result code.
952 */
953 if( res ){
drh51c6d962004-06-06 00:42:25 +0000954 rc = SQLITE_OK;
955 }else{
drh4f0c5872007-03-26 22:05:01 +0000956 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +0000957 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +0000958 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +0000959 }
drh1bd10f82008-12-10 21:19:56 +0000960 pFile->locktype = (u8)newLocktype;
drhbbd42a62004-05-22 17:41:58 +0000961 return rc;
962}
963
964/*
drh51c6d962004-06-06 00:42:25 +0000965** This routine checks if there is a RESERVED lock held on the specified
966** file by this or any other process. If such a lock is held, return
967** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +0000968*/
danielk1977861f7452008-06-05 11:39:11 +0000969static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
drhbbd42a62004-05-22 17:41:58 +0000970 int rc;
drh054889e2005-11-30 03:20:31 +0000971 winFile *pFile = (winFile*)id;
972 assert( pFile!=0 );
973 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000974 rc = 1;
drh4f0c5872007-03-26 22:05:01 +0000975 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000976 }else{
drh054889e2005-11-30 03:20:31 +0000977 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000978 if( rc ){
drh054889e2005-11-30 03:20:31 +0000979 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000980 }
drh2ac3ee92004-06-07 16:27:46 +0000981 rc = !rc;
drh4f0c5872007-03-26 22:05:01 +0000982 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000983 }
danielk1977861f7452008-06-05 11:39:11 +0000984 *pResOut = rc;
985 return SQLITE_OK;
drhbbd42a62004-05-22 17:41:58 +0000986}
987
988/*
drha6abd042004-06-09 17:37:22 +0000989** Lower the locking level on file descriptor id to locktype. locktype
990** must be either NO_LOCK or SHARED_LOCK.
991**
992** If the locking level of the file descriptor is already at or below
993** the requested locking level, this routine is a no-op.
994**
drh9c105bb2004-10-02 20:38:28 +0000995** It is not possible for this routine to fail if the second argument
996** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
997** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000998*/
drh153c62c2007-08-24 03:51:33 +0000999static int winUnlock(sqlite3_file *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001000 int type;
drh054889e2005-11-30 03:20:31 +00001001 winFile *pFile = (winFile*)id;
drh153c62c2007-08-24 03:51:33 +00001002 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001003 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001004 assert( locktype<=SHARED_LOCK );
drh4f0c5872007-03-26 22:05:01 +00001005 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
drh054889e2005-11-30 03:20:31 +00001006 pFile->locktype, pFile->sharedLockByte);
1007 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001008 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001009 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1010 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001011 /* This should never happen. We should always be able to
1012 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +00001013 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +00001014 }
drhbbd42a62004-05-22 17:41:58 +00001015 }
drhe54ca3f2004-06-07 01:52:14 +00001016 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001017 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001018 }
drh9c105bb2004-10-02 20:38:28 +00001019 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001020 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001021 }
drhb3e04342004-06-08 00:47:47 +00001022 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001023 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001024 }
drh1bd10f82008-12-10 21:19:56 +00001025 pFile->locktype = (u8)locktype;
drh9c105bb2004-10-02 20:38:28 +00001026 return rc;
drhbbd42a62004-05-22 17:41:58 +00001027}
1028
1029/*
drh9e33c2c2007-08-31 18:34:59 +00001030** Control and query of the open file handle.
drh0ccebe72005-06-07 22:22:50 +00001031*/
drh9e33c2c2007-08-31 18:34:59 +00001032static int winFileControl(sqlite3_file *id, int op, void *pArg){
1033 switch( op ){
1034 case SQLITE_FCNTL_LOCKSTATE: {
1035 *(int*)pArg = ((winFile*)id)->locktype;
1036 return SQLITE_OK;
1037 }
1038 }
drh153c62c2007-08-24 03:51:33 +00001039 return SQLITE_ERROR;
drh9cbe6352005-11-29 03:13:21 +00001040}
1041
1042/*
danielk1977a3d4c882007-03-23 10:08:38 +00001043** Return the sector size in bytes of the underlying block device for
1044** the specified file. This is almost always 512 bytes, but may be
1045** larger for some devices.
1046**
1047** SQLite code assumes this function cannot fail. It also assumes that
1048** if two files are created in the same file-system directory (i.e.
drh85b623f2007-12-13 21:54:09 +00001049** a database and its journal file) that the sector size will be the
danielk1977a3d4c882007-03-23 10:08:38 +00001050** same for both.
1051*/
drh153c62c2007-08-24 03:51:33 +00001052static int winSectorSize(sqlite3_file *id){
drh3ceeb752007-03-29 18:19:52 +00001053 return SQLITE_DEFAULT_SECTOR_SIZE;
danielk1977a3d4c882007-03-23 10:08:38 +00001054}
1055
1056/*
drh153c62c2007-08-24 03:51:33 +00001057** Return a vector of device characteristics.
drh9c06c952005-11-26 00:25:00 +00001058*/
drh153c62c2007-08-24 03:51:33 +00001059static int winDeviceCharacteristics(sqlite3_file *id){
1060 return 0;
1061}
1062
1063/*
1064** This vector defines all the methods that can operate on an
1065** sqlite3_file for win32.
1066*/
1067static const sqlite3_io_methods winIoMethod = {
1068 1, /* iVersion */
drh9c06c952005-11-26 00:25:00 +00001069 winClose,
1070 winRead,
1071 winWrite,
drh9c06c952005-11-26 00:25:00 +00001072 winTruncate,
drh054889e2005-11-30 03:20:31 +00001073 winSync,
drh054889e2005-11-30 03:20:31 +00001074 winFileSize,
1075 winLock,
1076 winUnlock,
drh054889e2005-11-30 03:20:31 +00001077 winCheckReservedLock,
drhcc6bb3e2007-08-31 16:11:35 +00001078 winFileControl,
danielk1977a3d4c882007-03-23 10:08:38 +00001079 winSectorSize,
drh153c62c2007-08-24 03:51:33 +00001080 winDeviceCharacteristics
drh9c06c952005-11-26 00:25:00 +00001081};
1082
drh153c62c2007-08-24 03:51:33 +00001083/***************************************************************************
1084** Here ends the I/O methods that form the sqlite3_io_methods object.
1085**
1086** The next block of code implements the VFS methods.
1087****************************************************************************/
1088
drh054889e2005-11-30 03:20:31 +00001089/*
drh153c62c2007-08-24 03:51:33 +00001090** Convert a UTF-8 filename into whatever form the underlying
1091** operating system wants filenames in. Space to hold the result
drhb11caac2007-08-24 17:52:21 +00001092** is obtained from malloc and must be freed by the calling
drh153c62c2007-08-24 03:51:33 +00001093** function.
drh054889e2005-11-30 03:20:31 +00001094*/
drh153c62c2007-08-24 03:51:33 +00001095static void *convertUtf8Filename(const char *zFilename){
1096 void *zConverted = 0;
1097 if( isNT() ){
1098 zConverted = utf8ToUnicode(zFilename);
shane891adea2008-10-22 16:55:47 +00001099/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1100*/
1101#if SQLITE_OS_WINCE==0
drh054889e2005-11-30 03:20:31 +00001102 }else{
drh153c62c2007-08-24 03:51:33 +00001103 zConverted = utf8ToMbcs(zFilename);
shane891adea2008-10-22 16:55:47 +00001104#endif
drh054889e2005-11-30 03:20:31 +00001105 }
drh153c62c2007-08-24 03:51:33 +00001106 /* caller will handle out of memory */
1107 return zConverted;
1108}
1109
1110/*
danielk197717b90b52008-06-06 11:11:25 +00001111** Create a temporary file name in zBuf. zBuf must be big enough to
1112** hold at pVfs->mxPathname characters.
1113*/
1114static int getTempname(int nBuf, char *zBuf){
1115 static char zChars[] =
1116 "abcdefghijklmnopqrstuvwxyz"
1117 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1118 "0123456789";
shane3582c5a2008-07-31 01:34:34 +00001119 size_t i, j;
danielk197717b90b52008-06-06 11:11:25 +00001120 char zTempPath[MAX_PATH+1];
1121 if( sqlite3_temp_directory ){
1122 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1123 }else if( isNT() ){
1124 char *zMulti;
1125 WCHAR zWidePath[MAX_PATH];
1126 GetTempPathW(MAX_PATH-30, zWidePath);
1127 zMulti = unicodeToUtf8(zWidePath);
1128 if( zMulti ){
1129 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1130 free(zMulti);
1131 }else{
1132 return SQLITE_NOMEM;
1133 }
shane891adea2008-10-22 16:55:47 +00001134/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1135** Since the ASCII version of these Windows API do not exist for WINCE,
1136** it's important to not reference them for WINCE builds.
1137*/
1138#if SQLITE_OS_WINCE==0
danielk197717b90b52008-06-06 11:11:25 +00001139 }else{
1140 char *zUtf8;
1141 char zMbcsPath[MAX_PATH];
1142 GetTempPathA(MAX_PATH-30, zMbcsPath);
drh1d298852008-11-18 19:18:52 +00001143 zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
danielk197717b90b52008-06-06 11:11:25 +00001144 if( zUtf8 ){
1145 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1146 free(zUtf8);
1147 }else{
1148 return SQLITE_NOMEM;
1149 }
shane891adea2008-10-22 16:55:47 +00001150#endif
danielk197717b90b52008-06-06 11:11:25 +00001151 }
drhea678832008-12-10 19:26:22 +00001152 for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
danielk197717b90b52008-06-06 11:11:25 +00001153 zTempPath[i] = 0;
1154 sqlite3_snprintf(nBuf-30, zBuf,
1155 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
drhea678832008-12-10 19:26:22 +00001156 j = sqlite3Strlen30(zBuf);
danielk197717b90b52008-06-06 11:11:25 +00001157 sqlite3_randomness(20, &zBuf[j]);
1158 for(i=0; i<20; i++, j++){
1159 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
1160 }
1161 zBuf[j] = 0;
1162 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
1163 return SQLITE_OK;
1164}
1165
shane820800d2008-07-22 05:32:03 +00001166/*
1167** The return value of getLastErrorMsg
1168** is zero if the error message fits in the buffer, or non-zero
1169** otherwise (if the message was truncated).
1170*/
1171static int getLastErrorMsg(int nBuf, char *zBuf){
1172 DWORD error = GetLastError();
1173
1174#if SQLITE_OS_WINCE
1175 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
1176#else
1177 /* FormatMessage returns 0 on failure. Otherwise it
1178 ** returns the number of TCHARs written to the output
1179 ** buffer, excluding the terminating null char.
1180 */
1181 if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
1182 NULL,
1183 error,
1184 0,
1185 zBuf,
1186 nBuf-1,
1187 0))
1188 {
1189 sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", error, error);
1190 }
1191#endif
1192
1193 return 0;
1194}
1195
danielk197717b90b52008-06-06 11:11:25 +00001196
1197/*
drh153c62c2007-08-24 03:51:33 +00001198** Open a file.
1199*/
1200static int winOpen(
1201 sqlite3_vfs *pVfs, /* Not used */
1202 const char *zName, /* Name of the file (UTF-8) */
1203 sqlite3_file *id, /* Write the SQLite file handle here */
1204 int flags, /* Open mode flags */
1205 int *pOutFlags /* Status return flags */
1206){
1207 HANDLE h;
1208 DWORD dwDesiredAccess;
1209 DWORD dwShareMode;
1210 DWORD dwCreationDisposition;
1211 DWORD dwFlagsAndAttributes = 0;
shaned94b0552008-09-30 04:20:07 +00001212#if SQLITE_OS_WINCE
1213 int isTemp = 0;
1214#endif
drh153c62c2007-08-24 03:51:33 +00001215 winFile *pFile = (winFile*)id;
danielk197717b90b52008-06-06 11:11:25 +00001216 void *zConverted; /* Filename in OS encoding */
1217 const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
1218 char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */
1219
1220 /* If the second argument to this function is NULL, generate a
1221 ** temporary file name to use
1222 */
1223 if( !zUtf8Name ){
1224 int rc = getTempname(MAX_PATH+1, zTmpname);
1225 if( rc!=SQLITE_OK ){
1226 return rc;
1227 }
1228 zUtf8Name = zTmpname;
1229 }
1230
1231 /* Convert the filename to the system encoding. */
1232 zConverted = convertUtf8Filename(zUtf8Name);
drh153c62c2007-08-24 03:51:33 +00001233 if( zConverted==0 ){
1234 return SQLITE_NOMEM;
1235 }
1236
1237 if( flags & SQLITE_OPEN_READWRITE ){
1238 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1239 }else{
1240 dwDesiredAccess = GENERIC_READ;
1241 }
1242 if( flags & SQLITE_OPEN_CREATE ){
1243 dwCreationDisposition = OPEN_ALWAYS;
1244 }else{
1245 dwCreationDisposition = OPEN_EXISTING;
1246 }
1247 if( flags & SQLITE_OPEN_MAIN_DB ){
1248 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1249 }else{
1250 dwShareMode = 0;
1251 }
drh64c1ea62007-12-10 21:11:31 +00001252 if( flags & SQLITE_OPEN_DELETEONCLOSE ){
danielk197729bafea2008-06-26 10:41:19 +00001253#if SQLITE_OS_WINCE
drh0cd1ea52007-10-08 15:06:03 +00001254 dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
shaned94b0552008-09-30 04:20:07 +00001255 isTemp = 1;
drh0cd1ea52007-10-08 15:06:03 +00001256#else
drh153c62c2007-08-24 03:51:33 +00001257 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
1258 | FILE_ATTRIBUTE_HIDDEN
1259 | FILE_FLAG_DELETE_ON_CLOSE;
drh0cd1ea52007-10-08 15:06:03 +00001260#endif
drh153c62c2007-08-24 03:51:33 +00001261 }else{
1262 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
1263 }
drh496936c2007-10-08 12:21:10 +00001264 /* Reports from the internet are that performance is always
1265 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
shaned94b0552008-09-30 04:20:07 +00001266#if SQLITE_OS_WINCE
drh496936c2007-10-08 12:21:10 +00001267 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
shaned94b0552008-09-30 04:20:07 +00001268#endif
drh153c62c2007-08-24 03:51:33 +00001269 if( isNT() ){
1270 h = CreateFileW((WCHAR*)zConverted,
1271 dwDesiredAccess,
1272 dwShareMode,
1273 NULL,
1274 dwCreationDisposition,
1275 dwFlagsAndAttributes,
1276 NULL
1277 );
shane891adea2008-10-22 16:55:47 +00001278/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1279** Since the ASCII version of these Windows API do not exist for WINCE,
1280** it's important to not reference them for WINCE builds.
1281*/
1282#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001283 }else{
drh153c62c2007-08-24 03:51:33 +00001284 h = CreateFileA((char*)zConverted,
1285 dwDesiredAccess,
1286 dwShareMode,
1287 NULL,
1288 dwCreationDisposition,
1289 dwFlagsAndAttributes,
1290 NULL
1291 );
shane891adea2008-10-22 16:55:47 +00001292#endif
drh153c62c2007-08-24 03:51:33 +00001293 }
1294 if( h==INVALID_HANDLE_VALUE ){
drhe1843af2007-08-30 16:46:04 +00001295 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001296 if( flags & SQLITE_OPEN_READWRITE ){
drh153c62c2007-08-24 03:51:33 +00001297 return winOpen(0, zName, id,
1298 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
1299 }else{
1300 return SQLITE_CANTOPEN;
1301 }
1302 }
1303 if( pOutFlags ){
1304 if( flags & SQLITE_OPEN_READWRITE ){
1305 *pOutFlags = SQLITE_OPEN_READWRITE;
1306 }else{
1307 *pOutFlags = SQLITE_OPEN_READONLY;
1308 }
1309 }
1310 memset(pFile, 0, sizeof(*pFile));
1311 pFile->pMethod = &winIoMethod;
1312 pFile->h = h;
danielk197729bafea2008-06-26 10:41:19 +00001313#if SQLITE_OS_WINCE
drh153c62c2007-08-24 03:51:33 +00001314 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
1315 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
drhaab2e6d2007-10-08 12:22:57 +00001316 && !winceCreateLock(zName, pFile)
drh153c62c2007-08-24 03:51:33 +00001317 ){
1318 CloseHandle(h);
drhb11caac2007-08-24 17:52:21 +00001319 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001320 return SQLITE_CANTOPEN;
1321 }
drhfc3afb62007-10-09 15:36:10 +00001322 if( isTemp ){
drh153c62c2007-08-24 03:51:33 +00001323 pFile->zDeleteOnClose = zConverted;
1324 }else
1325#endif
1326 {
drhb11caac2007-08-24 17:52:21 +00001327 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001328 }
drhaf5f0402007-09-03 17:09:03 +00001329 OpenCounter(+1);
drh153c62c2007-08-24 03:51:33 +00001330 return SQLITE_OK;
1331}
1332
1333/*
1334** Delete the named file.
1335**
1336** Note that windows does not allow a file to be deleted if some other
1337** process has it open. Sometimes a virus scanner or indexing program
1338** will open a journal file shortly after it is created in order to do
shane3582c5a2008-07-31 01:34:34 +00001339** whatever it does. While this other process is holding the
drh153c62c2007-08-24 03:51:33 +00001340** file open, we will be unable to delete it. To work around this
1341** problem, we delay 100 milliseconds and try to delete again. Up
1342** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
1343** up and returning an error.
1344*/
drhf024f0b2007-11-07 01:19:07 +00001345#define MX_DELETION_ATTEMPTS 5
drh153c62c2007-08-24 03:51:33 +00001346static int winDelete(
1347 sqlite3_vfs *pVfs, /* Not used on win32 */
1348 const char *zFilename, /* Name of file to delete */
1349 int syncDir /* Not used on win32 */
1350){
1351 int cnt = 0;
shaned94b0552008-09-30 04:20:07 +00001352 DWORD rc;
drhea678832008-12-10 19:26:22 +00001353 DWORD error = 0;
drh153c62c2007-08-24 03:51:33 +00001354 void *zConverted = convertUtf8Filename(zFilename);
1355 if( zConverted==0 ){
1356 return SQLITE_NOMEM;
1357 }
1358 SimulateIOError(return SQLITE_IOERR_DELETE);
1359 if( isNT() ){
1360 do{
drhf024f0b2007-11-07 01:19:07 +00001361 DeleteFileW(zConverted);
shane3582c5a2008-07-31 01:34:34 +00001362 }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
1363 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00001364 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00001365 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00001366/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1367** Since the ASCII version of these Windows API do not exist for WINCE,
1368** it's important to not reference them for WINCE builds.
1369*/
1370#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001371 }else{
drh153c62c2007-08-24 03:51:33 +00001372 do{
drhf024f0b2007-11-07 01:19:07 +00001373 DeleteFileA(zConverted);
shane3582c5a2008-07-31 01:34:34 +00001374 }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES)
1375 || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
shaned94b0552008-09-30 04:20:07 +00001376 && (++cnt < MX_DELETION_ATTEMPTS)
shane3582c5a2008-07-31 01:34:34 +00001377 && (Sleep(100), 1) );
shane891adea2008-10-22 16:55:47 +00001378#endif
drh153c62c2007-08-24 03:51:33 +00001379 }
drhb11caac2007-08-24 17:52:21 +00001380 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001381 OSTRACE2("DELETE \"%s\"\n", zFilename);
shaned94b0552008-09-30 04:20:07 +00001382 return ( (rc == INVALID_FILE_ATTRIBUTES)
shane3582c5a2008-07-31 01:34:34 +00001383 && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;
drh153c62c2007-08-24 03:51:33 +00001384}
1385
1386/*
1387** Check the existance and status of a file.
1388*/
1389static int winAccess(
1390 sqlite3_vfs *pVfs, /* Not used on win32 */
1391 const char *zFilename, /* Name of file to check */
danielk1977861f7452008-06-05 11:39:11 +00001392 int flags, /* Type of test to make on this file */
1393 int *pResOut /* OUT: Result */
drh153c62c2007-08-24 03:51:33 +00001394){
1395 DWORD attr;
drhea678832008-12-10 19:26:22 +00001396 int rc = 0;
drh153c62c2007-08-24 03:51:33 +00001397 void *zConverted = convertUtf8Filename(zFilename);
1398 if( zConverted==0 ){
1399 return SQLITE_NOMEM;
1400 }
1401 if( isNT() ){
1402 attr = GetFileAttributesW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00001403/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1404** Since the ASCII version of these Windows API do not exist for WINCE,
1405** it's important to not reference them for WINCE builds.
1406*/
1407#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001408 }else{
drh153c62c2007-08-24 03:51:33 +00001409 attr = GetFileAttributesA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00001410#endif
drh153c62c2007-08-24 03:51:33 +00001411 }
drhb11caac2007-08-24 17:52:21 +00001412 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001413 switch( flags ){
drh50d3f902007-08-27 21:10:36 +00001414 case SQLITE_ACCESS_READ:
drh153c62c2007-08-24 03:51:33 +00001415 case SQLITE_ACCESS_EXISTS:
shane820800d2008-07-22 05:32:03 +00001416 rc = attr!=INVALID_FILE_ATTRIBUTES;
drh153c62c2007-08-24 03:51:33 +00001417 break;
1418 case SQLITE_ACCESS_READWRITE:
1419 rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
1420 break;
drh153c62c2007-08-24 03:51:33 +00001421 default:
1422 assert(!"Invalid flags argument");
1423 }
danielk1977861f7452008-06-05 11:39:11 +00001424 *pResOut = rc;
1425 return SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001426}
1427
1428
drh153c62c2007-08-24 03:51:33 +00001429/*
drh153c62c2007-08-24 03:51:33 +00001430** Turn a relative pathname into a full pathname. Write the full
1431** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
1432** bytes in size.
1433*/
1434static int winFullPathname(
danielk1977adfb9b02007-09-17 07:02:56 +00001435 sqlite3_vfs *pVfs, /* Pointer to vfs object */
1436 const char *zRelative, /* Possibly relative input path */
1437 int nFull, /* Size of output buffer in bytes */
1438 char *zFull /* Output buffer */
drh153c62c2007-08-24 03:51:33 +00001439){
drh1bd10f82008-12-10 21:19:56 +00001440
drh153c62c2007-08-24 03:51:33 +00001441#if defined(__CYGWIN__)
1442 cygwin_conv_to_full_win32_path(zRelative, zFull);
danielk1977076f1c02007-09-12 14:09:23 +00001443 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001444#endif
1445
danielk197729bafea2008-06-26 10:41:19 +00001446#if SQLITE_OS_WINCE
drh153c62c2007-08-24 03:51:33 +00001447 /* WinCE has no concept of a relative pathname, or so I am told. */
1448 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
drhe8256092007-10-09 15:20:39 +00001449 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001450#endif
1451
danielk197729bafea2008-06-26 10:41:19 +00001452#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
drh153c62c2007-08-24 03:51:33 +00001453 int nByte;
1454 void *zConverted;
1455 char *zOut;
1456 zConverted = convertUtf8Filename(zRelative);
1457 if( isNT() ){
1458 WCHAR *zTemp;
1459 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001460 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001461 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001462 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001463 return SQLITE_NOMEM;
1464 }
1465 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001466 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001467 zOut = unicodeToUtf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001468 free(zTemp);
shane891adea2008-10-22 16:55:47 +00001469/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1470** Since the ASCII version of these Windows API do not exist for WINCE,
1471** it's important to not reference them for WINCE builds.
1472*/
1473#if SQLITE_OS_WINCE==0
drh153c62c2007-08-24 03:51:33 +00001474 }else{
1475 char *zTemp;
1476 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001477 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001478 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001479 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001480 return SQLITE_NOMEM;
1481 }
1482 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001483 free(zConverted);
drh1d298852008-11-18 19:18:52 +00001484 zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001485 free(zTemp);
shane891adea2008-10-22 16:55:47 +00001486#endif
drh153c62c2007-08-24 03:51:33 +00001487 }
1488 if( zOut ){
drhb11caac2007-08-24 17:52:21 +00001489 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
1490 free(zOut);
drh153c62c2007-08-24 03:51:33 +00001491 return SQLITE_OK;
1492 }else{
1493 return SQLITE_NOMEM;
1494 }
1495#endif
1496}
1497
1498#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh761df872006-12-21 01:29:22 +00001499/*
1500** Interfaces for opening a shared library, finding entry points
1501** within the shared library, and closing the shared library.
1502*/
drh153c62c2007-08-24 03:51:33 +00001503/*
1504** Interfaces for opening a shared library, finding entry points
1505** within the shared library, and closing the shared library.
1506*/
1507static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
drh761df872006-12-21 01:29:22 +00001508 HANDLE h;
1509 void *zConverted = convertUtf8Filename(zFilename);
drh1bd10f82008-12-10 21:19:56 +00001510 UNUSED_PARAMETER(pVfs);
drh761df872006-12-21 01:29:22 +00001511 if( zConverted==0 ){
1512 return 0;
1513 }
1514 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00001515 h = LoadLibraryW((WCHAR*)zConverted);
shane891adea2008-10-22 16:55:47 +00001516/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed.
1517** Since the ASCII version of these Windows API do not exist for WINCE,
1518** it's important to not reference them for WINCE builds.
1519*/
1520#if SQLITE_OS_WINCE==0
drh761df872006-12-21 01:29:22 +00001521 }else{
drh584c0942006-12-21 03:20:40 +00001522 h = LoadLibraryA((char*)zConverted);
shane891adea2008-10-22 16:55:47 +00001523#endif
drh761df872006-12-21 01:29:22 +00001524 }
drhb11caac2007-08-24 17:52:21 +00001525 free(zConverted);
drh761df872006-12-21 01:29:22 +00001526 return (void*)h;
drh761df872006-12-21 01:29:22 +00001527}
drh153c62c2007-08-24 03:51:33 +00001528static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
drh1bd10f82008-12-10 21:19:56 +00001529 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00001530 getLastErrorMsg(nBuf, zBufOut);
drh153c62c2007-08-24 03:51:33 +00001531}
drh1875f7a2008-12-08 18:19:17 +00001532void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
drh1bd10f82008-12-10 21:19:56 +00001533 UNUSED_PARAMETER(pVfs);
danielk197729bafea2008-06-26 10:41:19 +00001534#if SQLITE_OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00001535 /* The GetProcAddressA() routine is only available on wince. */
drh1875f7a2008-12-08 18:19:17 +00001536 return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001537#else
1538 /* All other windows platforms expect GetProcAddress() to take
1539 ** an Ansi string regardless of the _UNICODE setting */
drh1875f7a2008-12-08 18:19:17 +00001540 return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001541#endif
drh761df872006-12-21 01:29:22 +00001542}
drh153c62c2007-08-24 03:51:33 +00001543void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh1bd10f82008-12-10 21:19:56 +00001544 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001545 FreeLibrary((HANDLE)pHandle);
drh761df872006-12-21 01:29:22 +00001546}
drh153c62c2007-08-24 03:51:33 +00001547#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
1548 #define winDlOpen 0
1549 #define winDlError 0
1550 #define winDlSym 0
1551 #define winDlClose 0
1552#endif
1553
drh761df872006-12-21 01:29:22 +00001554
drh0ccebe72005-06-07 22:22:50 +00001555/*
drh153c62c2007-08-24 03:51:33 +00001556** Write up to nBuf bytes of randomness into zBuf.
drhbbd42a62004-05-22 17:41:58 +00001557*/
drh153c62c2007-08-24 03:51:33 +00001558static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drhd1a79312007-09-03 13:06:11 +00001559 int n = 0;
shanec7b7f1a2008-11-19 21:35:46 +00001560 UNUSED_PARAMETER(pVfs);
1561#if defined(SQLITE_TEST)
1562 n = nBuf;
1563 memset(zBuf, 0, nBuf);
1564#else
drh86742612007-09-05 17:06:03 +00001565 if( sizeof(SYSTEMTIME)<=nBuf-n ){
drhd1a79312007-09-03 13:06:11 +00001566 SYSTEMTIME x;
1567 GetSystemTime(&x);
1568 memcpy(&zBuf[n], &x, sizeof(x));
1569 n += sizeof(x);
drh153c62c2007-08-24 03:51:33 +00001570 }
drhd1a79312007-09-03 13:06:11 +00001571 if( sizeof(DWORD)<=nBuf-n ){
1572 DWORD pid = GetCurrentProcessId();
1573 memcpy(&zBuf[n], &pid, sizeof(pid));
1574 n += sizeof(pid);
1575 }
1576 if( sizeof(DWORD)<=nBuf-n ){
1577 DWORD cnt = GetTickCount();
1578 memcpy(&zBuf[n], &cnt, sizeof(cnt));
1579 n += sizeof(cnt);
1580 }
1581 if( sizeof(LARGE_INTEGER)<=nBuf-n ){
1582 LARGE_INTEGER i;
1583 QueryPerformanceCounter(&i);
1584 memcpy(&zBuf[n], &i, sizeof(i));
1585 n += sizeof(i);
1586 }
shanec7b7f1a2008-11-19 21:35:46 +00001587#endif
drhd1a79312007-09-03 13:06:11 +00001588 return n;
drhbbd42a62004-05-22 17:41:58 +00001589}
1590
drh153c62c2007-08-24 03:51:33 +00001591
drhbbd42a62004-05-22 17:41:58 +00001592/*
1593** Sleep for a little while. Return the amount of time slept.
1594*/
drh153c62c2007-08-24 03:51:33 +00001595static int winSleep(sqlite3_vfs *pVfs, int microsec){
1596 Sleep((microsec+999)/1000);
drh1bd10f82008-12-10 21:19:56 +00001597 UNUSED_PARAMETER(pVfs);
drh153c62c2007-08-24 03:51:33 +00001598 return ((microsec+999)/1000)*1000;
drhbbd42a62004-05-22 17:41:58 +00001599}
1600
1601/*
drhbbd42a62004-05-22 17:41:58 +00001602** The following variable, if set to a non-zero value, becomes the result
1603** returned from sqlite3OsCurrentTime(). This is used for testing.
1604*/
1605#ifdef SQLITE_TEST
1606int sqlite3_current_time = 0;
1607#endif
1608
1609/*
1610** Find the current time (in Universal Coordinated Time). Write the
1611** current time and date as a Julian Day number into *prNow and
1612** return 0. Return 1 if the time and date cannot be found.
1613*/
drh153c62c2007-08-24 03:51:33 +00001614int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001615 FILETIME ft;
1616 /* FILETIME structure is a 64-bit value representing the number of
1617 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1618 */
1619 double now;
danielk197729bafea2008-06-26 10:41:19 +00001620#if SQLITE_OS_WINCE
drhcc78fea2006-01-06 16:17:05 +00001621 SYSTEMTIME time;
1622 GetSystemTime(&time);
shane820800d2008-07-22 05:32:03 +00001623 /* if SystemTimeToFileTime() fails, it returns zero. */
1624 if (!SystemTimeToFileTime(&time,&ft)){
1625 return 1;
1626 }
drhcc78fea2006-01-06 16:17:05 +00001627#else
drhbbd42a62004-05-22 17:41:58 +00001628 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001629#endif
drh1bd10f82008-12-10 21:19:56 +00001630 UNUSED_PARAMETER(pVfs);
drhbbd42a62004-05-22 17:41:58 +00001631 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1632 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1633#ifdef SQLITE_TEST
1634 if( sqlite3_current_time ){
1635 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1636 }
1637#endif
1638 return 0;
1639}
1640
shane820800d2008-07-22 05:32:03 +00001641/*
1642** The idea is that this function works like a combination of
1643** GetLastError() and FormatMessage() on windows (or errno and
1644** strerror_r() on unix). After an error is returned by an OS
1645** function, SQLite calls this function with zBuf pointing to
1646** a buffer of nBuf bytes. The OS layer should populate the
1647** buffer with a nul-terminated UTF-8 encoded error message
1648** describing the last IO error to have occured within the calling
1649** thread.
1650**
1651** If the error message is too large for the supplied buffer,
1652** it should be truncated. The return value of xGetLastError
1653** is zero if the error message fits in the buffer, or non-zero
1654** otherwise (if the message was truncated). If non-zero is returned,
1655** then it is not necessary to include the nul-terminator character
1656** in the output buffer.
1657**
1658** Not supplying an error message will have no adverse effect
1659** on SQLite. It is fine to have an implementation that never
1660** returns an error message:
1661**
1662** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
1663** assert(zBuf[0]=='\0');
1664** return 0;
1665** }
1666**
1667** However if an error message is supplied, it will be incorporated
1668** by sqlite into the error message available to the user using
1669** sqlite3_errmsg(), possibly making IO errors easier to debug.
1670*/
danielk1977bcb97fe2008-06-06 15:49:29 +00001671static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drh1bd10f82008-12-10 21:19:56 +00001672 UNUSED_PARAMETER(pVfs);
shane820800d2008-07-22 05:32:03 +00001673 return getLastErrorMsg(nBuf, zBuf);
danielk1977bcb97fe2008-06-06 15:49:29 +00001674}
drhb4bc7052006-01-11 23:40:33 +00001675
1676/*
danielk1977c0fa4c52008-06-25 17:19:00 +00001677** Initialize and deinitialize the operating system interface.
danielk197713a68c32005-12-15 10:11:30 +00001678*/
danielk1977c0fa4c52008-06-25 17:19:00 +00001679int sqlite3_os_init(void){
drh153c62c2007-08-24 03:51:33 +00001680 static sqlite3_vfs winVfs = {
1681 1, /* iVersion */
1682 sizeof(winFile), /* szOsFile */
1683 MAX_PATH, /* mxPathname */
drh153c62c2007-08-24 03:51:33 +00001684 0, /* pNext */
1685 "win32", /* zName */
1686 0, /* pAppData */
danielk1977bcb97fe2008-06-06 15:49:29 +00001687
drh153c62c2007-08-24 03:51:33 +00001688 winOpen, /* xOpen */
1689 winDelete, /* xDelete */
1690 winAccess, /* xAccess */
drh153c62c2007-08-24 03:51:33 +00001691 winFullPathname, /* xFullPathname */
1692 winDlOpen, /* xDlOpen */
1693 winDlError, /* xDlError */
1694 winDlSym, /* xDlSym */
1695 winDlClose, /* xDlClose */
1696 winRandomness, /* xRandomness */
1697 winSleep, /* xSleep */
danielk1977bcb97fe2008-06-06 15:49:29 +00001698 winCurrentTime, /* xCurrentTime */
1699 winGetLastError /* xGetLastError */
drh153c62c2007-08-24 03:51:33 +00001700 };
danielk1977c0fa4c52008-06-25 17:19:00 +00001701 sqlite3_vfs_register(&winVfs, 1);
1702 return SQLITE_OK;
danielk197713a68c32005-12-15 10:11:30 +00001703}
danielk1977c0fa4c52008-06-25 17:19:00 +00001704int sqlite3_os_end(void){
1705 return SQLITE_OK;
1706}
drh40257ff2008-06-13 18:24:27 +00001707
danielk197729bafea2008-06-26 10:41:19 +00001708#endif /* SQLITE_OS_WIN */