monotone

monotone Mtn Source Tree

Root/sqlite/os_win.c

1/*
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*/
15#include "sqliteInt.h"
16#include "os.h"
17#if OS_WIN /* This file is used for windows only */
18
19#include <winbase.h>
20
21#ifdef __CYGWIN__
22# include <sys/cygwin.h>
23#endif
24
25/*
26** Macros used to determine whether or not to use threads.
27*/
28#if defined(THREADSAFE) && THREADSAFE
29# define SQLITE_W32_THREADS 1
30#endif
31
32/*
33** Include code that is common to all os_*.c files
34*/
35#include "os_common.h"
36
37/*
38** Determine if we are dealing with WindowsCE - which has a much
39** reduced API.
40*/
41#if defined(_WIN32_WCE)
42# define OS_WINCE 1
43# define AreFileApisANSI() 1
44#else
45# define OS_WINCE 0
46#endif
47
48/*
49** WinCE lacks native support for file locking so we have to fake it
50** with some code of our own.
51*/
52#if OS_WINCE
53typedef struct winceLock {
54 int nReaders; /* Number of reader locks obtained */
55 BOOL bPending; /* Indicates a pending lock has been obtained */
56 BOOL bReserved; /* Indicates a reserved lock has been obtained */
57 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
58} winceLock;
59#endif
60
61/*
62** The winFile structure is a subclass of OsFile specific to the win32
63** portability layer.
64*/
65typedef struct winFile winFile;
66struct winFile {
67 IoMethod const *pMethod;/* Must be first */
68 HANDLE h; /* Handle for accessing the file */
69 unsigned char locktype; /* Type of lock currently held on this file */
70 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
71#if OS_WINCE
72 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
73 HANDLE hMutex; /* Mutex used to control access to shared lock */
74 HANDLE hShared; /* Shared memory segment used for locking */
75 winceLock local; /* Locks obtained by this instance of winFile */
76 winceLock *shared; /* Global shared lock memory for the file */
77#endif
78};
79
80
81/*
82** Do not include any of the File I/O interface procedures if the
83** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
84** will be in-memory only)
85*/
86#ifndef SQLITE_OMIT_DISKIO
87
88/*
89** The following variable is (normally) set once and never changes
90** thereafter. It records whether the operating system is Win95
91** or WinNT.
92**
93** 0: Operating system unknown.
94** 1: Operating system is Win95.
95** 2: Operating system is WinNT.
96**
97** In order to facilitate testing on a WinNT system, the test fixture
98** can manually set this value to 1 to emulate Win98 behavior.
99*/
100int sqlite3_os_type = 0;
101
102/*
103** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
104** or WinCE. Return false (zero) for Win95, Win98, or WinME.
105**
106** Here is an interesting observation: Win95, Win98, and WinME lack
107** the LockFileEx() API. But we can still statically link against that
108** API as long as we don't call it win running Win95/98/ME. A call to
109** this routine is used to determine if the host is Win95/98/ME or
110** WinNT/2K/XP so that we will know whether or not we can safely call
111** the LockFileEx() API.
112*/
113#if OS_WINCE
114# define isNT() (1)
115#else
116 static int isNT(void){
117 if( sqlite3_os_type==0 ){
118 OSVERSIONINFO sInfo;
119 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
120 GetVersionEx(&sInfo);
121 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
122 }
123 return sqlite3_os_type==2;
124 }
125#endif /* OS_WINCE */
126
127/*
128** Convert a UTF-8 string to microsoft unicode (UTF-16?).
129**
130** Space to hold the returned string is obtained from sqliteMalloc.
131*/
132static WCHAR *utf8ToUnicode(const char *zFilename){
133 int nChar;
134 WCHAR *zWideFilename;
135
136 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
137 zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
138 if( zWideFilename==0 ){
139 return 0;
140 }
141 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
142 if( nChar==0 ){
143 sqliteFree(zWideFilename);
144 zWideFilename = 0;
145 }
146 return zWideFilename;
147}
148
149/*
150** Convert microsoft unicode to UTF-8. Space to hold the returned string is
151** obtained from sqliteMalloc().
152*/
153static char *unicodeToUtf8(const WCHAR *zWideFilename){
154 int nByte;
155 char *zFilename;
156
157 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
158 zFilename = sqliteMalloc( nByte );
159 if( zFilename==0 ){
160 return 0;
161 }
162 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
163 0, 0);
164 if( nByte == 0 ){
165 sqliteFree(zFilename);
166 zFilename = 0;
167 }
168 return zFilename;
169}
170
171/*
172** Convert an ansi string to microsoft unicode, based on the
173** current codepage settings for file apis.
174**
175** Space to hold the returned string is obtained
176** from sqliteMalloc.
177*/
178static WCHAR *mbcsToUnicode(const char *zFilename){
179 int nByte;
180 WCHAR *zMbcsFilename;
181 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
182
183 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
184 zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) );
185 if( zMbcsFilename==0 ){
186 return 0;
187 }
188 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
189 if( nByte==0 ){
190 sqliteFree(zMbcsFilename);
191 zMbcsFilename = 0;
192 }
193 return zMbcsFilename;
194}
195
196/*
197** Convert microsoft unicode to multibyte character string, based on the
198** user's Ansi codepage.
199**
200** Space to hold the returned string is obtained from
201** sqliteMalloc().
202*/
203static char *unicodeToMbcs(const WCHAR *zWideFilename){
204 int nByte;
205 char *zFilename;
206 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
207
208 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
209 zFilename = sqliteMalloc( nByte );
210 if( zFilename==0 ){
211 return 0;
212 }
213 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
214 0, 0);
215 if( nByte == 0 ){
216 sqliteFree(zFilename);
217 zFilename = 0;
218 }
219 return zFilename;
220}
221
222/*
223** Convert multibyte character string to UTF-8. Space to hold the
224** returned string is obtained from sqliteMalloc().
225*/
226static char *mbcsToUtf8(const char *zFilename){
227 char *zFilenameUtf8;
228 WCHAR *zTmpWide;
229
230 zTmpWide = mbcsToUnicode(zFilename);
231 if( zTmpWide==0 ){
232 return 0;
233 }
234 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
235 sqliteFree(zTmpWide);
236 return zFilenameUtf8;
237}
238
239/*
240** Convert UTF-8 to multibyte character string. Space to hold the
241** returned string is obtained from sqliteMalloc().
242*/
243static char *utf8ToMbcs(const char *zFilename){
244 char *zFilenameMbcs;
245 WCHAR *zTmpWide;
246
247 zTmpWide = utf8ToUnicode(zFilename);
248 if( zTmpWide==0 ){
249 return 0;
250 }
251 zFilenameMbcs = unicodeToMbcs(zTmpWide);
252 sqliteFree(zTmpWide);
253 return zFilenameMbcs;
254}
255
256#if OS_WINCE
257/*************************************************************************
258** This section contains code for WinCE only.
259*/
260/*
261** WindowsCE does not have a localtime() function. So create a
262** substitute.
263*/
264#include <time.h>
265struct tm *__cdecl localtime(const time_t *t)
266{
267 static struct tm y;
268 FILETIME uTm, lTm;
269 SYSTEMTIME pTm;
270 i64 t64;
271 t64 = *t;
272 t64 = (t64 + 11644473600)*10000000;
273 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
274 uTm.dwHighDateTime= t64 >> 32;
275 FileTimeToLocalFileTime(&uTm,&lTm);
276 FileTimeToSystemTime(&lTm,&pTm);
277 y.tm_year = pTm.wYear - 1900;
278 y.tm_mon = pTm.wMonth - 1;
279 y.tm_wday = pTm.wDayOfWeek;
280 y.tm_mday = pTm.wDay;
281 y.tm_hour = pTm.wHour;
282 y.tm_min = pTm.wMinute;
283 y.tm_sec = pTm.wSecond;
284 return &y;
285}
286
287/* This will never be called, but defined to make the code compile */
288#define GetTempPathA(a,b)
289
290#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
291#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
292#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
293
294#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
295
296/*
297** Acquire a lock on the handle h
298*/
299static void winceMutexAcquire(HANDLE h){
300 DWORD dwErr;
301 do {
302 dwErr = WaitForSingleObject(h, INFINITE);
303 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
304}
305/*
306** Release a lock acquired by winceMutexAcquire()
307*/
308#define winceMutexRelease(h) ReleaseMutex(h)
309
310/*
311** Create the mutex and shared memory used for locking in the file
312** descriptor pFile
313*/
314static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
315 WCHAR *zTok;
316 WCHAR *zName = utf8ToUnicode(zFilename);
317 BOOL bInit = TRUE;
318
319 /* Initialize the local lockdata */
320 ZeroMemory(&pFile->local, sizeof(pFile->local));
321
322 /* Replace the backslashes from the filename and lowercase it
323 ** to derive a mutex name. */
324 zTok = CharLowerW(zName);
325 for (;*zTok;zTok++){
326 if (*zTok == '\\') *zTok = '_';
327 }
328
329 /* Create/open the named mutex */
330 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
331 if (!pFile->hMutex){
332 sqliteFree(zName);
333 return FALSE;
334 }
335
336 /* Acquire the mutex before continuing */
337 winceMutexAcquire(pFile->hMutex);
338
339 /* Since the names of named mutexes, semaphores, file mappings etc are
340 ** case-sensitive, take advantage of that by uppercasing the mutex name
341 ** and using that as the shared filemapping name.
342 */
343 CharUpperW(zName);
344 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
345 PAGE_READWRITE, 0, sizeof(winceLock),
346 zName);
347
348 /* Set a flag that indicates we're the first to create the memory so it
349 ** must be zero-initialized */
350 if (GetLastError() == ERROR_ALREADY_EXISTS){
351 bInit = FALSE;
352 }
353
354 sqliteFree(zName);
355
356 /* If we succeeded in making the shared memory handle, map it. */
357 if (pFile->hShared){
358 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
359 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
360 /* If mapping failed, close the shared memory handle and erase it */
361 if (!pFile->shared){
362 CloseHandle(pFile->hShared);
363 pFile->hShared = NULL;
364 }
365 }
366
367 /* If shared memory could not be created, then close the mutex and fail */
368 if (pFile->hShared == NULL){
369 winceMutexRelease(pFile->hMutex);
370 CloseHandle(pFile->hMutex);
371 pFile->hMutex = NULL;
372 return FALSE;
373 }
374
375 /* Initialize the shared memory if we're supposed to */
376 if (bInit) {
377 ZeroMemory(pFile->shared, sizeof(winceLock));
378 }
379
380 winceMutexRelease(pFile->hMutex);
381 return TRUE;
382}
383
384/*
385** Destroy the part of winFile that deals with wince locks
386*/
387static void winceDestroyLock(winFile *pFile){
388 if (pFile->hMutex){
389 /* Acquire the mutex */
390 winceMutexAcquire(pFile->hMutex);
391
392 /* The following blocks should probably assert in debug mode, but they
393 are to cleanup in case any locks remained open */
394 if (pFile->local.nReaders){
395 pFile->shared->nReaders --;
396 }
397 if (pFile->local.bReserved){
398 pFile->shared->bReserved = FALSE;
399 }
400 if (pFile->local.bPending){
401 pFile->shared->bPending = FALSE;
402 }
403 if (pFile->local.bExclusive){
404 pFile->shared->bExclusive = FALSE;
405 }
406
407 /* De-reference and close our copy of the shared memory handle */
408 UnmapViewOfFile(pFile->shared);
409 CloseHandle(pFile->hShared);
410
411 if( pFile->zDeleteOnClose ){
412 DeleteFileW(pFile->zDeleteOnClose);
413 sqliteFree(pFile->zDeleteOnClose);
414 pFile->zDeleteOnClose = 0;
415 }
416
417 /* Done with the mutex */
418 winceMutexRelease(pFile->hMutex);
419 CloseHandle(pFile->hMutex);
420 pFile->hMutex = NULL;
421 }
422}
423
424/*
425** An implementation of the LockFile() API of windows for wince
426*/
427static BOOL winceLockFile(
428 HANDLE *phFile,
429 DWORD dwFileOffsetLow,
430 DWORD dwFileOffsetHigh,
431 DWORD nNumberOfBytesToLockLow,
432 DWORD nNumberOfBytesToLockHigh
433){
434 winFile *pFile = HANDLE_TO_WINFILE(phFile);
435 BOOL bReturn = FALSE;
436
437 if (!pFile->hMutex) return TRUE;
438 winceMutexAcquire(pFile->hMutex);
439
440 /* Wanting an exclusive lock? */
441 if (dwFileOffsetLow == SHARED_FIRST
442 && nNumberOfBytesToLockLow == SHARED_SIZE){
443 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
444 pFile->shared->bExclusive = TRUE;
445 pFile->local.bExclusive = TRUE;
446 bReturn = TRUE;
447 }
448 }
449
450 /* Want a read-only lock? */
451 else if ((dwFileOffsetLow >= SHARED_FIRST &&
452 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
453 nNumberOfBytesToLockLow == 1){
454 if (pFile->shared->bExclusive == 0){
455 pFile->local.nReaders ++;
456 if (pFile->local.nReaders == 1){
457 pFile->shared->nReaders ++;
458 }
459 bReturn = TRUE;
460 }
461 }
462
463 /* Want a pending lock? */
464 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
465 /* If no pending lock has been acquired, then acquire it */
466 if (pFile->shared->bPending == 0) {
467 pFile->shared->bPending = TRUE;
468 pFile->local.bPending = TRUE;
469 bReturn = TRUE;
470 }
471 }
472 /* Want a reserved lock? */
473 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
474 if (pFile->shared->bReserved == 0) {
475 pFile->shared->bReserved = TRUE;
476 pFile->local.bReserved = TRUE;
477 bReturn = TRUE;
478 }
479 }
480
481 winceMutexRelease(pFile->hMutex);
482 return bReturn;
483}
484
485/*
486** An implementation of the UnlockFile API of windows for wince
487*/
488static BOOL winceUnlockFile(
489 HANDLE *phFile,
490 DWORD dwFileOffsetLow,
491 DWORD dwFileOffsetHigh,
492 DWORD nNumberOfBytesToUnlockLow,
493 DWORD nNumberOfBytesToUnlockHigh
494){
495 winFile *pFile = HANDLE_TO_WINFILE(phFile);
496 BOOL bReturn = FALSE;
497
498 if (!pFile->hMutex) return TRUE;
499 winceMutexAcquire(pFile->hMutex);
500
501 /* Releasing a reader lock or an exclusive lock */
502 if (dwFileOffsetLow >= SHARED_FIRST &&
503 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
504 /* Did we have an exclusive lock? */
505 if (pFile->local.bExclusive){
506 pFile->local.bExclusive = FALSE;
507 pFile->shared->bExclusive = FALSE;
508 bReturn = TRUE;
509 }
510
511 /* Did we just have a reader lock? */
512 else if (pFile->local.nReaders){
513 pFile->local.nReaders --;
514 if (pFile->local.nReaders == 0)
515 {
516 pFile->shared->nReaders --;
517 }
518 bReturn = TRUE;
519 }
520 }
521
522 /* Releasing a pending lock */
523 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
524 if (pFile->local.bPending){
525 pFile->local.bPending = FALSE;
526 pFile->shared->bPending = FALSE;
527 bReturn = TRUE;
528 }
529 }
530 /* Releasing a reserved lock */
531 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
532 if (pFile->local.bReserved) {
533 pFile->local.bReserved = FALSE;
534 pFile->shared->bReserved = FALSE;
535 bReturn = TRUE;
536 }
537 }
538
539 winceMutexRelease(pFile->hMutex);
540 return bReturn;
541}
542
543/*
544** An implementation of the LockFileEx() API of windows for wince
545*/
546static BOOL winceLockFileEx(
547 HANDLE *phFile,
548 DWORD dwFlags,
549 DWORD dwReserved,
550 DWORD nNumberOfBytesToLockLow,
551 DWORD nNumberOfBytesToLockHigh,
552 LPOVERLAPPED lpOverlapped
553){
554 /* If the caller wants a shared read lock, forward this call
555 ** to winceLockFile */
556 if (lpOverlapped->Offset == SHARED_FIRST &&
557 dwFlags == 1 &&
558 nNumberOfBytesToLockLow == SHARED_SIZE){
559 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
560 }
561 return FALSE;
562}
563/*
564** End of the special code for wince
565*****************************************************************************/
566#endif /* OS_WINCE */
567
568/*
569** Convert a UTF-8 filename into whatever form the underlying
570** operating system wants filenames in. Space to hold the result
571** is obtained from sqliteMalloc and must be freed by the calling
572** function.
573*/
574static void *convertUtf8Filename(const char *zFilename){
575 void *zConverted = 0;
576 if( isNT() ){
577 zConverted = utf8ToUnicode(zFilename);
578 }else{
579 zConverted = utf8ToMbcs(zFilename);
580 }
581 /* caller will handle out of memory */
582 return zConverted;
583}
584
585/*
586** Delete the named file.
587**
588** Note that windows does not allow a file to be deleted if some other
589** process has it open. Sometimes a virus scanner or indexing program
590** will open a journal file shortly after it is created in order to do
591** whatever it is it does. While this other process is holding the
592** file open, we will be unable to delete it. To work around this
593** problem, we delay 100 milliseconds and try to delete again. Up
594** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
595** up and returning an error.
596*/
597#define MX_DELETION_ATTEMPTS 3
598int sqlite3WinDelete(const char *zFilename){
599 int cnt = 0;
600 int rc;
601 void *zConverted = convertUtf8Filename(zFilename);
602 if( zConverted==0 ){
603 return SQLITE_NOMEM;
604 }
605 SimulateIOError(return SQLITE_IOERR_DELETE);
606 if( isNT() ){
607 do{
608 rc = DeleteFileW(zConverted);
609 }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff
610 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
611 }else{
612#if OS_WINCE
613 return SQLITE_NOMEM;
614#else
615 do{
616 rc = DeleteFileA(zConverted);
617 }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
618 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
619#endif
620 }
621 sqliteFree(zConverted);
622 OSTRACE2("DELETE \"%s\"\n", zFilename);
623 return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
624}
625
626/*
627** Return TRUE if the named file exists.
628*/
629int sqlite3WinFileExists(const char *zFilename){
630 int exists = 0;
631 void *zConverted = convertUtf8Filename(zFilename);
632 if( zConverted==0 ){
633 return SQLITE_NOMEM;
634 }
635 if( isNT() ){
636 exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff;
637 }else{
638#if OS_WINCE
639 return SQLITE_NOMEM;
640#else
641 exists = GetFileAttributesA((char*)zConverted) != 0xffffffff;
642#endif
643 }
644 sqliteFree(zConverted);
645 return exists;
646}
647
648/* Forward declaration */
649static int allocateWinFile(winFile *pInit, OsFile **pId);
650
651/*
652** Attempt to open a file for both reading and writing. If that
653** fails, try opening it read-only. If the file does not exist,
654** try to create it.
655**
656** On success, a handle for the open file is written to *id
657** and *pReadonly is set to 0 if the file was opened for reading and
658** writing or 1 if the file was opened read-only. The function returns
659** SQLITE_OK.
660**
661** On failure, the function returns SQLITE_CANTOPEN and leaves
662** *id and *pReadonly unchanged.
663*/
664int sqlite3WinOpenReadWrite(
665 const char *zFilename,
666 OsFile **pId,
667 int *pReadonly
668){
669 winFile f;
670 HANDLE h;
671 void *zConverted = convertUtf8Filename(zFilename);
672 if( zConverted==0 ){
673 return SQLITE_NOMEM;
674 }
675 assert( *pId==0 );
676
677 if( isNT() ){
678 h = CreateFileW((WCHAR*)zConverted,
679 GENERIC_READ | GENERIC_WRITE,
680 FILE_SHARE_READ | FILE_SHARE_WRITE,
681 NULL,
682 OPEN_ALWAYS,
683 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
684 NULL
685 );
686 if( h==INVALID_HANDLE_VALUE ){
687 h = CreateFileW((WCHAR*)zConverted,
688 GENERIC_READ,
689 FILE_SHARE_READ | FILE_SHARE_WRITE,
690 NULL,
691 OPEN_ALWAYS,
692 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
693 NULL
694 );
695 if( h==INVALID_HANDLE_VALUE ){
696 sqliteFree(zConverted);
697 return SQLITE_CANTOPEN;
698 }
699 *pReadonly = 1;
700 }else{
701 *pReadonly = 0;
702 }
703#if OS_WINCE
704 if (!winceCreateLock(zFilename, &f)){
705 CloseHandle(h);
706 sqliteFree(zConverted);
707 return SQLITE_CANTOPEN;
708 }
709#endif
710 }else{
711#if OS_WINCE
712 return SQLITE_NOMEM;
713#else
714 h = CreateFileA((char*)zConverted,
715 GENERIC_READ | GENERIC_WRITE,
716 FILE_SHARE_READ | FILE_SHARE_WRITE,
717 NULL,
718 OPEN_ALWAYS,
719 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
720 NULL
721 );
722 if( h==INVALID_HANDLE_VALUE ){
723 h = CreateFileA((char*)zConverted,
724 GENERIC_READ,
725 FILE_SHARE_READ | FILE_SHARE_WRITE,
726 NULL,
727 OPEN_ALWAYS,
728 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
729 NULL
730 );
731 if( h==INVALID_HANDLE_VALUE ){
732 sqliteFree(zConverted);
733 return SQLITE_CANTOPEN;
734 }
735 *pReadonly = 1;
736 }else{
737 *pReadonly = 0;
738 }
739#endif /* OS_WINCE */
740 }
741
742 sqliteFree(zConverted);
743
744 f.h = h;
745#if OS_WINCE
746 f.zDeleteOnClose = 0;
747#endif
748 OSTRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
749 return allocateWinFile(&f, pId);
750}
751
752
753/*
754** Attempt to open a new file for exclusive access by this process.
755** The file will be opened for both reading and writing. To avoid
756** a potential security problem, we do not allow the file to have
757** previously existed. Nor do we allow the file to be a symbolic
758** link.
759**
760** If delFlag is true, then make arrangements to automatically delete
761** the file when it is closed.
762**
763** On success, write the file handle into *id and return SQLITE_OK.
764**
765** On failure, return SQLITE_CANTOPEN.
766**
767** Sometimes if we have just deleted a prior journal file, windows
768** will fail to open a new one because there is a "pending delete".
769** To work around this bug, we pause for 100 milliseconds and attempt
770** a second open after the first one fails. The whole operation only
771** fails if both open attempts are unsuccessful.
772*/
773int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
774 winFile f;
775 HANDLE h;
776 DWORD fileflags;
777 void *zConverted = convertUtf8Filename(zFilename);
778 if( zConverted==0 ){
779 return SQLITE_NOMEM;
780 }
781 assert( *pId == 0 );
782 fileflags = FILE_FLAG_RANDOM_ACCESS;
783#if !OS_WINCE
784 if( delFlag ){
785 fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
786 }
787#endif
788 if( isNT() ){
789 int cnt = 0;
790 do{
791 h = CreateFileW((WCHAR*)zConverted,
792 GENERIC_READ | GENERIC_WRITE,
793 0,
794 NULL,
795 CREATE_ALWAYS,
796 fileflags,
797 NULL
798 );
799 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
800 }else{
801#if OS_WINCE
802 return SQLITE_NOMEM;
803#else
804 int cnt = 0;
805 do{
806 h = CreateFileA((char*)zConverted,
807 GENERIC_READ | GENERIC_WRITE,
808 0,
809 NULL,
810 CREATE_ALWAYS,
811 fileflags,
812 NULL
813 );
814 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
815#endif /* OS_WINCE */
816 }
817#if OS_WINCE
818 if( delFlag && h!=INVALID_HANDLE_VALUE ){
819 f.zDeleteOnClose = zConverted;
820 zConverted = 0;
821 }
822 f.hMutex = NULL;
823#endif
824 sqliteFree(zConverted);
825 if( h==INVALID_HANDLE_VALUE ){
826 return SQLITE_CANTOPEN;
827 }
828 f.h = h;
829 OSTRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
830 return allocateWinFile(&f, pId);
831}
832
833/*
834** Attempt to open a new file for read-only access.
835**
836** On success, write the file handle into *id and return SQLITE_OK.
837**
838** On failure, return SQLITE_CANTOPEN.
839*/
840int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
841 winFile f;
842 HANDLE h;
843 void *zConverted = convertUtf8Filename(zFilename);
844 if( zConverted==0 ){
845 return SQLITE_NOMEM;
846 }
847 assert( *pId==0 );
848 if( isNT() ){
849 h = CreateFileW((WCHAR*)zConverted,
850 GENERIC_READ,
851 0,
852 NULL,
853 OPEN_EXISTING,
854 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
855 NULL
856 );
857 }else{
858#if OS_WINCE
859 return SQLITE_NOMEM;
860#else
861 h = CreateFileA((char*)zConverted,
862 GENERIC_READ,
863 0,
864 NULL,
865 OPEN_EXISTING,
866 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
867 NULL
868 );
869#endif
870 }
871 sqliteFree(zConverted);
872 if( h==INVALID_HANDLE_VALUE ){
873 return SQLITE_CANTOPEN;
874 }
875 f.h = h;
876#if OS_WINCE
877 f.zDeleteOnClose = 0;
878 f.hMutex = NULL;
879#endif
880 OSTRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
881 return allocateWinFile(&f, pId);
882}
883
884/*
885** Attempt to open a file descriptor for the directory that contains a
886** file. This file descriptor can be used to fsync() the directory
887** in order to make sure the creation of a new file is actually written
888** to disk.
889**
890** This routine is only meaningful for Unix. It is a no-op under
891** windows since windows does not support hard links.
892**
893** On success, a handle for a previously open file is at *id is
894** updated with the new directory file descriptor and SQLITE_OK is
895** returned.
896**
897** On failure, the function returns SQLITE_CANTOPEN and leaves
898** *id unchanged.
899*/
900static int winOpenDirectory(
901 OsFile *id,
902 const char *zDirname
903){
904 return SQLITE_OK;
905}
906
907/*
908** Create a temporary file name in zBuf. zBuf must be big enough to
909** hold at least SQLITE_TEMPNAME_SIZE characters.
910*/
911int sqlite3WinTempFileName(char *zBuf){
912 static char zChars[] =
913 "abcdefghijklmnopqrstuvwxyz"
914 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
915 "0123456789";
916 int i, j;
917 char zTempPath[SQLITE_TEMPNAME_SIZE];
918 if( sqlite3_temp_directory ){
919 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
920 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
921 }else if( isNT() ){
922 char *zMulti;
923 WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
924 GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
925 zMulti = unicodeToUtf8(zWidePath);
926 if( zMulti ){
927 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
928 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
929 sqliteFree(zMulti);
930 }else{
931 return SQLITE_NOMEM;
932 }
933 }else{
934 char *zUtf8;
935 char zMbcsPath[SQLITE_TEMPNAME_SIZE];
936 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath);
937 zUtf8 = mbcsToUtf8(zMbcsPath);
938 if( zUtf8 ){
939 strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30);
940 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
941 sqliteFree(zUtf8);
942 }else{
943 return SQLITE_NOMEM;
944 }
945 }
946 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
947 zTempPath[i] = 0;
948 for(;;){
949 sqlite3_snprintf(SQLITE_TEMPNAME_SIZE, zBuf,
950 "%s\\"TEMP_FILE_PREFIX, zTempPath);
951 j = strlen(zBuf);
952 sqlite3Randomness(15, &zBuf[j]);
953 for(i=0; i<15; i++, j++){
954 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
955 }
956 zBuf[j] = 0;
957 if( !sqlite3OsFileExists(zBuf) ) break;
958 }
959 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
960 return SQLITE_OK;
961}
962
963/*
964** Close a file.
965**
966** It is reported that an attempt to close a handle might sometimes
967** fail. This is a very unreasonable result, but windows is notorious
968** for being unreasonable so I do not doubt that it might happen. If
969** the close fails, we pause for 100 milliseconds and try again. As
970** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
971** giving up and returning an error.
972*/
973#define MX_CLOSE_ATTEMPT 3
974static int winClose(OsFile **pId){
975 winFile *pFile;
976 int rc = 1;
977 if( pId && (pFile = (winFile*)*pId)!=0 ){
978 int rc, cnt = 0;
979 OSTRACE2("CLOSE %d\n", pFile->h);
980 do{
981 rc = CloseHandle(pFile->h);
982 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
983#if OS_WINCE
984 winceDestroyLock(pFile);
985#endif
986 OpenCounter(-1);
987 sqliteFree(pFile);
988 *pId = 0;
989 }
990 return rc ? SQLITE_OK : SQLITE_IOERR;
991}
992
993/*
994** Read data from a file into a buffer. Return SQLITE_OK if all
995** bytes were read successfully and SQLITE_IOERR if anything goes
996** wrong.
997*/
998static int winRead(OsFile *id, void *pBuf, int amt){
999 DWORD got;
1000 assert( id!=0 );
1001 SimulateIOError(return SQLITE_IOERR_READ);
1002 OSTRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
1003 if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
1004 return SQLITE_IOERR_READ;
1005 }
1006 if( got==(DWORD)amt ){
1007 return SQLITE_OK;
1008 }else{
1009 memset(&((char*)pBuf)[got], 0, amt-got);
1010 return SQLITE_IOERR_SHORT_READ;
1011 }
1012}
1013
1014/*
1015** Write data from a buffer into a file. Return SQLITE_OK on success
1016** or some other error code on failure.
1017*/
1018static int winWrite(OsFile *id, const void *pBuf, int amt){
1019 int rc = 0;
1020 DWORD wrote;
1021 assert( id!=0 );
1022 SimulateIOError(return SQLITE_IOERR_READ);
1023 SimulateDiskfullError(return SQLITE_FULL);
1024 OSTRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
1025 assert( amt>0 );
1026 while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
1027 && wrote>0 ){
1028 amt -= wrote;
1029 pBuf = &((char*)pBuf)[wrote];
1030 }
1031 if( !rc || amt>(int)wrote ){
1032 return SQLITE_FULL;
1033 }
1034 return SQLITE_OK;
1035}
1036
1037/*
1038** Some microsoft compilers lack this definition.
1039*/
1040#ifndef INVALID_SET_FILE_POINTER
1041# define INVALID_SET_FILE_POINTER ((DWORD)-1)
1042#endif
1043
1044/*
1045** Move the read/write pointer in a file.
1046*/
1047static int winSeek(OsFile *id, i64 offset){
1048 LONG upperBits = offset>>32;
1049 LONG lowerBits = offset & 0xffffffff;
1050 DWORD rc;
1051 assert( id!=0 );
1052#ifdef SQLITE_TEST
1053 if( offset ) SimulateDiskfullError(return SQLITE_FULL);
1054#endif
1055 rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
1056 OSTRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
1057 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
1058 return SQLITE_FULL;
1059 }
1060 return SQLITE_OK;
1061}
1062
1063/*
1064** Make sure all writes to a particular file are committed to disk.
1065*/
1066static int winSync(OsFile *id, int dataOnly){
1067 assert( id!=0 );
1068 OSTRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
1069 if( FlushFileBuffers(((winFile*)id)->h) ){
1070 return SQLITE_OK;
1071 }else{
1072 return SQLITE_IOERR;
1073 }
1074}
1075
1076/*
1077** Sync the directory zDirname. This is a no-op on operating systems other
1078** than UNIX.
1079*/
1080int sqlite3WinSyncDirectory(const char *zDirname){
1081 SimulateIOError(return SQLITE_IOERR_READ);
1082 return SQLITE_OK;
1083}
1084
1085/*
1086** Truncate an open file to a specified size
1087*/
1088static int winTruncate(OsFile *id, i64 nByte){
1089 LONG upperBits = nByte>>32;
1090 assert( id!=0 );
1091 OSTRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
1092 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
1093 SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
1094 SetEndOfFile(((winFile*)id)->h);
1095 return SQLITE_OK;
1096}
1097
1098/*
1099** Determine the current size of a file in bytes
1100*/
1101static int winFileSize(OsFile *id, i64 *pSize){
1102 DWORD upperBits, lowerBits;
1103 assert( id!=0 );
1104 SimulateIOError(return SQLITE_IOERR_FSTAT);
1105 lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
1106 *pSize = (((i64)upperBits)<<32) + lowerBits;
1107 return SQLITE_OK;
1108}
1109
1110/*
1111** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
1112*/
1113#ifndef LOCKFILE_FAIL_IMMEDIATELY
1114# define LOCKFILE_FAIL_IMMEDIATELY 1
1115#endif
1116
1117/*
1118** Acquire a reader lock.
1119** Different API routines are called depending on whether or not this
1120** is Win95 or WinNT.
1121*/
1122static int getReadLock(winFile *id){
1123 int res;
1124 if( isNT() ){
1125 OVERLAPPED ovlp;
1126 ovlp.Offset = SHARED_FIRST;
1127 ovlp.OffsetHigh = 0;
1128 ovlp.hEvent = 0;
1129 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
1130 }else{
1131 int lk;
1132 sqlite3Randomness(sizeof(lk), &lk);
1133 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
1134 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
1135 }
1136 return res;
1137}
1138
1139/*
1140** Undo a readlock
1141*/
1142static int unlockReadLock(winFile *pFile){
1143 int res;
1144 if( isNT() ){
1145 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1146 }else{
1147 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
1148 }
1149 return res;
1150}
1151
1152#ifndef SQLITE_OMIT_PAGER_PRAGMAS
1153/*
1154** Check that a given pathname is a directory and is writable
1155**
1156*/
1157int sqlite3WinIsDirWritable(char *zDirname){
1158 int fileAttr;
1159 void *zConverted;
1160 if( zDirname==0 ) return 0;
1161 if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
1162
1163 zConverted = convertUtf8Filename(zDirname);
1164 if( zConverted==0 ){
1165 return SQLITE_NOMEM;
1166 }
1167 if( isNT() ){
1168 fileAttr = GetFileAttributesW((WCHAR*)zConverted);
1169 }else{
1170#if OS_WINCE
1171 return 0;
1172#else
1173 fileAttr = GetFileAttributesA((char*)zConverted);
1174#endif
1175 }
1176 sqliteFree(zConverted);
1177 if( fileAttr == 0xffffffff ) return 0;
1178 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
1179 return 0;
1180 }
1181 return 1;
1182}
1183#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
1184
1185/*
1186** Lock the file with the lock specified by parameter locktype - one
1187** of the following:
1188**
1189** (1) SHARED_LOCK
1190** (2) RESERVED_LOCK
1191** (3) PENDING_LOCK
1192** (4) EXCLUSIVE_LOCK
1193**
1194** Sometimes when requesting one lock state, additional lock states
1195** are inserted in between. The locking might fail on one of the later
1196** transitions leaving the lock state different from what it started but
1197** still short of its goal. The following chart shows the allowed
1198** transitions and the inserted intermediate states:
1199**
1200** UNLOCKED -> SHARED
1201** SHARED -> RESERVED
1202** SHARED -> (PENDING) -> EXCLUSIVE
1203** RESERVED -> (PENDING) -> EXCLUSIVE
1204** PENDING -> EXCLUSIVE
1205**
1206** This routine will only increase a lock. The winUnlock() routine
1207** erases all locks at once and returns us immediately to locking level 0.
1208** It is not possible to lower the locking level one step at a time. You
1209** must go straight to locking level 0.
1210*/
1211static int winLock(OsFile *id, int locktype){
1212 int rc = SQLITE_OK; /* Return code from subroutines */
1213 int res = 1; /* Result of a windows lock call */
1214 int newLocktype; /* Set id->locktype to this value before exiting */
1215 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
1216 winFile *pFile = (winFile*)id;
1217
1218 assert( pFile!=0 );
1219 OSTRACE5("LOCK %d %d was %d(%d)\n",
1220 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
1221
1222 /* If there is already a lock of this type or more restrictive on the
1223 ** OsFile, do nothing. Don't use the end_lock: exit path, as
1224 ** sqlite3OsEnterMutex() hasn't been called yet.
1225 */
1226 if( pFile->locktype>=locktype ){
1227 return SQLITE_OK;
1228 }
1229
1230 /* Make sure the locking sequence is correct
1231 */
1232 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
1233 assert( locktype!=PENDING_LOCK );
1234 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
1235
1236 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
1237 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
1238 ** the PENDING_LOCK byte is temporary.
1239 */
1240 newLocktype = pFile->locktype;
1241 if( pFile->locktype==NO_LOCK
1242 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
1243 ){
1244 int cnt = 3;
1245 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
1246 /* Try 3 times to get the pending lock. The pending lock might be
1247 ** held by another reader process who will release it momentarily.
1248 */
1249 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
1250 Sleep(1);
1251 }
1252 gotPendingLock = res;
1253 }
1254
1255 /* Acquire a shared lock
1256 */
1257 if( locktype==SHARED_LOCK && res ){
1258 assert( pFile->locktype==NO_LOCK );
1259 res = getReadLock(pFile);
1260 if( res ){
1261 newLocktype = SHARED_LOCK;
1262 }
1263 }
1264
1265 /* Acquire a RESERVED lock
1266 */
1267 if( locktype==RESERVED_LOCK && res ){
1268 assert( pFile->locktype==SHARED_LOCK );
1269 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1270 if( res ){
1271 newLocktype = RESERVED_LOCK;
1272 }
1273 }
1274
1275 /* Acquire a PENDING lock
1276 */
1277 if( locktype==EXCLUSIVE_LOCK && res ){
1278 newLocktype = PENDING_LOCK;
1279 gotPendingLock = 0;
1280 }
1281
1282 /* Acquire an EXCLUSIVE lock
1283 */
1284 if( locktype==EXCLUSIVE_LOCK && res ){
1285 assert( pFile->locktype>=SHARED_LOCK );
1286 res = unlockReadLock(pFile);
1287 OSTRACE2("unreadlock = %d\n", res);
1288 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1289 if( res ){
1290 newLocktype = EXCLUSIVE_LOCK;
1291 }else{
1292 OSTRACE2("error-code = %d\n", GetLastError());
1293 getReadLock(pFile);
1294 }
1295 }
1296
1297 /* If we are holding a PENDING lock that ought to be released, then
1298 ** release it now.
1299 */
1300 if( gotPendingLock && locktype==SHARED_LOCK ){
1301 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
1302 }
1303
1304 /* Update the state of the lock has held in the file descriptor then
1305 ** return the appropriate result code.
1306 */
1307 if( res ){
1308 rc = SQLITE_OK;
1309 }else{
1310 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
1311 locktype, newLocktype);
1312 rc = SQLITE_BUSY;
1313 }
1314 pFile->locktype = newLocktype;
1315 return rc;
1316}
1317
1318/*
1319** This routine checks if there is a RESERVED lock held on the specified
1320** file by this or any other process. If such a lock is held, return
1321** non-zero, otherwise zero.
1322*/
1323static int winCheckReservedLock(OsFile *id){
1324 int rc;
1325 winFile *pFile = (winFile*)id;
1326 assert( pFile!=0 );
1327 if( pFile->locktype>=RESERVED_LOCK ){
1328 rc = 1;
1329 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
1330 }else{
1331 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1332 if( rc ){
1333 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1334 }
1335 rc = !rc;
1336 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
1337 }
1338 return rc;
1339}
1340
1341/*
1342** Lower the locking level on file descriptor id to locktype. locktype
1343** must be either NO_LOCK or SHARED_LOCK.
1344**
1345** If the locking level of the file descriptor is already at or below
1346** the requested locking level, this routine is a no-op.
1347**
1348** It is not possible for this routine to fail if the second argument
1349** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1350** might return SQLITE_IOERR;
1351*/
1352static int winUnlock(OsFile *id, int locktype){
1353 int type;
1354 int rc = SQLITE_OK;
1355 winFile *pFile = (winFile*)id;
1356 assert( pFile!=0 );
1357 assert( locktype<=SHARED_LOCK );
1358 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
1359 pFile->locktype, pFile->sharedLockByte);
1360 type = pFile->locktype;
1361 if( type>=EXCLUSIVE_LOCK ){
1362 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1363 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
1364 /* This should never happen. We should always be able to
1365 ** reacquire the read lock */
1366 rc = SQLITE_IOERR_UNLOCK;
1367 }
1368 }
1369 if( type>=RESERVED_LOCK ){
1370 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
1371 }
1372 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
1373 unlockReadLock(pFile);
1374 }
1375 if( type>=PENDING_LOCK ){
1376 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
1377 }
1378 pFile->locktype = locktype;
1379 return rc;
1380}
1381
1382/*
1383** Turn a relative pathname into a full pathname. Return a pointer
1384** to the full pathname stored in space obtained from sqliteMalloc().
1385** The calling function is responsible for freeing this space once it
1386** is no longer needed.
1387*/
1388char *sqlite3WinFullPathname(const char *zRelative){
1389 char *zFull;
1390#if defined(__CYGWIN__)
1391 int nByte;
1392 nByte = strlen(zRelative) + MAX_PATH + 1001;
1393 zFull = sqliteMalloc( nByte );
1394 if( zFull==0 ) return 0;
1395 if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
1396#elif OS_WINCE
1397 /* WinCE has no concept of a relative pathname, or so I am told. */
1398 zFull = sqliteStrDup(zRelative);
1399#else
1400 int nByte;
1401 void *zConverted;
1402 zConverted = convertUtf8Filename(zRelative);
1403 if( isNT() ){
1404 WCHAR *zTemp;
1405 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
1406 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
1407 if( zTemp==0 ){
1408 sqliteFree(zConverted);
1409 return 0;
1410 }
1411 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
1412 sqliteFree(zConverted);
1413 zFull = unicodeToUtf8(zTemp);
1414 sqliteFree(zTemp);
1415 }else{
1416 char *zTemp;
1417 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
1418 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
1419 if( zTemp==0 ){
1420 sqliteFree(zConverted);
1421 return 0;
1422 }
1423 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
1424 sqliteFree(zConverted);
1425 zFull = mbcsToUtf8(zTemp);
1426 sqliteFree(zTemp);
1427 }
1428#endif
1429 return zFull;
1430}
1431
1432/*
1433** The fullSync option is meaningless on windows. This is a no-op.
1434*/
1435static void winSetFullSync(OsFile *id, int v){
1436 return;
1437}
1438
1439/*
1440** Return the underlying file handle for an OsFile
1441*/
1442static int winFileHandle(OsFile *id){
1443 return (int)((winFile*)id)->h;
1444}
1445
1446/*
1447** Return an integer that indices the type of lock currently held
1448** by this handle. (Used for testing and analysis only.)
1449*/
1450static int winLockState(OsFile *id){
1451 return ((winFile*)id)->locktype;
1452}
1453
1454/*
1455** Return the sector size in bytes of the underlying block device for
1456** the specified file. This is almost always 512 bytes, but may be
1457** larger for some devices.
1458**
1459** SQLite code assumes this function cannot fail. It also assumes that
1460** if two files are created in the same file-system directory (i.e.
1461** a database and it's journal file) that the sector size will be the
1462** same for both.
1463*/
1464static int winSectorSize(OsFile *id){
1465 return SQLITE_DEFAULT_SECTOR_SIZE;
1466}
1467
1468/*
1469** This vector defines all the methods that can operate on an OsFile
1470** for win32.
1471*/
1472static const IoMethod sqlite3WinIoMethod = {
1473 winClose,
1474 winOpenDirectory,
1475 winRead,
1476 winWrite,
1477 winSeek,
1478 winTruncate,
1479 winSync,
1480 winSetFullSync,
1481 winFileHandle,
1482 winFileSize,
1483 winLock,
1484 winUnlock,
1485 winLockState,
1486 winCheckReservedLock,
1487 winSectorSize,
1488};
1489
1490/*
1491** Allocate memory for an OsFile. Initialize the new OsFile
1492** to the value given in pInit and return a pointer to the new
1493** OsFile. If we run out of memory, close the file and return NULL.
1494*/
1495static int allocateWinFile(winFile *pInit, OsFile **pId){
1496 winFile *pNew;
1497 pNew = sqliteMalloc( sizeof(*pNew) );
1498 if( pNew==0 ){
1499 CloseHandle(pInit->h);
1500#if OS_WINCE
1501 sqliteFree(pInit->zDeleteOnClose);
1502#endif
1503 *pId = 0;
1504 return SQLITE_NOMEM;
1505 }else{
1506 *pNew = *pInit;
1507 pNew->pMethod = &sqlite3WinIoMethod;
1508 pNew->locktype = NO_LOCK;
1509 pNew->sharedLockByte = 0;
1510 *pId = (OsFile*)pNew;
1511 OpenCounter(+1);
1512 return SQLITE_OK;
1513 }
1514}
1515
1516
1517#endif /* SQLITE_OMIT_DISKIO */
1518/***************************************************************************
1519** Everything above deals with file I/O. Everything that follows deals
1520** with other miscellanous aspects of the operating system interface
1521****************************************************************************/
1522
1523#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
1524/*
1525** Interfaces for opening a shared library, finding entry points
1526** within the shared library, and closing the shared library.
1527*/
1528void *sqlite3WinDlopen(const char *zFilename){
1529 HANDLE h;
1530 void *zConverted = convertUtf8Filename(zFilename);
1531 if( zConverted==0 ){
1532 return 0;
1533 }
1534 if( isNT() ){
1535 h = LoadLibraryW((WCHAR*)zConverted);
1536 }else{
1537#if OS_WINCE
1538 return 0;
1539#else
1540 h = LoadLibraryA((char*)zConverted);
1541#endif
1542 }
1543 sqliteFree(zConverted);
1544 return (void*)h;
1545
1546}
1547void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
1548#if OS_WINCE
1549 /* The GetProcAddressA() routine is only available on wince. */
1550 return GetProcAddressA((HANDLE)pHandle, zSymbol);
1551#else
1552 /* All other windows platforms expect GetProcAddress() to take
1553 ** an Ansi string regardless of the _UNICODE setting */
1554 return GetProcAddress((HANDLE)pHandle, zSymbol);
1555#endif
1556}
1557int sqlite3WinDlclose(void *pHandle){
1558 return FreeLibrary((HANDLE)pHandle);
1559}
1560#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
1561
1562/*
1563** Get information to seed the random number generator. The seed
1564** is written into the buffer zBuf[256]. The calling function must
1565** supply a sufficiently large buffer.
1566*/
1567int sqlite3WinRandomSeed(char *zBuf){
1568 /* We have to initialize zBuf to prevent valgrind from reporting
1569 ** errors. The reports issued by valgrind are incorrect - we would
1570 ** prefer that the randomness be increased by making use of the
1571 ** uninitialized space in zBuf - but valgrind errors tend to worry
1572 ** some users. Rather than argue, it seems easier just to initialize
1573 ** the whole array and silence valgrind, even if that means less randomness
1574 ** in the random seed.
1575 **
1576 ** When testing, initializing zBuf[] to zero is all we do. That means
1577 ** that we always use the same random number sequence.* This makes the
1578 ** tests repeatable.
1579 */
1580 memset(zBuf, 0, 256);
1581 GetSystemTime((LPSYSTEMTIME)zBuf);
1582 return SQLITE_OK;
1583}
1584
1585/*
1586** Sleep for a little while. Return the amount of time slept.
1587*/
1588int sqlite3WinSleep(int ms){
1589 Sleep(ms);
1590 return ms;
1591}
1592
1593/*
1594** Static variables used for thread synchronization
1595*/
1596static int inMutex = 0;
1597#ifdef SQLITE_W32_THREADS
1598 static DWORD mutexOwner;
1599 static CRITICAL_SECTION cs;
1600#endif
1601
1602/*
1603** The following pair of routines implement mutual exclusion for
1604** multi-threaded processes. Only a single thread is allowed to
1605** executed code that is surrounded by EnterMutex() and LeaveMutex().
1606**
1607** SQLite uses only a single Mutex. There is not much critical
1608** code and what little there is executes quickly and without blocking.
1609**
1610** Version 3.3.1 and earlier used a simple mutex. Beginning with
1611** version 3.3.2, a recursive mutex is required.
1612*/
1613void sqlite3WinEnterMutex(){
1614#ifdef SQLITE_W32_THREADS
1615 static int isInit = 0;
1616 while( !isInit ){
1617 static long lock = 0;
1618 if( InterlockedIncrement(&lock)==1 ){
1619 InitializeCriticalSection(&cs);
1620 isInit = 1;
1621 }else{
1622 Sleep(1);
1623 }
1624 }
1625 EnterCriticalSection(&cs);
1626 mutexOwner = GetCurrentThreadId();
1627#endif
1628 inMutex++;
1629}
1630void sqlite3WinLeaveMutex(){
1631 assert( inMutex );
1632 inMutex--;
1633#ifdef SQLITE_W32_THREADS
1634 assert( mutexOwner==GetCurrentThreadId() );
1635 LeaveCriticalSection(&cs);
1636#endif
1637}
1638
1639/*
1640** Return TRUE if the mutex is currently held.
1641**
1642** If the thisThreadOnly parameter is true, return true if and only if the
1643** calling thread holds the mutex. If the parameter is false, return
1644** true if any thread holds the mutex.
1645*/
1646int sqlite3WinInMutex(int thisThreadOnly){
1647#ifdef SQLITE_W32_THREADS
1648 return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId());
1649#else
1650 return inMutex>0;
1651#endif
1652}
1653
1654
1655/*
1656** The following variable, if set to a non-zero value, becomes the result
1657** returned from sqlite3OsCurrentTime(). This is used for testing.
1658*/
1659#ifdef SQLITE_TEST
1660int sqlite3_current_time = 0;
1661#endif
1662
1663/*
1664** Find the current time (in Universal Coordinated Time). Write the
1665** current time and date as a Julian Day number into *prNow and
1666** return 0. Return 1 if the time and date cannot be found.
1667*/
1668int sqlite3WinCurrentTime(double *prNow){
1669 FILETIME ft;
1670 /* FILETIME structure is a 64-bit value representing the number of
1671 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1672 */
1673 double now;
1674#if OS_WINCE
1675 SYSTEMTIME time;
1676 GetSystemTime(&time);
1677 SystemTimeToFileTime(&time,&ft);
1678#else
1679 GetSystemTimeAsFileTime( &ft );
1680#endif
1681 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1682 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1683#ifdef SQLITE_TEST
1684 if( sqlite3_current_time ){
1685 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1686 }
1687#endif
1688 return 0;
1689}
1690
1691/*
1692** Remember the number of thread-specific-data blocks allocated.
1693** Use this to verify that we are not leaking thread-specific-data.
1694** Ticket #1601
1695*/
1696#ifdef SQLITE_TEST
1697int sqlite3_tsd_count = 0;
1698# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
1699# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
1700#else
1701# define TSD_COUNTER_INCR /* no-op */
1702# define TSD_COUNTER_DECR /* no-op */
1703#endif
1704
1705
1706
1707/*
1708** If called with allocateFlag>1, then return a pointer to thread
1709** specific data for the current thread. Allocate and zero the
1710** thread-specific data if it does not already exist necessary.
1711**
1712** If called with allocateFlag==0, then check the current thread
1713** specific data. Return it if it exists. If it does not exist,
1714** then return NULL.
1715**
1716** If called with allocateFlag<0, check to see if the thread specific
1717** data is allocated and is all zero. If it is then deallocate it.
1718** Return a pointer to the thread specific data or NULL if it is
1719** unallocated or gets deallocated.
1720*/
1721ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
1722 static int key;
1723 static int keyInit = 0;
1724 static const ThreadData zeroData = {0};
1725 ThreadData *pTsd;
1726
1727 if( !keyInit ){
1728 sqlite3OsEnterMutex();
1729 if( !keyInit ){
1730 key = TlsAlloc();
1731 if( key==0xffffffff ){
1732 sqlite3OsLeaveMutex();
1733 return 0;
1734 }
1735 keyInit = 1;
1736 }
1737 sqlite3OsLeaveMutex();
1738 }
1739 pTsd = TlsGetValue(key);
1740 if( allocateFlag>0 ){
1741 if( !pTsd ){
1742 pTsd = sqlite3OsMalloc( sizeof(zeroData) );
1743 if( pTsd ){
1744 *pTsd = zeroData;
1745 TlsSetValue(key, pTsd);
1746 TSD_COUNTER_INCR;
1747 }
1748 }
1749 }else if( pTsd!=0 && allocateFlag<0
1750 && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
1751 sqlite3OsFree(pTsd);
1752 TlsSetValue(key, 0);
1753 TSD_COUNTER_DECR;
1754 pTsd = 0;
1755 }
1756 return pTsd;
1757}
1758#endif /* OS_WIN */

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status