blob: 51050421941fcd93d30d6a9a06b6b86955188f61 [file] [log] [blame]
drhbbd42a62004-05-22 17:41:58 +00001/*
2** 2004 May 22
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
13** This file contains code that is specific to windows.
14*/
drhbbd42a62004-05-22 17:41:58 +000015#include "sqliteInt.h"
drheb206252004-10-01 02:00:31 +000016#if OS_WIN /* This file is used for windows only */
drhbbd42a62004-05-22 17:41:58 +000017
drhb11caac2007-08-24 17:52:21 +000018
19/*
20** A Note About Memory Allocation:
21**
22** This driver uses malloc()/free() directly rather than going through
23** the SQLite-wrappers sqlite3_malloc()/sqlite3_free(). Those wrappers
24** are designed for use on embedded systems where memory is scarce and
25** malloc failures happen frequently. Win32 does not typically run on
26** embedded systems, and when it does the developers normally have bigger
27** problems to worry about than running out of memory. So there is not
28** a compelling need to use the wrappers.
29**
30** But there is a good reason to not use the wrappers. If we use the
31** wrappers then we will get simulated malloc() failures within this
32** driver. And that causes all kinds of problems for our tests. We
33** could enhance SQLite to deal with simulated malloc failures within
34** the OS driver, but the code to deal with those failure would not
35** be exercised on Linux (which does not need to malloc() in the driver)
36** and so we would have difficulty writing coverage tests for that
37** code. Better to leave the code out, we think.
38**
39** The point of this discussion is as follows: When creating a new
40** OS layer for an embedded system, if you use this file as an example,
41** avoid the use of malloc()/free(). Those routines work ok on windows
42** desktops but not so well in embedded systems.
43*/
44
drhbbd42a62004-05-22 17:41:58 +000045#include <winbase.h>
46
drh09bf0e82005-03-21 00:36:08 +000047#ifdef __CYGWIN__
48# include <sys/cygwin.h>
49#endif
50
drhbbd42a62004-05-22 17:41:58 +000051/*
52** Macros used to determine whether or not to use threads.
53*/
54#if defined(THREADSAFE) && THREADSAFE
55# define SQLITE_W32_THREADS 1
56#endif
57
58/*
59** Include code that is common to all os_*.c files
60*/
61#include "os_common.h"
62
63/*
drhcc78fea2006-01-06 16:17:05 +000064** Determine if we are dealing with WindowsCE - which has a much
65** reduced API.
66*/
67#if defined(_WIN32_WCE)
68# define OS_WINCE 1
drhd2832bf2007-01-10 18:56:15 +000069# define AreFileApisANSI() 1
drhcc78fea2006-01-06 16:17:05 +000070#else
71# define OS_WINCE 0
72#endif
73
74/*
drh72aead82006-01-23 15:54:25 +000075** WinCE lacks native support for file locking so we have to fake it
76** with some code of our own.
77*/
78#if OS_WINCE
79typedef struct winceLock {
80 int nReaders; /* Number of reader locks obtained */
81 BOOL bPending; /* Indicates a pending lock has been obtained */
82 BOOL bReserved; /* Indicates a reserved lock has been obtained */
83 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
84} winceLock;
85#endif
86
87/*
drh153c62c2007-08-24 03:51:33 +000088** The winFile structure is a subclass of sqlite3_file* specific to the win32
drh054889e2005-11-30 03:20:31 +000089** portability layer.
drh9cbe6352005-11-29 03:13:21 +000090*/
drh054889e2005-11-30 03:20:31 +000091typedef struct winFile winFile;
92struct winFile {
drh153c62c2007-08-24 03:51:33 +000093 const sqlite3_io_methods *pMethod;/* Must be first */
drh9cbe6352005-11-29 03:13:21 +000094 HANDLE h; /* Handle for accessing the file */
95 unsigned char locktype; /* Type of lock currently held on this file */
96 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
drhcc78fea2006-01-06 16:17:05 +000097#if OS_WINCE
drh72aead82006-01-23 15:54:25 +000098 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
99 HANDLE hMutex; /* Mutex used to control access to shared lock */
100 HANDLE hShared; /* Shared memory segment used for locking */
101 winceLock local; /* Locks obtained by this instance of winFile */
102 winceLock *shared; /* Global shared lock memory for the file */
drhcc78fea2006-01-06 16:17:05 +0000103#endif
drh9cbe6352005-11-29 03:13:21 +0000104};
105
106
drh9cbe6352005-11-29 03:13:21 +0000107/*
drhc0929982005-09-05 19:08:29 +0000108** The following variable is (normally) set once and never changes
109** thereafter. It records whether the operating system is Win95
110** or WinNT.
111**
112** 0: Operating system unknown.
113** 1: Operating system is Win95.
114** 2: Operating system is WinNT.
115**
116** In order to facilitate testing on a WinNT system, the test fixture
117** can manually set this value to 1 to emulate Win98 behavior.
118*/
drh153c62c2007-08-24 03:51:33 +0000119#ifdef SQLITE_TEST
drhc0929982005-09-05 19:08:29 +0000120int sqlite3_os_type = 0;
drh153c62c2007-08-24 03:51:33 +0000121#else
122static int sqlite3_os_type = 0;
123#endif
drhc0929982005-09-05 19:08:29 +0000124
125/*
drhcc78fea2006-01-06 16:17:05 +0000126** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
127** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +0000128**
129** Here is an interesting observation: Win95, Win98, and WinME lack
130** the LockFileEx() API. But we can still statically link against that
131** API as long as we don't call it win running Win95/98/ME. A call to
132** this routine is used to determine if the host is Win95/98/ME or
133** WinNT/2K/XP so that we will know whether or not we can safely call
134** the LockFileEx() API.
135*/
drhcc78fea2006-01-06 16:17:05 +0000136#if OS_WINCE
137# define isNT() (1)
138#else
139 static int isNT(void){
140 if( sqlite3_os_type==0 ){
141 OSVERSIONINFO sInfo;
142 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
143 GetVersionEx(&sInfo);
144 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
145 }
146 return sqlite3_os_type==2;
drhc0929982005-09-05 19:08:29 +0000147 }
drhcc78fea2006-01-06 16:17:05 +0000148#endif /* OS_WINCE */
149
drhc0929982005-09-05 19:08:29 +0000150/*
drh584c0942006-12-21 03:20:40 +0000151** Convert a UTF-8 string to microsoft unicode (UTF-16?).
152**
drhb11caac2007-08-24 17:52:21 +0000153** Space to hold the returned string is obtained from malloc.
drhc0929982005-09-05 19:08:29 +0000154*/
155static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000156 int nChar;
drhc0929982005-09-05 19:08:29 +0000157 WCHAR *zWideFilename;
158
drhe3dd8bb2006-02-27 23:44:35 +0000159 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
drhb11caac2007-08-24 17:52:21 +0000160 zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000161 if( zWideFilename==0 ){
162 return 0;
163 }
drhe3dd8bb2006-02-27 23:44:35 +0000164 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
165 if( nChar==0 ){
drhb11caac2007-08-24 17:52:21 +0000166 free(zWideFilename);
drhc0929982005-09-05 19:08:29 +0000167 zWideFilename = 0;
168 }
169 return zWideFilename;
170}
171
172/*
drh584c0942006-12-21 03:20:40 +0000173** Convert microsoft unicode to UTF-8. Space to hold the returned string is
drhb11caac2007-08-24 17:52:21 +0000174** obtained from malloc().
drhc0929982005-09-05 19:08:29 +0000175*/
176static char *unicodeToUtf8(const WCHAR *zWideFilename){
177 int nByte;
178 char *zFilename;
179
180 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000181 zFilename = malloc( nByte );
drhc0929982005-09-05 19:08:29 +0000182 if( zFilename==0 ){
183 return 0;
184 }
185 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
186 0, 0);
187 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000188 free(zFilename);
drhc0929982005-09-05 19:08:29 +0000189 zFilename = 0;
190 }
191 return zFilename;
192}
193
drh371de5a2006-10-30 13:37:22 +0000194/*
drh584c0942006-12-21 03:20:40 +0000195** Convert an ansi string to microsoft unicode, based on the
196** current codepage settings for file apis.
197**
198** Space to hold the returned string is obtained
drhb11caac2007-08-24 17:52:21 +0000199** from malloc.
drh371de5a2006-10-30 13:37:22 +0000200*/
201static WCHAR *mbcsToUnicode(const char *zFilename){
202 int nByte;
203 WCHAR *zMbcsFilename;
drh584c0942006-12-21 03:20:40 +0000204 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000205
drh584c0942006-12-21 03:20:40 +0000206 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
drhb11caac2007-08-24 17:52:21 +0000207 zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );
drh371de5a2006-10-30 13:37:22 +0000208 if( zMbcsFilename==0 ){
209 return 0;
210 }
drh584c0942006-12-21 03:20:40 +0000211 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
drh371de5a2006-10-30 13:37:22 +0000212 if( nByte==0 ){
drhb11caac2007-08-24 17:52:21 +0000213 free(zMbcsFilename);
drh371de5a2006-10-30 13:37:22 +0000214 zMbcsFilename = 0;
215 }
216 return zMbcsFilename;
217}
218
219/*
drh584c0942006-12-21 03:20:40 +0000220** Convert microsoft unicode to multibyte character string, based on the
221** user's Ansi codepage.
222**
223** Space to hold the returned string is obtained from
drhb11caac2007-08-24 17:52:21 +0000224** malloc().
drh371de5a2006-10-30 13:37:22 +0000225*/
226static char *unicodeToMbcs(const WCHAR *zWideFilename){
227 int nByte;
228 char *zFilename;
drh584c0942006-12-21 03:20:40 +0000229 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000230
drh584c0942006-12-21 03:20:40 +0000231 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
drhb11caac2007-08-24 17:52:21 +0000232 zFilename = malloc( nByte );
drh371de5a2006-10-30 13:37:22 +0000233 if( zFilename==0 ){
234 return 0;
235 }
drh584c0942006-12-21 03:20:40 +0000236 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
drh371de5a2006-10-30 13:37:22 +0000237 0, 0);
238 if( nByte == 0 ){
drhb11caac2007-08-24 17:52:21 +0000239 free(zFilename);
drh371de5a2006-10-30 13:37:22 +0000240 zFilename = 0;
241 }
242 return zFilename;
243}
244
245/*
246** Convert multibyte character string to UTF-8. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000247** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000248*/
249static char *mbcsToUtf8(const char *zFilename){
250 char *zFilenameUtf8;
251 WCHAR *zTmpWide;
252
253 zTmpWide = mbcsToUnicode(zFilename);
254 if( zTmpWide==0 ){
255 return 0;
256 }
257 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000258 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000259 return zFilenameUtf8;
260}
261
262/*
263** Convert UTF-8 to multibyte character string. Space to hold the
drhb11caac2007-08-24 17:52:21 +0000264** returned string is obtained from malloc().
drh371de5a2006-10-30 13:37:22 +0000265*/
266static char *utf8ToMbcs(const char *zFilename){
267 char *zFilenameMbcs;
268 WCHAR *zTmpWide;
269
270 zTmpWide = utf8ToUnicode(zFilename);
271 if( zTmpWide==0 ){
272 return 0;
273 }
274 zFilenameMbcs = unicodeToMbcs(zTmpWide);
drhb11caac2007-08-24 17:52:21 +0000275 free(zTmpWide);
drh371de5a2006-10-30 13:37:22 +0000276 return zFilenameMbcs;
277}
278
drh72aead82006-01-23 15:54:25 +0000279#if OS_WINCE
280/*************************************************************************
281** This section contains code for WinCE only.
282*/
283/*
284** WindowsCE does not have a localtime() function. So create a
285** substitute.
286*/
287#include <time.h>
288struct tm *__cdecl localtime(const time_t *t)
289{
290 static struct tm y;
291 FILETIME uTm, lTm;
292 SYSTEMTIME pTm;
drhc51250a2007-09-20 14:39:23 +0000293 sqlite3_int64 t64;
drh72aead82006-01-23 15:54:25 +0000294 t64 = *t;
295 t64 = (t64 + 11644473600)*10000000;
296 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
297 uTm.dwHighDateTime= t64 >> 32;
298 FileTimeToLocalFileTime(&uTm,&lTm);
299 FileTimeToSystemTime(&lTm,&pTm);
300 y.tm_year = pTm.wYear - 1900;
301 y.tm_mon = pTm.wMonth - 1;
302 y.tm_wday = pTm.wDayOfWeek;
303 y.tm_mday = pTm.wDay;
304 y.tm_hour = pTm.wHour;
305 y.tm_min = pTm.wMinute;
306 y.tm_sec = pTm.wSecond;
307 return &y;
308}
309
310/* This will never be called, but defined to make the code compile */
311#define GetTempPathA(a,b)
312
313#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
314#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
315#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
316
317#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
318
319/*
320** Acquire a lock on the handle h
321*/
322static void winceMutexAcquire(HANDLE h){
323 DWORD dwErr;
324 do {
325 dwErr = WaitForSingleObject(h, INFINITE);
326 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
327}
328/*
329** Release a lock acquired by winceMutexAcquire()
330*/
331#define winceMutexRelease(h) ReleaseMutex(h)
332
333/*
334** Create the mutex and shared memory used for locking in the file
335** descriptor pFile
336*/
337static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
338 WCHAR *zTok;
339 WCHAR *zName = utf8ToUnicode(zFilename);
340 BOOL bInit = TRUE;
341
342 /* Initialize the local lockdata */
343 ZeroMemory(&pFile->local, sizeof(pFile->local));
344
345 /* Replace the backslashes from the filename and lowercase it
346 ** to derive a mutex name. */
347 zTok = CharLowerW(zName);
348 for (;*zTok;zTok++){
349 if (*zTok == '\\') *zTok = '_';
350 }
351
352 /* Create/open the named mutex */
353 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
354 if (!pFile->hMutex){
drhb11caac2007-08-24 17:52:21 +0000355 free(zName);
drh72aead82006-01-23 15:54:25 +0000356 return FALSE;
357 }
358
359 /* Acquire the mutex before continuing */
360 winceMutexAcquire(pFile->hMutex);
361
362 /* Since the names of named mutexes, semaphores, file mappings etc are
363 ** case-sensitive, take advantage of that by uppercasing the mutex name
364 ** and using that as the shared filemapping name.
365 */
366 CharUpperW(zName);
367 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
368 PAGE_READWRITE, 0, sizeof(winceLock),
369 zName);
370
371 /* Set a flag that indicates we're the first to create the memory so it
372 ** must be zero-initialized */
373 if (GetLastError() == ERROR_ALREADY_EXISTS){
374 bInit = FALSE;
375 }
376
drhb11caac2007-08-24 17:52:21 +0000377 free(zName);
drh72aead82006-01-23 15:54:25 +0000378
379 /* If we succeeded in making the shared memory handle, map it. */
380 if (pFile->hShared){
381 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
382 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
383 /* If mapping failed, close the shared memory handle and erase it */
384 if (!pFile->shared){
385 CloseHandle(pFile->hShared);
386 pFile->hShared = NULL;
387 }
388 }
389
390 /* If shared memory could not be created, then close the mutex and fail */
391 if (pFile->hShared == NULL){
392 winceMutexRelease(pFile->hMutex);
393 CloseHandle(pFile->hMutex);
394 pFile->hMutex = NULL;
395 return FALSE;
396 }
397
398 /* Initialize the shared memory if we're supposed to */
399 if (bInit) {
400 ZeroMemory(pFile->shared, sizeof(winceLock));
401 }
402
403 winceMutexRelease(pFile->hMutex);
404 return TRUE;
405}
406
407/*
408** Destroy the part of winFile that deals with wince locks
409*/
410static void winceDestroyLock(winFile *pFile){
411 if (pFile->hMutex){
412 /* Acquire the mutex */
413 winceMutexAcquire(pFile->hMutex);
414
415 /* The following blocks should probably assert in debug mode, but they
416 are to cleanup in case any locks remained open */
417 if (pFile->local.nReaders){
418 pFile->shared->nReaders --;
419 }
420 if (pFile->local.bReserved){
421 pFile->shared->bReserved = FALSE;
422 }
423 if (pFile->local.bPending){
424 pFile->shared->bPending = FALSE;
425 }
426 if (pFile->local.bExclusive){
427 pFile->shared->bExclusive = FALSE;
428 }
429
430 /* De-reference and close our copy of the shared memory handle */
431 UnmapViewOfFile(pFile->shared);
432 CloseHandle(pFile->hShared);
433
drh694b19d2007-04-11 17:54:03 +0000434 if( pFile->zDeleteOnClose ){
435 DeleteFileW(pFile->zDeleteOnClose);
drhb11caac2007-08-24 17:52:21 +0000436 free(pFile->zDeleteOnClose);
drh694b19d2007-04-11 17:54:03 +0000437 pFile->zDeleteOnClose = 0;
438 }
439
drh72aead82006-01-23 15:54:25 +0000440 /* 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*****************************************************************************/
589#endif /* 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);
613 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000614#if OS_WINCE
drh153c62c2007-08-24 03:51:33 +0000615 winceDestroyLock(pFile);
drhcc78fea2006-01-06 16:17:05 +0000616#endif
drh153c62c2007-08-24 03:51:33 +0000617 OpenCounter(-1);
drheb4fa522006-06-04 23:02:20 +0000618 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000619}
620
621/*
drh153c62c2007-08-24 03:51:33 +0000622** Some microsoft compilers lack this definition.
623*/
624#ifndef INVALID_SET_FILE_POINTER
625# define INVALID_SET_FILE_POINTER ((DWORD)-1)
626#endif
627
628/*
drhbbd42a62004-05-22 17:41:58 +0000629** Read data from a file into a buffer. Return SQLITE_OK if all
630** bytes were read successfully and SQLITE_IOERR if anything goes
631** wrong.
632*/
drh153c62c2007-08-24 03:51:33 +0000633static int winRead(
634 sqlite3_file *id, /* File to read from */
635 void *pBuf, /* Write content into this buffer */
636 int amt, /* Number of bytes to read */
637 sqlite3_int64 offset /* Begin reading at this offset */
638){
639 LONG upperBits = (offset>>32) & 0x7fffffff;
640 LONG lowerBits = offset & 0xffffffff;
641 DWORD rc;
drhbbd42a62004-05-22 17:41:58 +0000642 DWORD got;
drh153c62c2007-08-24 03:51:33 +0000643 winFile *pFile = (winFile*)id;
drh9cbe6352005-11-29 03:13:21 +0000644 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +0000645 SimulateIOError(return SQLITE_IOERR_READ);
drh153c62c2007-08-24 03:51:33 +0000646 OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
647 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
648 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
649 return SQLITE_FULL;
650 }
651 if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
drhaedd8922007-01-05 14:38:54 +0000652 return SQLITE_IOERR_READ;
drhbbd42a62004-05-22 17:41:58 +0000653 }
654 if( got==(DWORD)amt ){
655 return SQLITE_OK;
656 }else{
drhbafda092007-01-03 23:36:22 +0000657 memset(&((char*)pBuf)[got], 0, amt-got);
drh551b7732006-11-06 21:20:25 +0000658 return SQLITE_IOERR_SHORT_READ;
drhbbd42a62004-05-22 17:41:58 +0000659 }
660}
661
662/*
663** Write data from a buffer into a file. Return SQLITE_OK on success
664** or some other error code on failure.
665*/
drh153c62c2007-08-24 03:51:33 +0000666static int winWrite(
667 sqlite3_file *id, /* File to write into */
668 const void *pBuf, /* The bytes to be written */
669 int amt, /* Number of bytes to write */
670 sqlite3_int64 offset /* Offset into the file to begin writing at */
671){
672 LONG upperBits = (offset>>32) & 0x7fffffff;
673 LONG lowerBits = offset & 0xffffffff;
674 DWORD rc;
drhbbd42a62004-05-22 17:41:58 +0000675 DWORD wrote;
drh153c62c2007-08-24 03:51:33 +0000676 winFile *pFile = (winFile*)id;
drh9cbe6352005-11-29 03:13:21 +0000677 assert( id!=0 );
drh153c62c2007-08-24 03:51:33 +0000678 SimulateIOError(return SQLITE_IOERR_WRITE);
drh59685932006-09-14 13:47:11 +0000679 SimulateDiskfullError(return SQLITE_FULL);
drh153c62c2007-08-24 03:51:33 +0000680 OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
681 rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
682 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
683 return SQLITE_FULL;
684 }
drh4c7f9412005-02-03 00:29:47 +0000685 assert( amt>0 );
drh153c62c2007-08-24 03:51:33 +0000686 while(
687 amt>0
688 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
689 && wrote>0
690 ){
drhbbd42a62004-05-22 17:41:58 +0000691 amt -= wrote;
692 pBuf = &((char*)pBuf)[wrote];
693 }
694 if( !rc || amt>(int)wrote ){
695 return SQLITE_FULL;
696 }
697 return SQLITE_OK;
698}
699
700/*
drh153c62c2007-08-24 03:51:33 +0000701** Truncate an open file to a specified size
drhbbdc2b92005-09-19 12:53:18 +0000702*/
drhc51250a2007-09-20 14:39:23 +0000703static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
drh153c62c2007-08-24 03:51:33 +0000704 LONG upperBits = (nByte>>32) & 0x7fffffff;
705 LONG lowerBits = nByte & 0xffffffff;
706 winFile *pFile = (winFile*)id;
707 OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
708 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
709 SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
710 SetEndOfFile(pFile->h);
drhbbd42a62004-05-22 17:41:58 +0000711 return SQLITE_OK;
712}
713
drhdec6fae2007-09-03 17:02:50 +0000714#ifdef SQLITE_TEST
715/*
716** Count the number of fullsyncs and normal syncs. This is used to test
717** that syncs and fullsyncs are occuring at the right times.
718*/
719int sqlite3_sync_count = 0;
720int sqlite3_fullsync_count = 0;
721#endif
722
drhbbd42a62004-05-22 17:41:58 +0000723/*
724** Make sure all writes to a particular file are committed to disk.
725*/
drh153c62c2007-08-24 03:51:33 +0000726static int winSync(sqlite3_file *id, int flags){
727 winFile *pFile = (winFile*)id;
728 OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
drhdec6fae2007-09-03 17:02:50 +0000729#ifdef SQLITE_TEST
730 if( flags & SQLITE_SYNC_FULL ){
731 sqlite3_fullsync_count++;
732 }
733 sqlite3_sync_count++;
734#endif
drh153c62c2007-08-24 03:51:33 +0000735 if( FlushFileBuffers(pFile->h) ){
drhbbd42a62004-05-22 17:41:58 +0000736 return SQLITE_OK;
737 }else{
738 return SQLITE_IOERR;
739 }
740}
741
742/*
drhbbd42a62004-05-22 17:41:58 +0000743** Determine the current size of a file in bytes
744*/
drh153c62c2007-08-24 03:51:33 +0000745static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
746 winFile *pFile = (winFile*)id;
drhbbd42a62004-05-22 17:41:58 +0000747 DWORD upperBits, lowerBits;
drh9cce7102007-01-09 17:18:19 +0000748 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh153c62c2007-08-24 03:51:33 +0000749 lowerBits = GetFileSize(pFile->h, &upperBits);
750 *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000751 return SQLITE_OK;
752}
753
754/*
drh602bbd32006-01-06 20:22:29 +0000755** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
756*/
757#ifndef LOCKFILE_FAIL_IMMEDIATELY
758# define LOCKFILE_FAIL_IMMEDIATELY 1
759#endif
760
761/*
drh9c105bb2004-10-02 20:38:28 +0000762** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000763** Different API routines are called depending on whether or not this
764** is Win95 or WinNT.
765*/
drh153c62c2007-08-24 03:51:33 +0000766static int getReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000767 int res;
768 if( isNT() ){
769 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000770 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000771 ovlp.OffsetHigh = 0;
772 ovlp.hEvent = 0;
drh153c62c2007-08-24 03:51:33 +0000773 res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
774 0, SHARED_SIZE, 0, &ovlp);
drhbbd42a62004-05-22 17:41:58 +0000775 }else{
drh9c105bb2004-10-02 20:38:28 +0000776 int lk;
777 sqlite3Randomness(sizeof(lk), &lk);
drh153c62c2007-08-24 03:51:33 +0000778 pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
779 res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000780 }
781 return res;
782}
783
784/*
785** Undo a readlock
786*/
drh054889e2005-11-30 03:20:31 +0000787static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000788 int res;
789 if( isNT() ){
drh054889e2005-11-30 03:20:31 +0000790 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drh51c6d962004-06-06 00:42:25 +0000791 }else{
drh054889e2005-11-30 03:20:31 +0000792 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000793 }
794 return res;
795}
796
tpoindex9a09a3c2004-12-20 19:01:32 +0000797/*
drhb3e04342004-06-08 00:47:47 +0000798** Lock the file with the lock specified by parameter locktype - one
799** of the following:
800**
801** (1) SHARED_LOCK
802** (2) RESERVED_LOCK
803** (3) PENDING_LOCK
804** (4) EXCLUSIVE_LOCK
805**
806** Sometimes when requesting one lock state, additional lock states
807** are inserted in between. The locking might fail on one of the later
808** transitions leaving the lock state different from what it started but
809** still short of its goal. The following chart shows the allowed
810** transitions and the inserted intermediate states:
811**
812** UNLOCKED -> SHARED
813** SHARED -> RESERVED
814** SHARED -> (PENDING) -> EXCLUSIVE
815** RESERVED -> (PENDING) -> EXCLUSIVE
816** PENDING -> EXCLUSIVE
817**
drh9c06c952005-11-26 00:25:00 +0000818** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +0000819** erases all locks at once and returns us immediately to locking level 0.
820** It is not possible to lower the locking level one step at a time. You
821** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000822*/
drh153c62c2007-08-24 03:51:33 +0000823static int winLock(sqlite3_file *id, int locktype){
drh51c6d962004-06-06 00:42:25 +0000824 int rc = SQLITE_OK; /* Return code from subroutines */
825 int res = 1; /* Result of a windows lock call */
drh153c62c2007-08-24 03:51:33 +0000826 int newLocktype; /* Set pFile->locktype to this value before exiting */
drhe54ca3f2004-06-07 01:52:14 +0000827 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +0000828 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +0000829
drh054889e2005-11-30 03:20:31 +0000830 assert( pFile!=0 );
drh4f0c5872007-03-26 22:05:01 +0000831 OSTRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +0000832 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000833
834 /* If there is already a lock of this type or more restrictive on the
835 ** OsFile, do nothing. Don't use the end_lock: exit path, as
836 ** sqlite3OsEnterMutex() hasn't been called yet.
837 */
drh054889e2005-11-30 03:20:31 +0000838 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +0000839 return SQLITE_OK;
840 }
841
drhb3e04342004-06-08 00:47:47 +0000842 /* Make sure the locking sequence is correct
843 */
drh054889e2005-11-30 03:20:31 +0000844 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000845 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +0000846 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000847
drh51c6d962004-06-06 00:42:25 +0000848 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
849 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
850 ** the PENDING_LOCK byte is temporary.
851 */
drh054889e2005-11-30 03:20:31 +0000852 newLocktype = pFile->locktype;
853 if( pFile->locktype==NO_LOCK
854 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +0000855 ){
drhb3e04342004-06-08 00:47:47 +0000856 int cnt = 3;
drh054889e2005-11-30 03:20:31 +0000857 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000858 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000859 ** held by another reader process who will release it momentarily.
860 */
drh4f0c5872007-03-26 22:05:01 +0000861 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000862 Sleep(1);
863 }
drhe54ca3f2004-06-07 01:52:14 +0000864 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +0000865 }
866
867 /* Acquire a shared lock
868 */
drhb3e04342004-06-08 00:47:47 +0000869 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000870 assert( pFile->locktype==NO_LOCK );
871 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000872 if( res ){
873 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +0000874 }
875 }
876
877 /* Acquire a RESERVED lock
878 */
drhb3e04342004-06-08 00:47:47 +0000879 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000880 assert( pFile->locktype==SHARED_LOCK );
881 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +0000882 if( res ){
883 newLocktype = RESERVED_LOCK;
884 }
885 }
886
887 /* Acquire a PENDING lock
888 */
drhb3e04342004-06-08 00:47:47 +0000889 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000890 newLocktype = PENDING_LOCK;
891 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000892 }
893
894 /* Acquire an EXCLUSIVE lock
895 */
drhe54ca3f2004-06-07 01:52:14 +0000896 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000897 assert( pFile->locktype>=SHARED_LOCK );
898 res = unlockReadLock(pFile);
drh4f0c5872007-03-26 22:05:01 +0000899 OSTRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +0000900 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +0000901 if( res ){
902 newLocktype = EXCLUSIVE_LOCK;
903 }else{
drh4f0c5872007-03-26 22:05:01 +0000904 OSTRACE2("error-code = %d\n", GetLastError());
drh8fea1282007-05-14 12:12:11 +0000905 getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000906 }
907 }
908
909 /* If we are holding a PENDING lock that ought to be released, then
910 ** release it now.
911 */
drhb3e04342004-06-08 00:47:47 +0000912 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000913 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000914 }
915
916 /* Update the state of the lock has held in the file descriptor then
917 ** return the appropriate result code.
918 */
919 if( res ){
drh51c6d962004-06-06 00:42:25 +0000920 rc = SQLITE_OK;
921 }else{
drh4f0c5872007-03-26 22:05:01 +0000922 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +0000923 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +0000924 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +0000925 }
drh054889e2005-11-30 03:20:31 +0000926 pFile->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +0000927 return rc;
928}
929
930/*
drh51c6d962004-06-06 00:42:25 +0000931** This routine checks if there is a RESERVED lock held on the specified
932** file by this or any other process. If such a lock is held, return
933** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +0000934*/
drh153c62c2007-08-24 03:51:33 +0000935static int winCheckReservedLock(sqlite3_file *id){
drhbbd42a62004-05-22 17:41:58 +0000936 int rc;
drh054889e2005-11-30 03:20:31 +0000937 winFile *pFile = (winFile*)id;
938 assert( pFile!=0 );
939 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000940 rc = 1;
drh4f0c5872007-03-26 22:05:01 +0000941 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000942 }else{
drh054889e2005-11-30 03:20:31 +0000943 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000944 if( rc ){
drh054889e2005-11-30 03:20:31 +0000945 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000946 }
drh2ac3ee92004-06-07 16:27:46 +0000947 rc = !rc;
drh4f0c5872007-03-26 22:05:01 +0000948 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000949 }
drh2ac3ee92004-06-07 16:27:46 +0000950 return rc;
drhbbd42a62004-05-22 17:41:58 +0000951}
952
953/*
drha6abd042004-06-09 17:37:22 +0000954** Lower the locking level on file descriptor id to locktype. locktype
955** must be either NO_LOCK or SHARED_LOCK.
956**
957** If the locking level of the file descriptor is already at or below
958** the requested locking level, this routine is a no-op.
959**
drh9c105bb2004-10-02 20:38:28 +0000960** It is not possible for this routine to fail if the second argument
961** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
962** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000963*/
drh153c62c2007-08-24 03:51:33 +0000964static int winUnlock(sqlite3_file *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +0000965 int type;
drh054889e2005-11-30 03:20:31 +0000966 winFile *pFile = (winFile*)id;
drh153c62c2007-08-24 03:51:33 +0000967 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +0000968 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +0000969 assert( locktype<=SHARED_LOCK );
drh4f0c5872007-03-26 22:05:01 +0000970 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
drh054889e2005-11-30 03:20:31 +0000971 pFile->locktype, pFile->sharedLockByte);
972 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +0000973 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +0000974 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
975 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +0000976 /* This should never happen. We should always be able to
977 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +0000978 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +0000979 }
drhbbd42a62004-05-22 17:41:58 +0000980 }
drhe54ca3f2004-06-07 01:52:14 +0000981 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000982 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000983 }
drh9c105bb2004-10-02 20:38:28 +0000984 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000985 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +0000986 }
drhb3e04342004-06-08 00:47:47 +0000987 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +0000988 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +0000989 }
drh054889e2005-11-30 03:20:31 +0000990 pFile->locktype = locktype;
drh9c105bb2004-10-02 20:38:28 +0000991 return rc;
drhbbd42a62004-05-22 17:41:58 +0000992}
993
994/*
drh9e33c2c2007-08-31 18:34:59 +0000995** Control and query of the open file handle.
drh0ccebe72005-06-07 22:22:50 +0000996*/
drh9e33c2c2007-08-31 18:34:59 +0000997static int winFileControl(sqlite3_file *id, int op, void *pArg){
998 switch( op ){
999 case SQLITE_FCNTL_LOCKSTATE: {
1000 *(int*)pArg = ((winFile*)id)->locktype;
1001 return SQLITE_OK;
1002 }
1003 }
drh153c62c2007-08-24 03:51:33 +00001004 return SQLITE_ERROR;
drh9cbe6352005-11-29 03:13:21 +00001005}
1006
1007/*
danielk1977a3d4c882007-03-23 10:08:38 +00001008** Return the sector size in bytes of the underlying block device for
1009** the specified file. This is almost always 512 bytes, but may be
1010** larger for some devices.
1011**
1012** SQLite code assumes this function cannot fail. It also assumes that
1013** if two files are created in the same file-system directory (i.e.
1014** a database and it's journal file) that the sector size will be the
1015** same for both.
1016*/
drh153c62c2007-08-24 03:51:33 +00001017static int winSectorSize(sqlite3_file *id){
drh3ceeb752007-03-29 18:19:52 +00001018 return SQLITE_DEFAULT_SECTOR_SIZE;
danielk1977a3d4c882007-03-23 10:08:38 +00001019}
1020
1021/*
drh153c62c2007-08-24 03:51:33 +00001022** Return a vector of device characteristics.
drh9c06c952005-11-26 00:25:00 +00001023*/
drh153c62c2007-08-24 03:51:33 +00001024static int winDeviceCharacteristics(sqlite3_file *id){
1025 return 0;
1026}
1027
1028/*
1029** This vector defines all the methods that can operate on an
1030** sqlite3_file for win32.
1031*/
1032static const sqlite3_io_methods winIoMethod = {
1033 1, /* iVersion */
drh9c06c952005-11-26 00:25:00 +00001034 winClose,
1035 winRead,
1036 winWrite,
drh9c06c952005-11-26 00:25:00 +00001037 winTruncate,
drh054889e2005-11-30 03:20:31 +00001038 winSync,
drh054889e2005-11-30 03:20:31 +00001039 winFileSize,
1040 winLock,
1041 winUnlock,
drh054889e2005-11-30 03:20:31 +00001042 winCheckReservedLock,
drhcc6bb3e2007-08-31 16:11:35 +00001043 winFileControl,
danielk1977a3d4c882007-03-23 10:08:38 +00001044 winSectorSize,
drh153c62c2007-08-24 03:51:33 +00001045 winDeviceCharacteristics
drh9c06c952005-11-26 00:25:00 +00001046};
1047
drh153c62c2007-08-24 03:51:33 +00001048/***************************************************************************
1049** Here ends the I/O methods that form the sqlite3_io_methods object.
1050**
1051** The next block of code implements the VFS methods.
1052****************************************************************************/
1053
drh054889e2005-11-30 03:20:31 +00001054/*
drh153c62c2007-08-24 03:51:33 +00001055** Convert a UTF-8 filename into whatever form the underlying
1056** operating system wants filenames in. Space to hold the result
drhb11caac2007-08-24 17:52:21 +00001057** is obtained from malloc and must be freed by the calling
drh153c62c2007-08-24 03:51:33 +00001058** function.
drh054889e2005-11-30 03:20:31 +00001059*/
drh153c62c2007-08-24 03:51:33 +00001060static void *convertUtf8Filename(const char *zFilename){
1061 void *zConverted = 0;
1062 if( isNT() ){
1063 zConverted = utf8ToUnicode(zFilename);
drh054889e2005-11-30 03:20:31 +00001064 }else{
drh153c62c2007-08-24 03:51:33 +00001065 zConverted = utf8ToMbcs(zFilename);
drh054889e2005-11-30 03:20:31 +00001066 }
drh153c62c2007-08-24 03:51:33 +00001067 /* caller will handle out of memory */
1068 return zConverted;
1069}
1070
1071/*
1072** Open a file.
1073*/
1074static int winOpen(
1075 sqlite3_vfs *pVfs, /* Not used */
1076 const char *zName, /* Name of the file (UTF-8) */
1077 sqlite3_file *id, /* Write the SQLite file handle here */
1078 int flags, /* Open mode flags */
1079 int *pOutFlags /* Status return flags */
1080){
1081 HANDLE h;
1082 DWORD dwDesiredAccess;
1083 DWORD dwShareMode;
1084 DWORD dwCreationDisposition;
1085 DWORD dwFlagsAndAttributes = 0;
1086 winFile *pFile = (winFile*)id;
1087 void *zConverted = convertUtf8Filename(zName);
1088 if( zConverted==0 ){
1089 return SQLITE_NOMEM;
1090 }
1091
1092 if( flags & SQLITE_OPEN_READWRITE ){
1093 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
1094 }else{
1095 dwDesiredAccess = GENERIC_READ;
1096 }
1097 if( flags & SQLITE_OPEN_CREATE ){
1098 dwCreationDisposition = OPEN_ALWAYS;
1099 }else{
1100 dwCreationDisposition = OPEN_EXISTING;
1101 }
1102 if( flags & SQLITE_OPEN_MAIN_DB ){
1103 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1104 }else{
1105 dwShareMode = 0;
1106 }
1107 if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL
1108 | SQLITE_OPEN_SUBJOURNAL) ){
1109 dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
1110 | FILE_ATTRIBUTE_HIDDEN
1111 | FILE_FLAG_DELETE_ON_CLOSE;
1112 }else{
1113 dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
1114 }
drh496936c2007-10-08 12:21:10 +00001115#if 0
drh153c62c2007-08-24 03:51:33 +00001116 if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){
1117 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
1118 }else{
1119 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
1120 }
drh496936c2007-10-08 12:21:10 +00001121#else
1122 /* Reports from the internet are that performance is always
1123 ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
1124 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
1125#endif
drh153c62c2007-08-24 03:51:33 +00001126 if( isNT() ){
1127 h = CreateFileW((WCHAR*)zConverted,
1128 dwDesiredAccess,
1129 dwShareMode,
1130 NULL,
1131 dwCreationDisposition,
1132 dwFlagsAndAttributes,
1133 NULL
1134 );
1135 }else{
1136#if OS_WINCE
1137 return SQLITE_NOMEM;
1138#else
1139 h = CreateFileA((char*)zConverted,
1140 dwDesiredAccess,
1141 dwShareMode,
1142 NULL,
1143 dwCreationDisposition,
1144 dwFlagsAndAttributes,
1145 NULL
1146 );
1147#endif
1148 }
1149 if( h==INVALID_HANDLE_VALUE ){
drhe1843af2007-08-30 16:46:04 +00001150 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001151 if( flags & SQLITE_OPEN_READWRITE ){
drh153c62c2007-08-24 03:51:33 +00001152 return winOpen(0, zName, id,
1153 ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
1154 }else{
1155 return SQLITE_CANTOPEN;
1156 }
1157 }
1158 if( pOutFlags ){
1159 if( flags & SQLITE_OPEN_READWRITE ){
1160 *pOutFlags = SQLITE_OPEN_READWRITE;
1161 }else{
1162 *pOutFlags = SQLITE_OPEN_READONLY;
1163 }
1164 }
1165 memset(pFile, 0, sizeof(*pFile));
1166 pFile->pMethod = &winIoMethod;
1167 pFile->h = h;
1168#if OS_WINCE
1169 if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
1170 (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
drhaab2e6d2007-10-08 12:22:57 +00001171 && !winceCreateLock(zName, pFile)
drh153c62c2007-08-24 03:51:33 +00001172 ){
1173 CloseHandle(h);
drhb11caac2007-08-24 17:52:21 +00001174 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001175 return SQLITE_CANTOPEN;
1176 }
drh6ac164d2007-09-14 20:32:18 +00001177 if( dwFlagsAndAttributes & FILE_FLAG_DELETE_ON_CLOSE ){
drh153c62c2007-08-24 03:51:33 +00001178 pFile->zDeleteOnClose = zConverted;
1179 }else
1180#endif
1181 {
drhb11caac2007-08-24 17:52:21 +00001182 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001183 }
drhaf5f0402007-09-03 17:09:03 +00001184 OpenCounter(+1);
drh153c62c2007-08-24 03:51:33 +00001185 return SQLITE_OK;
1186}
1187
1188/*
1189** Delete the named file.
1190**
1191** Note that windows does not allow a file to be deleted if some other
1192** process has it open. Sometimes a virus scanner or indexing program
1193** will open a journal file shortly after it is created in order to do
1194** whatever it is it does. While this other process is holding the
1195** file open, we will be unable to delete it. To work around this
1196** problem, we delay 100 milliseconds and try to delete again. Up
1197** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
1198** up and returning an error.
1199*/
1200#define MX_DELETION_ATTEMPTS 3
1201static int winDelete(
1202 sqlite3_vfs *pVfs, /* Not used on win32 */
1203 const char *zFilename, /* Name of file to delete */
1204 int syncDir /* Not used on win32 */
1205){
1206 int cnt = 0;
1207 int rc;
1208 void *zConverted = convertUtf8Filename(zFilename);
1209 if( zConverted==0 ){
1210 return SQLITE_NOMEM;
1211 }
1212 SimulateIOError(return SQLITE_IOERR_DELETE);
1213 if( isNT() ){
1214 do{
1215 rc = DeleteFileW(zConverted);
1216 }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff
1217 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
1218 }else{
1219#if OS_WINCE
1220 return SQLITE_NOMEM;
1221#else
1222 do{
1223 rc = DeleteFileA(zConverted);
1224 }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
1225 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
1226#endif
1227 }
drhb11caac2007-08-24 17:52:21 +00001228 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001229 OSTRACE2("DELETE \"%s\"\n", zFilename);
1230 return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
1231}
1232
1233/*
1234** Check the existance and status of a file.
1235*/
1236static int winAccess(
1237 sqlite3_vfs *pVfs, /* Not used on win32 */
1238 const char *zFilename, /* Name of file to check */
1239 int flags /* Type of test to make on this file */
1240){
1241 DWORD attr;
1242 int rc;
1243 void *zConverted = convertUtf8Filename(zFilename);
1244 if( zConverted==0 ){
1245 return SQLITE_NOMEM;
1246 }
1247 if( isNT() ){
1248 attr = GetFileAttributesW((WCHAR*)zConverted);
1249 }else{
1250#if OS_WINCE
1251 return SQLITE_NOMEM;
1252#else
1253 attr = GetFileAttributesA((char*)zConverted);
1254#endif
1255 }
drhb11caac2007-08-24 17:52:21 +00001256 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001257 switch( flags ){
drh50d3f902007-08-27 21:10:36 +00001258 case SQLITE_ACCESS_READ:
drh153c62c2007-08-24 03:51:33 +00001259 case SQLITE_ACCESS_EXISTS:
1260 rc = attr!=0xffffffff;
1261 break;
1262 case SQLITE_ACCESS_READWRITE:
1263 rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
1264 break;
drh153c62c2007-08-24 03:51:33 +00001265 default:
1266 assert(!"Invalid flags argument");
1267 }
1268 return rc;
drh054889e2005-11-30 03:20:31 +00001269}
1270
1271
drh153c62c2007-08-24 03:51:33 +00001272/*
1273** Create a temporary file name in zBuf. zBuf must be big enough to
1274** hold at pVfs->mxPathname characters.
1275*/
danielk1977adfb9b02007-09-17 07:02:56 +00001276static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drh153c62c2007-08-24 03:51:33 +00001277 static char zChars[] =
1278 "abcdefghijklmnopqrstuvwxyz"
1279 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1280 "0123456789";
1281 int i, j;
1282 char zTempPath[MAX_PATH+1];
1283 if( sqlite3_temp_directory ){
1284 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
1285 }else if( isNT() ){
1286 char *zMulti;
1287 WCHAR zWidePath[MAX_PATH];
1288 GetTempPathW(MAX_PATH-30, zWidePath);
1289 zMulti = unicodeToUtf8(zWidePath);
1290 if( zMulti ){
drhb11caac2007-08-24 17:52:21 +00001291 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
1292 free(zMulti);
drh153c62c2007-08-24 03:51:33 +00001293 }else{
1294 return SQLITE_NOMEM;
1295 }
1296 }else{
1297 char *zUtf8;
1298 char zMbcsPath[MAX_PATH];
1299 GetTempPathA(MAX_PATH-30, zMbcsPath);
1300 zUtf8 = mbcsToUtf8(zMbcsPath);
1301 if( zUtf8 ){
drhb11caac2007-08-24 17:52:21 +00001302 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
1303 free(zUtf8);
drh153c62c2007-08-24 03:51:33 +00001304 }else{
1305 return SQLITE_NOMEM;
1306 }
1307 }
1308 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
1309 zTempPath[i] = 0;
drhf8693472007-09-01 02:13:10 +00001310 sqlite3_snprintf(pVfs->mxPathname-30, zBuf,
1311 "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
1312 j = strlen(zBuf);
1313 sqlite3Randomness(20, &zBuf[j]);
1314 for(i=0; i<20; i++, j++){
1315 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
drh153c62c2007-08-24 03:51:33 +00001316 }
drhf8693472007-09-01 02:13:10 +00001317 zBuf[j] = 0;
drh153c62c2007-08-24 03:51:33 +00001318 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
1319 return SQLITE_OK;
1320}
drh0ccebe72005-06-07 22:22:50 +00001321
drh153c62c2007-08-24 03:51:33 +00001322/*
1323** Turn a relative pathname into a full pathname. Write the full
1324** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
1325** bytes in size.
1326*/
1327static int winFullPathname(
danielk1977adfb9b02007-09-17 07:02:56 +00001328 sqlite3_vfs *pVfs, /* Pointer to vfs object */
1329 const char *zRelative, /* Possibly relative input path */
1330 int nFull, /* Size of output buffer in bytes */
1331 char *zFull /* Output buffer */
drh153c62c2007-08-24 03:51:33 +00001332){
1333
1334#if defined(__CYGWIN__)
1335 cygwin_conv_to_full_win32_path(zRelative, zFull);
danielk1977076f1c02007-09-12 14:09:23 +00001336 return SQLITE_OK;
drh153c62c2007-08-24 03:51:33 +00001337#endif
1338
1339#if OS_WINCE
1340 /* WinCE has no concept of a relative pathname, or so I am told. */
1341 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
1342#endif
1343
1344#if !OS_WINCE && !defined(__CYGWIN__)
1345 int nByte;
1346 void *zConverted;
1347 char *zOut;
1348 zConverted = convertUtf8Filename(zRelative);
1349 if( isNT() ){
1350 WCHAR *zTemp;
1351 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001352 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001353 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001354 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001355 return SQLITE_NOMEM;
1356 }
1357 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001358 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001359 zOut = unicodeToUtf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001360 free(zTemp);
drh153c62c2007-08-24 03:51:33 +00001361 }else{
1362 char *zTemp;
1363 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drhb11caac2007-08-24 17:52:21 +00001364 zTemp = malloc( nByte*sizeof(zTemp[0]) );
drh153c62c2007-08-24 03:51:33 +00001365 if( zTemp==0 ){
drhb11caac2007-08-24 17:52:21 +00001366 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001367 return SQLITE_NOMEM;
1368 }
1369 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drhb11caac2007-08-24 17:52:21 +00001370 free(zConverted);
drh153c62c2007-08-24 03:51:33 +00001371 zOut = mbcsToUtf8(zTemp);
drhb11caac2007-08-24 17:52:21 +00001372 free(zTemp);
drh153c62c2007-08-24 03:51:33 +00001373 }
1374 if( zOut ){
drhb11caac2007-08-24 17:52:21 +00001375 sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut);
1376 free(zOut);
drh153c62c2007-08-24 03:51:33 +00001377 return SQLITE_OK;
1378 }else{
1379 return SQLITE_NOMEM;
1380 }
1381#endif
1382}
1383
1384#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh761df872006-12-21 01:29:22 +00001385/*
1386** Interfaces for opening a shared library, finding entry points
1387** within the shared library, and closing the shared library.
1388*/
drh153c62c2007-08-24 03:51:33 +00001389/*
1390** Interfaces for opening a shared library, finding entry points
1391** within the shared library, and closing the shared library.
1392*/
1393static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
drh761df872006-12-21 01:29:22 +00001394 HANDLE h;
1395 void *zConverted = convertUtf8Filename(zFilename);
1396 if( zConverted==0 ){
1397 return 0;
1398 }
1399 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00001400 h = LoadLibraryW((WCHAR*)zConverted);
drh761df872006-12-21 01:29:22 +00001401 }else{
1402#if OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00001403 return 0;
drh761df872006-12-21 01:29:22 +00001404#else
drh584c0942006-12-21 03:20:40 +00001405 h = LoadLibraryA((char*)zConverted);
drh761df872006-12-21 01:29:22 +00001406#endif
1407 }
drhb11caac2007-08-24 17:52:21 +00001408 free(zConverted);
drh761df872006-12-21 01:29:22 +00001409 return (void*)h;
drh761df872006-12-21 01:29:22 +00001410}
drh153c62c2007-08-24 03:51:33 +00001411static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
drhee8683e2007-10-05 14:49:45 +00001412 FormatMessageA(
drh153c62c2007-08-24 03:51:33 +00001413 FORMAT_MESSAGE_FROM_SYSTEM,
1414 NULL,
1415 GetLastError(),
1416 0,
1417 zBufOut,
1418 nBuf-1,
1419 0
1420 );
1421}
1422void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
drh2a4d54b2006-12-21 02:21:56 +00001423#if OS_WINCE
1424 /* The GetProcAddressA() routine is only available on wince. */
1425 return GetProcAddressA((HANDLE)pHandle, zSymbol);
1426#else
1427 /* All other windows platforms expect GetProcAddress() to take
1428 ** an Ansi string regardless of the _UNICODE setting */
drh761df872006-12-21 01:29:22 +00001429 return GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001430#endif
drh761df872006-12-21 01:29:22 +00001431}
drh153c62c2007-08-24 03:51:33 +00001432void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
1433 FreeLibrary((HANDLE)pHandle);
drh761df872006-12-21 01:29:22 +00001434}
drh153c62c2007-08-24 03:51:33 +00001435#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
1436 #define winDlOpen 0
1437 #define winDlError 0
1438 #define winDlSym 0
1439 #define winDlClose 0
1440#endif
1441
drh761df872006-12-21 01:29:22 +00001442
drh0ccebe72005-06-07 22:22:50 +00001443/*
drh153c62c2007-08-24 03:51:33 +00001444** Write up to nBuf bytes of randomness into zBuf.
drhbbd42a62004-05-22 17:41:58 +00001445*/
drh153c62c2007-08-24 03:51:33 +00001446static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
drhd1a79312007-09-03 13:06:11 +00001447 int n = 0;
drh86742612007-09-05 17:06:03 +00001448 if( sizeof(SYSTEMTIME)<=nBuf-n ){
drhd1a79312007-09-03 13:06:11 +00001449 SYSTEMTIME x;
1450 GetSystemTime(&x);
1451 memcpy(&zBuf[n], &x, sizeof(x));
1452 n += sizeof(x);
drh153c62c2007-08-24 03:51:33 +00001453 }
drhd1a79312007-09-03 13:06:11 +00001454 if( sizeof(DWORD)<=nBuf-n ){
1455 DWORD pid = GetCurrentProcessId();
1456 memcpy(&zBuf[n], &pid, sizeof(pid));
1457 n += sizeof(pid);
1458 }
1459 if( sizeof(DWORD)<=nBuf-n ){
1460 DWORD cnt = GetTickCount();
1461 memcpy(&zBuf[n], &cnt, sizeof(cnt));
1462 n += sizeof(cnt);
1463 }
1464 if( sizeof(LARGE_INTEGER)<=nBuf-n ){
1465 LARGE_INTEGER i;
1466 QueryPerformanceCounter(&i);
1467 memcpy(&zBuf[n], &i, sizeof(i));
1468 n += sizeof(i);
1469 }
1470 return n;
drhbbd42a62004-05-22 17:41:58 +00001471}
1472
drh153c62c2007-08-24 03:51:33 +00001473
drhbbd42a62004-05-22 17:41:58 +00001474/*
1475** Sleep for a little while. Return the amount of time slept.
1476*/
drh153c62c2007-08-24 03:51:33 +00001477static int winSleep(sqlite3_vfs *pVfs, int microsec){
1478 Sleep((microsec+999)/1000);
1479 return ((microsec+999)/1000)*1000;
drhbbd42a62004-05-22 17:41:58 +00001480}
1481
1482/*
drhbbd42a62004-05-22 17:41:58 +00001483** The following variable, if set to a non-zero value, becomes the result
1484** returned from sqlite3OsCurrentTime(). This is used for testing.
1485*/
1486#ifdef SQLITE_TEST
1487int sqlite3_current_time = 0;
1488#endif
1489
1490/*
1491** Find the current time (in Universal Coordinated Time). Write the
1492** current time and date as a Julian Day number into *prNow and
1493** return 0. Return 1 if the time and date cannot be found.
1494*/
drh153c62c2007-08-24 03:51:33 +00001495int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001496 FILETIME ft;
1497 /* FILETIME structure is a 64-bit value representing the number of
1498 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1499 */
1500 double now;
drhcc78fea2006-01-06 16:17:05 +00001501#if OS_WINCE
1502 SYSTEMTIME time;
1503 GetSystemTime(&time);
1504 SystemTimeToFileTime(&time,&ft);
1505#else
drhbbd42a62004-05-22 17:41:58 +00001506 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001507#endif
drhbbd42a62004-05-22 17:41:58 +00001508 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1509 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1510#ifdef SQLITE_TEST
1511 if( sqlite3_current_time ){
1512 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1513 }
1514#endif
1515 return 0;
1516}
1517
drhb4bc7052006-01-11 23:40:33 +00001518
1519/*
drh153c62c2007-08-24 03:51:33 +00001520** Return a pointer to the sqlite3DefaultVfs structure. We use
1521** a function rather than give the structure global scope because
1522** some compilers (MSVC) do not allow forward declarations of
1523** initialized structures.
danielk197713a68c32005-12-15 10:11:30 +00001524*/
drh153c62c2007-08-24 03:51:33 +00001525sqlite3_vfs *sqlite3OsDefaultVfs(void){
1526 static sqlite3_vfs winVfs = {
1527 1, /* iVersion */
1528 sizeof(winFile), /* szOsFile */
1529 MAX_PATH, /* mxPathname */
drh153c62c2007-08-24 03:51:33 +00001530 0, /* pNext */
1531 "win32", /* zName */
1532 0, /* pAppData */
1533
1534 winOpen, /* xOpen */
1535 winDelete, /* xDelete */
1536 winAccess, /* xAccess */
danielk197776ee37f2007-09-17 06:06:39 +00001537 winGetTempname, /* xGetTempName */
drh153c62c2007-08-24 03:51:33 +00001538 winFullPathname, /* xFullPathname */
1539 winDlOpen, /* xDlOpen */
1540 winDlError, /* xDlError */
1541 winDlSym, /* xDlSym */
1542 winDlClose, /* xDlClose */
1543 winRandomness, /* xRandomness */
1544 winSleep, /* xSleep */
1545 winCurrentTime /* xCurrentTime */
1546 };
1547
1548 return &winVfs;
danielk197713a68c32005-12-15 10:11:30 +00001549}
drh153c62c2007-08-24 03:51:33 +00001550
drhbbd42a62004-05-22 17:41:58 +00001551#endif /* OS_WIN */