blob: 59d759902a2b5a2b4866adb9e6084a6f73d8a57f [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#include "os.h"
17#if OS_WIN /* This file is used for windows only */
drhbbd42a62004-05-22 17:41:58 +000018
19#include <winbase.h>
20
drh09bf0e82005-03-21 00:36:08 +000021#ifdef __CYGWIN__
22# include <sys/cygwin.h>
23#endif
24
drhbbd42a62004-05-22 17:41:58 +000025/*
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/*
drhcc78fea2006-01-06 16:17:05 +000038** 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#else
44# define OS_WINCE 0
45#endif
46
47/*
drh72aead82006-01-23 15:54:25 +000048** WinCE lacks native support for file locking so we have to fake it
49** with some code of our own.
50*/
51#if OS_WINCE
52typedef struct winceLock {
53 int nReaders; /* Number of reader locks obtained */
54 BOOL bPending; /* Indicates a pending lock has been obtained */
55 BOOL bReserved; /* Indicates a reserved lock has been obtained */
56 BOOL bExclusive; /* Indicates an exclusive lock has been obtained */
57} winceLock;
58#endif
59
60/*
drh054889e2005-11-30 03:20:31 +000061** The winFile structure is a subclass of OsFile specific to the win32
62** portability layer.
drh9cbe6352005-11-29 03:13:21 +000063*/
drh054889e2005-11-30 03:20:31 +000064typedef struct winFile winFile;
65struct winFile {
66 IoMethod const *pMethod;/* Must be first */
drh9cbe6352005-11-29 03:13:21 +000067 HANDLE h; /* Handle for accessing the file */
68 unsigned char locktype; /* Type of lock currently held on this file */
69 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
drhcc78fea2006-01-06 16:17:05 +000070#if OS_WINCE
drh72aead82006-01-23 15:54:25 +000071 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
72 HANDLE hMutex; /* Mutex used to control access to shared lock */
73 HANDLE hShared; /* Shared memory segment used for locking */
74 winceLock local; /* Locks obtained by this instance of winFile */
75 winceLock *shared; /* Global shared lock memory for the file */
drhcc78fea2006-01-06 16:17:05 +000076#endif
drh9cbe6352005-11-29 03:13:21 +000077};
78
79
drh9cbe6352005-11-29 03:13:21 +000080/*
drh0ccebe72005-06-07 22:22:50 +000081** Do not include any of the File I/O interface procedures if the
82** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
83** will be in-memory only)
84*/
85#ifndef SQLITE_OMIT_DISKIO
86
87/*
drhc0929982005-09-05 19:08:29 +000088** The following variable is (normally) set once and never changes
89** thereafter. It records whether the operating system is Win95
90** or WinNT.
91**
92** 0: Operating system unknown.
93** 1: Operating system is Win95.
94** 2: Operating system is WinNT.
95**
96** In order to facilitate testing on a WinNT system, the test fixture
97** can manually set this value to 1 to emulate Win98 behavior.
98*/
99int sqlite3_os_type = 0;
100
101/*
drhcc78fea2006-01-06 16:17:05 +0000102** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
103** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +0000104**
105** Here is an interesting observation: Win95, Win98, and WinME lack
106** the LockFileEx() API. But we can still statically link against that
107** API as long as we don't call it win running Win95/98/ME. A call to
108** this routine is used to determine if the host is Win95/98/ME or
109** WinNT/2K/XP so that we will know whether or not we can safely call
110** the LockFileEx() API.
111*/
drhcc78fea2006-01-06 16:17:05 +0000112#if OS_WINCE
113# define isNT() (1)
114#else
115 static int isNT(void){
116 if( sqlite3_os_type==0 ){
117 OSVERSIONINFO sInfo;
118 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
119 GetVersionEx(&sInfo);
120 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
121 }
122 return sqlite3_os_type==2;
drhc0929982005-09-05 19:08:29 +0000123 }
drhcc78fea2006-01-06 16:17:05 +0000124#endif /* OS_WINCE */
125
drhc0929982005-09-05 19:08:29 +0000126/*
drh584c0942006-12-21 03:20:40 +0000127** Convert a UTF-8 string to microsoft unicode (UTF-16?).
128**
129** Space to hold the returned string is obtained from sqliteMalloc.
drhc0929982005-09-05 19:08:29 +0000130*/
131static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000132 int nChar;
drhc0929982005-09-05 19:08:29 +0000133 WCHAR *zWideFilename;
134
drhe3dd8bb2006-02-27 23:44:35 +0000135 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
136 zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000137 if( zWideFilename==0 ){
138 return 0;
139 }
drhe3dd8bb2006-02-27 23:44:35 +0000140 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
141 if( nChar==0 ){
drhc0929982005-09-05 19:08:29 +0000142 sqliteFree(zWideFilename);
143 zWideFilename = 0;
144 }
145 return zWideFilename;
146}
147
148/*
drh584c0942006-12-21 03:20:40 +0000149** Convert microsoft unicode to UTF-8. Space to hold the returned string is
drhc0929982005-09-05 19:08:29 +0000150** obtained from sqliteMalloc().
151*/
152static char *unicodeToUtf8(const WCHAR *zWideFilename){
153 int nByte;
154 char *zFilename;
155
156 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
157 zFilename = sqliteMalloc( nByte );
158 if( zFilename==0 ){
159 return 0;
160 }
161 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
162 0, 0);
163 if( nByte == 0 ){
164 sqliteFree(zFilename);
165 zFilename = 0;
166 }
167 return zFilename;
168}
169
drh371de5a2006-10-30 13:37:22 +0000170/*
drh584c0942006-12-21 03:20:40 +0000171** Convert an ansi string to microsoft unicode, based on the
172** current codepage settings for file apis.
173**
174** Space to hold the returned string is obtained
drh371de5a2006-10-30 13:37:22 +0000175** from sqliteMalloc.
176*/
177static WCHAR *mbcsToUnicode(const char *zFilename){
178 int nByte;
179 WCHAR *zMbcsFilename;
drh584c0942006-12-21 03:20:40 +0000180 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000181
drh584c0942006-12-21 03:20:40 +0000182 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
drh371de5a2006-10-30 13:37:22 +0000183 zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) );
184 if( zMbcsFilename==0 ){
185 return 0;
186 }
drh584c0942006-12-21 03:20:40 +0000187 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
drh371de5a2006-10-30 13:37:22 +0000188 if( nByte==0 ){
189 sqliteFree(zMbcsFilename);
190 zMbcsFilename = 0;
191 }
192 return zMbcsFilename;
193}
194
195/*
drh584c0942006-12-21 03:20:40 +0000196** Convert microsoft unicode to multibyte character string, based on the
197** user's Ansi codepage.
198**
199** Space to hold the returned string is obtained from
drh371de5a2006-10-30 13:37:22 +0000200** sqliteMalloc().
201*/
202static char *unicodeToMbcs(const WCHAR *zWideFilename){
203 int nByte;
204 char *zFilename;
drh584c0942006-12-21 03:20:40 +0000205 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000206
drh584c0942006-12-21 03:20:40 +0000207 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
drh371de5a2006-10-30 13:37:22 +0000208 zFilename = sqliteMalloc( nByte );
209 if( zFilename==0 ){
210 return 0;
211 }
drh584c0942006-12-21 03:20:40 +0000212 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
drh371de5a2006-10-30 13:37:22 +0000213 0, 0);
214 if( nByte == 0 ){
215 sqliteFree(zFilename);
216 zFilename = 0;
217 }
218 return zFilename;
219}
220
221/*
222** Convert multibyte character string to UTF-8. Space to hold the
223** returned string is obtained from sqliteMalloc().
224*/
225static char *mbcsToUtf8(const char *zFilename){
226 char *zFilenameUtf8;
227 WCHAR *zTmpWide;
228
229 zTmpWide = mbcsToUnicode(zFilename);
230 if( zTmpWide==0 ){
231 return 0;
232 }
233 zFilenameUtf8 = unicodeToUtf8(zTmpWide);
234 sqliteFree(zTmpWide);
235 return zFilenameUtf8;
236}
237
238/*
239** Convert UTF-8 to multibyte character string. Space to hold the
240** returned string is obtained from sqliteMalloc().
241*/
242static char *utf8ToMbcs(const char *zFilename){
243 char *zFilenameMbcs;
244 WCHAR *zTmpWide;
245
246 zTmpWide = utf8ToUnicode(zFilename);
247 if( zTmpWide==0 ){
248 return 0;
249 }
250 zFilenameMbcs = unicodeToMbcs(zTmpWide);
251 sqliteFree(zTmpWide);
252 return zFilenameMbcs;
253}
254
drh72aead82006-01-23 15:54:25 +0000255#if OS_WINCE
256/*************************************************************************
257** This section contains code for WinCE only.
258*/
259/*
260** WindowsCE does not have a localtime() function. So create a
261** substitute.
262*/
263#include <time.h>
264struct tm *__cdecl localtime(const time_t *t)
265{
266 static struct tm y;
267 FILETIME uTm, lTm;
268 SYSTEMTIME pTm;
269 i64 t64;
270 t64 = *t;
271 t64 = (t64 + 11644473600)*10000000;
272 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
273 uTm.dwHighDateTime= t64 >> 32;
274 FileTimeToLocalFileTime(&uTm,&lTm);
275 FileTimeToSystemTime(&lTm,&pTm);
276 y.tm_year = pTm.wYear - 1900;
277 y.tm_mon = pTm.wMonth - 1;
278 y.tm_wday = pTm.wDayOfWeek;
279 y.tm_mday = pTm.wDay;
280 y.tm_hour = pTm.wHour;
281 y.tm_min = pTm.wMinute;
282 y.tm_sec = pTm.wSecond;
283 return &y;
284}
285
286/* This will never be called, but defined to make the code compile */
287#define GetTempPathA(a,b)
288
289#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
290#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
291#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
292
293#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
294
295/*
296** Acquire a lock on the handle h
297*/
298static void winceMutexAcquire(HANDLE h){
299 DWORD dwErr;
300 do {
301 dwErr = WaitForSingleObject(h, INFINITE);
302 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
303}
304/*
305** Release a lock acquired by winceMutexAcquire()
306*/
307#define winceMutexRelease(h) ReleaseMutex(h)
308
309/*
310** Create the mutex and shared memory used for locking in the file
311** descriptor pFile
312*/
313static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
314 WCHAR *zTok;
315 WCHAR *zName = utf8ToUnicode(zFilename);
316 BOOL bInit = TRUE;
317
318 /* Initialize the local lockdata */
319 ZeroMemory(&pFile->local, sizeof(pFile->local));
320
321 /* Replace the backslashes from the filename and lowercase it
322 ** to derive a mutex name. */
323 zTok = CharLowerW(zName);
324 for (;*zTok;zTok++){
325 if (*zTok == '\\') *zTok = '_';
326 }
327
328 /* Create/open the named mutex */
329 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
330 if (!pFile->hMutex){
331 sqliteFree(zName);
332 return FALSE;
333 }
334
335 /* Acquire the mutex before continuing */
336 winceMutexAcquire(pFile->hMutex);
337
338 /* Since the names of named mutexes, semaphores, file mappings etc are
339 ** case-sensitive, take advantage of that by uppercasing the mutex name
340 ** and using that as the shared filemapping name.
341 */
342 CharUpperW(zName);
343 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
344 PAGE_READWRITE, 0, sizeof(winceLock),
345 zName);
346
347 /* Set a flag that indicates we're the first to create the memory so it
348 ** must be zero-initialized */
349 if (GetLastError() == ERROR_ALREADY_EXISTS){
350 bInit = FALSE;
351 }
352
353 sqliteFree(zName);
354
355 /* If we succeeded in making the shared memory handle, map it. */
356 if (pFile->hShared){
357 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
358 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
359 /* If mapping failed, close the shared memory handle and erase it */
360 if (!pFile->shared){
361 CloseHandle(pFile->hShared);
362 pFile->hShared = NULL;
363 }
364 }
365
366 /* If shared memory could not be created, then close the mutex and fail */
367 if (pFile->hShared == NULL){
368 winceMutexRelease(pFile->hMutex);
369 CloseHandle(pFile->hMutex);
370 pFile->hMutex = NULL;
371 return FALSE;
372 }
373
374 /* Initialize the shared memory if we're supposed to */
375 if (bInit) {
376 ZeroMemory(pFile->shared, sizeof(winceLock));
377 }
378
379 winceMutexRelease(pFile->hMutex);
380 return TRUE;
381}
382
383/*
384** Destroy the part of winFile that deals with wince locks
385*/
386static void winceDestroyLock(winFile *pFile){
387 if (pFile->hMutex){
388 /* Acquire the mutex */
389 winceMutexAcquire(pFile->hMutex);
390
391 /* The following blocks should probably assert in debug mode, but they
392 are to cleanup in case any locks remained open */
393 if (pFile->local.nReaders){
394 pFile->shared->nReaders --;
395 }
396 if (pFile->local.bReserved){
397 pFile->shared->bReserved = FALSE;
398 }
399 if (pFile->local.bPending){
400 pFile->shared->bPending = FALSE;
401 }
402 if (pFile->local.bExclusive){
403 pFile->shared->bExclusive = FALSE;
404 }
405
406 /* De-reference and close our copy of the shared memory handle */
407 UnmapViewOfFile(pFile->shared);
408 CloseHandle(pFile->hShared);
409
410 /* Done with the mutex */
411 winceMutexRelease(pFile->hMutex);
412 CloseHandle(pFile->hMutex);
413 pFile->hMutex = NULL;
414 }
415}
416
417/*
418** An implementation of the LockFile() API of windows for wince
419*/
420static BOOL winceLockFile(
421 HANDLE *phFile,
422 DWORD dwFileOffsetLow,
423 DWORD dwFileOffsetHigh,
424 DWORD nNumberOfBytesToLockLow,
425 DWORD nNumberOfBytesToLockHigh
426){
427 winFile *pFile = HANDLE_TO_WINFILE(phFile);
428 BOOL bReturn = FALSE;
429
430 if (!pFile->hMutex) return TRUE;
431 winceMutexAcquire(pFile->hMutex);
432
433 /* Wanting an exclusive lock? */
434 if (dwFileOffsetLow == SHARED_FIRST
435 && nNumberOfBytesToLockLow == SHARED_SIZE){
436 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
437 pFile->shared->bExclusive = TRUE;
438 pFile->local.bExclusive = TRUE;
439 bReturn = TRUE;
440 }
441 }
442
443 /* Want a read-only lock? */
444 else if ((dwFileOffsetLow >= SHARED_FIRST &&
445 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
446 nNumberOfBytesToLockLow == 1){
447 if (pFile->shared->bExclusive == 0){
448 pFile->local.nReaders ++;
449 if (pFile->local.nReaders == 1){
450 pFile->shared->nReaders ++;
451 }
452 bReturn = TRUE;
453 }
454 }
455
456 /* Want a pending lock? */
457 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
458 /* If no pending lock has been acquired, then acquire it */
459 if (pFile->shared->bPending == 0) {
460 pFile->shared->bPending = TRUE;
461 pFile->local.bPending = TRUE;
462 bReturn = TRUE;
463 }
464 }
465 /* Want a reserved lock? */
466 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
467 if (pFile->shared->bReserved == 0) {
468 pFile->shared->bReserved = TRUE;
469 pFile->local.bReserved = TRUE;
470 bReturn = TRUE;
471 }
472 }
473
474 winceMutexRelease(pFile->hMutex);
475 return bReturn;
476}
477
478/*
479** An implementation of the UnlockFile API of windows for wince
480*/
481static BOOL winceUnlockFile(
482 HANDLE *phFile,
483 DWORD dwFileOffsetLow,
484 DWORD dwFileOffsetHigh,
485 DWORD nNumberOfBytesToUnlockLow,
486 DWORD nNumberOfBytesToUnlockHigh
487){
488 winFile *pFile = HANDLE_TO_WINFILE(phFile);
489 BOOL bReturn = FALSE;
490
491 if (!pFile->hMutex) return TRUE;
492 winceMutexAcquire(pFile->hMutex);
493
494 /* Releasing a reader lock or an exclusive lock */
495 if (dwFileOffsetLow >= SHARED_FIRST &&
496 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
497 /* Did we have an exclusive lock? */
498 if (pFile->local.bExclusive){
499 pFile->local.bExclusive = FALSE;
500 pFile->shared->bExclusive = FALSE;
501 bReturn = TRUE;
502 }
503
504 /* Did we just have a reader lock? */
505 else if (pFile->local.nReaders){
506 pFile->local.nReaders --;
507 if (pFile->local.nReaders == 0)
508 {
509 pFile->shared->nReaders --;
510 }
511 bReturn = TRUE;
512 }
513 }
514
515 /* Releasing a pending lock */
516 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
517 if (pFile->local.bPending){
518 pFile->local.bPending = FALSE;
519 pFile->shared->bPending = FALSE;
520 bReturn = TRUE;
521 }
522 }
523 /* Releasing a reserved lock */
524 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
525 if (pFile->local.bReserved) {
526 pFile->local.bReserved = FALSE;
527 pFile->shared->bReserved = FALSE;
528 bReturn = TRUE;
529 }
530 }
531
532 winceMutexRelease(pFile->hMutex);
533 return bReturn;
534}
535
536/*
537** An implementation of the LockFileEx() API of windows for wince
538*/
539static BOOL winceLockFileEx(
540 HANDLE *phFile,
541 DWORD dwFlags,
542 DWORD dwReserved,
543 DWORD nNumberOfBytesToLockLow,
544 DWORD nNumberOfBytesToLockHigh,
545 LPOVERLAPPED lpOverlapped
546){
547 /* If the caller wants a shared read lock, forward this call
548 ** to winceLockFile */
549 if (lpOverlapped->Offset == SHARED_FIRST &&
550 dwFlags == 1 &&
551 nNumberOfBytesToLockLow == SHARED_SIZE){
552 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
553 }
554 return FALSE;
555}
556/*
557** End of the special code for wince
558*****************************************************************************/
559#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000560
561/*
drh371de5a2006-10-30 13:37:22 +0000562** Convert a UTF-8 filename into whatever form the underlying
563** operating system wants filenames in. Space to hold the result
564** is obtained from sqliteMalloc and must be freed by the calling
565** function.
566*/
567static void *convertUtf8Filename(const char *zFilename){
568 void *zConverted = 0;
569 if( isNT() ){
570 zConverted = utf8ToUnicode(zFilename);
571 }else{
572 zConverted = utf8ToMbcs(zFilename);
573 }
574 /* caller will handle out of memory */
575 return zConverted;
576}
577
578/*
drh59e63a62006-06-04 23:31:48 +0000579** Delete the named file.
580**
581** Note that windows does not allow a file to be deleted if some other
582** process has it open. Sometimes a virus scanner or indexing program
583** will open a journal file shortly after it is created in order to do
584** whatever it is it does. While this other process is holding the
585** file open, we will be unable to delete it. To work around this
586** problem, we delay 100 milliseconds and try to delete again. Up
587** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
588** up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000589*/
drh59e63a62006-06-04 23:31:48 +0000590#define MX_DELETION_ATTEMPTS 3
drh66560ad2006-01-06 14:32:19 +0000591int sqlite3WinDelete(const char *zFilename){
drheb4fa522006-06-04 23:02:20 +0000592 int cnt = 0;
593 int rc;
drh371de5a2006-10-30 13:37:22 +0000594 void *zConverted = convertUtf8Filename(zFilename);
595 if( zConverted==0 ){
596 return SQLITE_NOMEM;
597 }
598 if( isNT() ){
drheb4fa522006-06-04 23:02:20 +0000599 do{
drh371de5a2006-10-30 13:37:22 +0000600 rc = DeleteFileW(zConverted);
601 }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff
drh50c2b352006-09-26 00:34:17 +0000602 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
drhc0929982005-09-05 19:08:29 +0000603 }else{
drhcc78fea2006-01-06 16:17:05 +0000604#if OS_WINCE
605 return SQLITE_NOMEM;
606#else
drheb4fa522006-06-04 23:02:20 +0000607 do{
drh371de5a2006-10-30 13:37:22 +0000608 rc = DeleteFileA(zConverted);
609 }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
drh50c2b352006-09-26 00:34:17 +0000610 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000611#endif
drhc0929982005-09-05 19:08:29 +0000612 }
drh371de5a2006-10-30 13:37:22 +0000613 sqliteFree(zConverted);
drh51c6d962004-06-06 00:42:25 +0000614 TRACE2("DELETE \"%s\"\n", zFilename);
drh50c2b352006-09-26 00:34:17 +0000615 return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000616}
617
618/*
619** Return TRUE if the named file exists.
620*/
drh66560ad2006-01-06 14:32:19 +0000621int sqlite3WinFileExists(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000622 int exists = 0;
drh371de5a2006-10-30 13:37:22 +0000623 void *zConverted = convertUtf8Filename(zFilename);
624 if( zConverted==0 ){
625 return SQLITE_NOMEM;
626 }
627 if( isNT() ){
628 exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff;
drhc0929982005-09-05 19:08:29 +0000629 }else{
drhcc78fea2006-01-06 16:17:05 +0000630#if OS_WINCE
631 return SQLITE_NOMEM;
632#else
drh371de5a2006-10-30 13:37:22 +0000633 exists = GetFileAttributesA((char*)zConverted) != 0xffffffff;
drhcc78fea2006-01-06 16:17:05 +0000634#endif
drhc0929982005-09-05 19:08:29 +0000635 }
drh371de5a2006-10-30 13:37:22 +0000636 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +0000637 return exists;
drhbbd42a62004-05-22 17:41:58 +0000638}
639
drh054889e2005-11-30 03:20:31 +0000640/* Forward declaration */
danielk1977f0113002006-01-24 12:09:17 +0000641static int allocateWinFile(winFile *pInit, OsFile **pId);
drh9cbe6352005-11-29 03:13:21 +0000642
drhbbd42a62004-05-22 17:41:58 +0000643/*
644** Attempt to open a file for both reading and writing. If that
645** fails, try opening it read-only. If the file does not exist,
646** try to create it.
647**
648** On success, a handle for the open file is written to *id
649** and *pReadonly is set to 0 if the file was opened for reading and
650** writing or 1 if the file was opened read-only. The function returns
651** SQLITE_OK.
652**
653** On failure, the function returns SQLITE_CANTOPEN and leaves
654** *id and *pReadonly unchanged.
655*/
drh66560ad2006-01-06 14:32:19 +0000656int sqlite3WinOpenReadWrite(
drhbbd42a62004-05-22 17:41:58 +0000657 const char *zFilename,
drh9cbe6352005-11-29 03:13:21 +0000658 OsFile **pId,
drhbbd42a62004-05-22 17:41:58 +0000659 int *pReadonly
660){
drh054889e2005-11-30 03:20:31 +0000661 winFile f;
drhda71ce12004-06-21 18:14:45 +0000662 HANDLE h;
drh371de5a2006-10-30 13:37:22 +0000663 void *zConverted = convertUtf8Filename(zFilename);
664 if( zConverted==0 ){
665 return SQLITE_NOMEM;
666 }
drh9cbe6352005-11-29 03:13:21 +0000667 assert( *pId==0 );
drh371de5a2006-10-30 13:37:22 +0000668
669 if( isNT() ){
670 h = CreateFileW((WCHAR*)zConverted,
drhc0929982005-09-05 19:08:29 +0000671 GENERIC_READ | GENERIC_WRITE,
672 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhbbd42a62004-05-22 17:41:58 +0000673 NULL,
674 OPEN_ALWAYS,
675 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
676 NULL
677 );
678 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000679 h = CreateFileW((WCHAR*)zConverted,
drhc0929982005-09-05 19:08:29 +0000680 GENERIC_READ,
drh94d57e32006-06-02 12:40:08 +0000681 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhc0929982005-09-05 19:08:29 +0000682 NULL,
683 OPEN_ALWAYS,
684 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
685 NULL
686 );
687 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000688 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +0000689 return SQLITE_CANTOPEN;
690 }
691 *pReadonly = 1;
692 }else{
693 *pReadonly = 0;
drhbbd42a62004-05-22 17:41:58 +0000694 }
drh72aead82006-01-23 15:54:25 +0000695#if OS_WINCE
696 if (!winceCreateLock(zFilename, &f)){
697 CloseHandle(h);
drh371de5a2006-10-30 13:37:22 +0000698 sqliteFree(zConverted);
drh72aead82006-01-23 15:54:25 +0000699 return SQLITE_CANTOPEN;
700 }
701#endif
drhbbd42a62004-05-22 17:41:58 +0000702 }else{
drhcc78fea2006-01-06 16:17:05 +0000703#if OS_WINCE
704 return SQLITE_NOMEM;
705#else
drh371de5a2006-10-30 13:37:22 +0000706 h = CreateFileA((char*)zConverted,
drhc0929982005-09-05 19:08:29 +0000707 GENERIC_READ | GENERIC_WRITE,
708 FILE_SHARE_READ | FILE_SHARE_WRITE,
709 NULL,
710 OPEN_ALWAYS,
711 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
712 NULL
713 );
714 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000715 h = CreateFileA((char*)zConverted,
drhc0929982005-09-05 19:08:29 +0000716 GENERIC_READ,
drh94d57e32006-06-02 12:40:08 +0000717 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhc0929982005-09-05 19:08:29 +0000718 NULL,
719 OPEN_ALWAYS,
720 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
721 NULL
722 );
723 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000724 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +0000725 return SQLITE_CANTOPEN;
726 }
727 *pReadonly = 1;
728 }else{
729 *pReadonly = 0;
730 }
drhcc78fea2006-01-06 16:17:05 +0000731#endif /* OS_WINCE */
drhbbd42a62004-05-22 17:41:58 +0000732 }
drh371de5a2006-10-30 13:37:22 +0000733
734 sqliteFree(zConverted);
735
drh9cbe6352005-11-29 03:13:21 +0000736 f.h = h;
drh4bddfd22006-01-07 18:14:48 +0000737#if OS_WINCE
738 f.zDeleteOnClose = 0;
739#endif
drh51c6d962004-06-06 00:42:25 +0000740 TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000741 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000742}
743
744
745/*
746** Attempt to open a new file for exclusive access by this process.
747** The file will be opened for both reading and writing. To avoid
748** a potential security problem, we do not allow the file to have
749** previously existed. Nor do we allow the file to be a symbolic
750** link.
751**
752** If delFlag is true, then make arrangements to automatically delete
753** the file when it is closed.
754**
755** On success, write the file handle into *id and return SQLITE_OK.
756**
757** On failure, return SQLITE_CANTOPEN.
drh59e63a62006-06-04 23:31:48 +0000758**
759** Sometimes if we have just deleted a prior journal file, windows
760** will fail to open a new one because there is a "pending delete".
761** To work around this bug, we pause for 100 milliseconds and attempt
762** a second open after the first one fails. The whole operation only
763** fails if both open attempts are unsuccessful.
drhbbd42a62004-05-22 17:41:58 +0000764*/
drh66560ad2006-01-06 14:32:19 +0000765int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
drh054889e2005-11-30 03:20:31 +0000766 winFile f;
drhbbd42a62004-05-22 17:41:58 +0000767 HANDLE h;
drhec4d88f2006-12-21 00:46:42 +0000768 DWORD fileflags;
drh371de5a2006-10-30 13:37:22 +0000769 void *zConverted = convertUtf8Filename(zFilename);
770 if( zConverted==0 ){
771 return SQLITE_NOMEM;
772 }
drh9cbe6352005-11-29 03:13:21 +0000773 assert( *pId == 0 );
drhcc78fea2006-01-06 16:17:05 +0000774 fileflags = FILE_FLAG_RANDOM_ACCESS;
775#if !OS_WINCE
drhbbd42a62004-05-22 17:41:58 +0000776 if( delFlag ){
drhcc78fea2006-01-06 16:17:05 +0000777 fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
drhbbd42a62004-05-22 17:41:58 +0000778 }
drhcc78fea2006-01-06 16:17:05 +0000779#endif
drh371de5a2006-10-30 13:37:22 +0000780 if( isNT() ){
drheb4fa522006-06-04 23:02:20 +0000781 int cnt = 0;
782 do{
drh371de5a2006-10-30 13:37:22 +0000783 h = CreateFileW((WCHAR*)zConverted,
drheb4fa522006-06-04 23:02:20 +0000784 GENERIC_READ | GENERIC_WRITE,
785 0,
786 NULL,
787 CREATE_ALWAYS,
788 fileflags,
789 NULL
790 );
791 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
drhc0929982005-09-05 19:08:29 +0000792 }else{
drhcc78fea2006-01-06 16:17:05 +0000793#if OS_WINCE
794 return SQLITE_NOMEM;
795#else
drheb4fa522006-06-04 23:02:20 +0000796 int cnt = 0;
797 do{
drh371de5a2006-10-30 13:37:22 +0000798 h = CreateFileA((char*)zConverted,
drheb4fa522006-06-04 23:02:20 +0000799 GENERIC_READ | GENERIC_WRITE,
800 0,
801 NULL,
802 CREATE_ALWAYS,
803 fileflags,
804 NULL
805 );
806 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000807#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000808 }
drhc96d4982006-12-21 01:37:39 +0000809#if OS_WINCE
810 if( delFlag && h!=INVALID_HANDLE_VALUE ){
811 f.zDeleteOnClose = zConverted;
812 zConverted = 0;
813 }
814 f.hMutex = NULL;
815#endif
drh371de5a2006-10-30 13:37:22 +0000816 sqliteFree(zConverted);
drhbbd42a62004-05-22 17:41:58 +0000817 if( h==INVALID_HANDLE_VALUE ){
818 return SQLITE_CANTOPEN;
819 }
drh9cbe6352005-11-29 03:13:21 +0000820 f.h = h;
drh51c6d962004-06-06 00:42:25 +0000821 TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000822 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000823}
824
825/*
826** Attempt to open a new file for read-only access.
827**
828** On success, write the file handle into *id and return SQLITE_OK.
829**
830** On failure, return SQLITE_CANTOPEN.
831*/
drh66560ad2006-01-06 14:32:19 +0000832int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000833 winFile f;
drhda71ce12004-06-21 18:14:45 +0000834 HANDLE h;
drh371de5a2006-10-30 13:37:22 +0000835 void *zConverted = convertUtf8Filename(zFilename);
836 if( zConverted==0 ){
837 return SQLITE_NOMEM;
838 }
drh9cbe6352005-11-29 03:13:21 +0000839 assert( *pId==0 );
drh371de5a2006-10-30 13:37:22 +0000840 if( isNT() ){
841 h = CreateFileW((WCHAR*)zConverted,
drhc0929982005-09-05 19:08:29 +0000842 GENERIC_READ,
843 0,
844 NULL,
845 OPEN_EXISTING,
846 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
847 NULL
848 );
drhc0929982005-09-05 19:08:29 +0000849 }else{
drhcc78fea2006-01-06 16:17:05 +0000850#if OS_WINCE
851 return SQLITE_NOMEM;
852#else
drh371de5a2006-10-30 13:37:22 +0000853 h = CreateFileA((char*)zConverted,
drhc0929982005-09-05 19:08:29 +0000854 GENERIC_READ,
855 0,
856 NULL,
857 OPEN_EXISTING,
858 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
859 NULL
860 );
drhcc78fea2006-01-06 16:17:05 +0000861#endif
drhc0929982005-09-05 19:08:29 +0000862 }
drh371de5a2006-10-30 13:37:22 +0000863 sqliteFree(zConverted);
drhbbd42a62004-05-22 17:41:58 +0000864 if( h==INVALID_HANDLE_VALUE ){
865 return SQLITE_CANTOPEN;
866 }
drh9cbe6352005-11-29 03:13:21 +0000867 f.h = h;
drh4bddfd22006-01-07 18:14:48 +0000868#if OS_WINCE
869 f.zDeleteOnClose = 0;
drh36a50052006-01-23 22:15:07 +0000870 f.hMutex = NULL;
drh4bddfd22006-01-07 18:14:48 +0000871#endif
drh51c6d962004-06-06 00:42:25 +0000872 TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000873 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000874}
875
876/*
877** Attempt to open a file descriptor for the directory that contains a
878** file. This file descriptor can be used to fsync() the directory
879** in order to make sure the creation of a new file is actually written
880** to disk.
881**
882** This routine is only meaningful for Unix. It is a no-op under
883** windows since windows does not support hard links.
884**
885** On success, a handle for a previously open file is at *id is
886** updated with the new directory file descriptor and SQLITE_OK is
887** returned.
888**
889** On failure, the function returns SQLITE_CANTOPEN and leaves
890** *id unchanged.
891*/
drh9c06c952005-11-26 00:25:00 +0000892static int winOpenDirectory(
drh054889e2005-11-30 03:20:31 +0000893 OsFile *id,
894 const char *zDirname
drhbbd42a62004-05-22 17:41:58 +0000895){
896 return SQLITE_OK;
897}
898
899/*
drh3d2efea2004-08-28 01:12:56 +0000900** If the following global variable points to a string which is the
901** name of a directory, then that directory will be used to store
902** temporary files.
903*/
tpoindex9a09a3c2004-12-20 19:01:32 +0000904char *sqlite3_temp_directory = 0;
drh3d2efea2004-08-28 01:12:56 +0000905
906/*
drhbbd42a62004-05-22 17:41:58 +0000907** Create a temporary file name in zBuf. zBuf must be big enough to
908** hold at least SQLITE_TEMPNAME_SIZE characters.
909*/
drh66560ad2006-01-06 14:32:19 +0000910int sqlite3WinTempFileName(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +0000911 static char zChars[] =
912 "abcdefghijklmnopqrstuvwxyz"
913 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
914 "0123456789";
915 int i, j;
916 char zTempPath[SQLITE_TEMPNAME_SIZE];
drheffd02b2004-08-29 23:42:13 +0000917 if( sqlite3_temp_directory ){
918 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
drh3d2efea2004-08-28 01:12:56 +0000919 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
drhc0929982005-09-05 19:08:29 +0000920 }else if( isNT() ){
921 char *zMulti;
922 WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
923 GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
924 zMulti = unicodeToUtf8(zWidePath);
925 if( zMulti ){
drhd81bd4e2005-09-05 20:06:49 +0000926 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
drhc0929982005-09-05 19:08:29 +0000927 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
928 sqliteFree(zMulti);
drh371de5a2006-10-30 13:37:22 +0000929 }else{
930 return SQLITE_NOMEM;
drhc0929982005-09-05 19:08:29 +0000931 }
drh3d2efea2004-08-28 01:12:56 +0000932 }else{
drh371de5a2006-10-30 13:37:22 +0000933 char *zUtf8;
934 char zMbcsPath[SQLITE_TEMPNAME_SIZE];
935 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath);
936 zUtf8 = mbcsToUtf8(zMbcsPath);
937 if( zUtf8 ){
938 strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30);
939 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
940 sqliteFree(zUtf8);
941 }else{
942 return SQLITE_NOMEM;
943 }
drh3d2efea2004-08-28 01:12:56 +0000944 }
drhbbd42a62004-05-22 17:41:58 +0000945 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
946 zTempPath[i] = 0;
947 for(;;){
948 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
949 j = strlen(zBuf);
950 sqlite3Randomness(15, &zBuf[j]);
951 for(i=0; i<15; i++, j++){
952 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
953 }
954 zBuf[j] = 0;
drh66560ad2006-01-06 14:32:19 +0000955 if( !sqlite3OsFileExists(zBuf) ) break;
drhbbd42a62004-05-22 17:41:58 +0000956 }
drh51c6d962004-06-06 00:42:25 +0000957 TRACE2("TEMP FILENAME: %s\n", zBuf);
drhbbd42a62004-05-22 17:41:58 +0000958 return SQLITE_OK;
959}
960
961/*
962** Close a file.
drh59e63a62006-06-04 23:31:48 +0000963**
964** It is reported that an attempt to close a handle might sometimes
965** fail. This is a very unreasonable result, but windows is notorious
966** for being unreasonable so I do not doubt that it might happen. If
967** the close fails, we pause for 100 milliseconds and try again. As
968** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
969** giving up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000970*/
drh59e63a62006-06-04 23:31:48 +0000971#define MX_CLOSE_ATTEMPT 3
drh9cbe6352005-11-29 03:13:21 +0000972static int winClose(OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000973 winFile *pFile;
drheb4fa522006-06-04 23:02:20 +0000974 int rc = 1;
drh054889e2005-11-30 03:20:31 +0000975 if( pId && (pFile = (winFile*)*pId)!=0 ){
drheb4fa522006-06-04 23:02:20 +0000976 int rc, cnt = 0;
drh054889e2005-11-30 03:20:31 +0000977 TRACE2("CLOSE %d\n", pFile->h);
drheb4fa522006-06-04 23:02:20 +0000978 do{
979 rc = CloseHandle(pFile->h);
drh59e63a62006-06-04 23:31:48 +0000980 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000981#if OS_WINCE
drh72aead82006-01-23 15:54:25 +0000982 winceDestroyLock(pFile);
drhcc78fea2006-01-06 16:17:05 +0000983 if( pFile->zDeleteOnClose ){
drh9e9fe6f2006-01-06 21:09:01 +0000984 DeleteFileW(pFile->zDeleteOnClose);
drhcc78fea2006-01-06 16:17:05 +0000985 sqliteFree(pFile->zDeleteOnClose);
986 }
987#endif
drhda71ce12004-06-21 18:14:45 +0000988 OpenCounter(-1);
drh054889e2005-11-30 03:20:31 +0000989 sqliteFree(pFile);
drh9cbe6352005-11-29 03:13:21 +0000990 *pId = 0;
drhda71ce12004-06-21 18:14:45 +0000991 }
drheb4fa522006-06-04 23:02:20 +0000992 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000993}
994
995/*
996** Read data from a file into a buffer. Return SQLITE_OK if all
997** bytes were read successfully and SQLITE_IOERR if anything goes
998** wrong.
999*/
drh9c06c952005-11-26 00:25:00 +00001000static int winRead(OsFile *id, void *pBuf, int amt){
drhbbd42a62004-05-22 17:41:58 +00001001 DWORD got;
drh9cbe6352005-11-29 03:13:21 +00001002 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +00001003 SimulateIOError(return SQLITE_IOERR_READ);
drh054889e2005-11-30 03:20:31 +00001004 TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
1005 if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
drhaedd8922007-01-05 14:38:54 +00001006 return SQLITE_IOERR_READ;
drhbbd42a62004-05-22 17:41:58 +00001007 }
1008 if( got==(DWORD)amt ){
1009 return SQLITE_OK;
1010 }else{
drhbafda092007-01-03 23:36:22 +00001011 memset(&((char*)pBuf)[got], 0, amt-got);
drh551b7732006-11-06 21:20:25 +00001012 return SQLITE_IOERR_SHORT_READ;
drhbbd42a62004-05-22 17:41:58 +00001013 }
1014}
1015
1016/*
1017** Write data from a buffer into a file. Return SQLITE_OK on success
1018** or some other error code on failure.
1019*/
drh9c06c952005-11-26 00:25:00 +00001020static int winWrite(OsFile *id, const void *pBuf, int amt){
drh4c7f9412005-02-03 00:29:47 +00001021 int rc = 0;
drhbbd42a62004-05-22 17:41:58 +00001022 DWORD wrote;
drh9cbe6352005-11-29 03:13:21 +00001023 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +00001024 SimulateIOError(return SQLITE_IOERR_READ);
drh59685932006-09-14 13:47:11 +00001025 SimulateDiskfullError(return SQLITE_FULL);
drh054889e2005-11-30 03:20:31 +00001026 TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
drh4c7f9412005-02-03 00:29:47 +00001027 assert( amt>0 );
drh054889e2005-11-30 03:20:31 +00001028 while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
1029 && wrote>0 ){
drhbbd42a62004-05-22 17:41:58 +00001030 amt -= wrote;
1031 pBuf = &((char*)pBuf)[wrote];
1032 }
1033 if( !rc || amt>(int)wrote ){
1034 return SQLITE_FULL;
1035 }
1036 return SQLITE_OK;
1037}
1038
1039/*
drhbbdc2b92005-09-19 12:53:18 +00001040** Some microsoft compilers lack this definition.
1041*/
1042#ifndef INVALID_SET_FILE_POINTER
1043# define INVALID_SET_FILE_POINTER ((DWORD)-1)
1044#endif
1045
1046/*
drhbbd42a62004-05-22 17:41:58 +00001047** Move the read/write pointer in a file.
1048*/
drh9c06c952005-11-26 00:25:00 +00001049static int winSeek(OsFile *id, i64 offset){
drhbbd42a62004-05-22 17:41:58 +00001050 LONG upperBits = offset>>32;
1051 LONG lowerBits = offset & 0xffffffff;
1052 DWORD rc;
drh9cbe6352005-11-29 03:13:21 +00001053 assert( id!=0 );
drhb4746b92005-09-09 01:32:06 +00001054#ifdef SQLITE_TEST
drh59685932006-09-14 13:47:11 +00001055 if( offset ) SimulateDiskfullError(return SQLITE_FULL);
drhb4746b92005-09-09 01:32:06 +00001056#endif
drhbbd42a62004-05-22 17:41:58 +00001057 SEEK(offset/1024 + 1);
drh054889e2005-11-30 03:20:31 +00001058 rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
1059 TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
drhe08b8142005-09-09 10:17:33 +00001060 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
1061 return SQLITE_FULL;
1062 }
drhbbd42a62004-05-22 17:41:58 +00001063 return SQLITE_OK;
1064}
1065
1066/*
1067** Make sure all writes to a particular file are committed to disk.
1068*/
drh9c06c952005-11-26 00:25:00 +00001069static int winSync(OsFile *id, int dataOnly){
drh9cbe6352005-11-29 03:13:21 +00001070 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +00001071 TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
1072 if( FlushFileBuffers(((winFile*)id)->h) ){
drhbbd42a62004-05-22 17:41:58 +00001073 return SQLITE_OK;
1074 }else{
1075 return SQLITE_IOERR;
1076 }
1077}
1078
1079/*
danielk1977962398d2004-06-14 09:35:16 +00001080** Sync the directory zDirname. This is a no-op on operating systems other
1081** than UNIX.
1082*/
drh66560ad2006-01-06 14:32:19 +00001083int sqlite3WinSyncDirectory(const char *zDirname){
drh9cce7102007-01-09 17:18:19 +00001084 SimulateIOError(return SQLITE_IOERR_READ);
danielk1977962398d2004-06-14 09:35:16 +00001085 return SQLITE_OK;
1086}
1087
1088/*
drhbbd42a62004-05-22 17:41:58 +00001089** Truncate an open file to a specified size
1090*/
drh9c06c952005-11-26 00:25:00 +00001091static int winTruncate(OsFile *id, i64 nByte){
drhbbd42a62004-05-22 17:41:58 +00001092 LONG upperBits = nByte>>32;
drh9cbe6352005-11-29 03:13:21 +00001093 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +00001094 TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
drh9cce7102007-01-09 17:18:19 +00001095 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
drh054889e2005-11-30 03:20:31 +00001096 SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
1097 SetEndOfFile(((winFile*)id)->h);
drhbbd42a62004-05-22 17:41:58 +00001098 return SQLITE_OK;
1099}
1100
1101/*
1102** Determine the current size of a file in bytes
1103*/
drh9c06c952005-11-26 00:25:00 +00001104static int winFileSize(OsFile *id, i64 *pSize){
drhbbd42a62004-05-22 17:41:58 +00001105 DWORD upperBits, lowerBits;
drh9cbe6352005-11-29 03:13:21 +00001106 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +00001107 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh054889e2005-11-30 03:20:31 +00001108 lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
drheb206252004-10-01 02:00:31 +00001109 *pSize = (((i64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +00001110 return SQLITE_OK;
1111}
1112
1113/*
drh602bbd32006-01-06 20:22:29 +00001114** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
1115*/
1116#ifndef LOCKFILE_FAIL_IMMEDIATELY
1117# define LOCKFILE_FAIL_IMMEDIATELY 1
1118#endif
1119
1120/*
drh9c105bb2004-10-02 20:38:28 +00001121** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +00001122** Different API routines are called depending on whether or not this
1123** is Win95 or WinNT.
1124*/
drh054889e2005-11-30 03:20:31 +00001125static int getReadLock(winFile *id){
drh51c6d962004-06-06 00:42:25 +00001126 int res;
1127 if( isNT() ){
1128 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +00001129 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +00001130 ovlp.OffsetHigh = 0;
1131 ovlp.hEvent = 0;
drh9c105bb2004-10-02 20:38:28 +00001132 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
drhbbd42a62004-05-22 17:41:58 +00001133 }else{
drh9c105bb2004-10-02 20:38:28 +00001134 int lk;
1135 sqlite3Randomness(sizeof(lk), &lk);
1136 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
1137 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001138 }
1139 return res;
1140}
1141
1142/*
1143** Undo a readlock
1144*/
drh054889e2005-11-30 03:20:31 +00001145static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +00001146 int res;
1147 if( isNT() ){
drh054889e2005-11-30 03:20:31 +00001148 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drh51c6d962004-06-06 00:42:25 +00001149 }else{
drh054889e2005-11-30 03:20:31 +00001150 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001151 }
1152 return res;
1153}
1154
drh268283b2005-01-08 15:44:25 +00001155#ifndef SQLITE_OMIT_PAGER_PRAGMAS
drh51c6d962004-06-06 00:42:25 +00001156/*
tpoindex9a09a3c2004-12-20 19:01:32 +00001157** Check that a given pathname is a directory and is writable
1158**
1159*/
drh66560ad2006-01-06 14:32:19 +00001160int sqlite3WinIsDirWritable(char *zDirname){
tpoindex9a09a3c2004-12-20 19:01:32 +00001161 int fileAttr;
drh371de5a2006-10-30 13:37:22 +00001162 void *zConverted;
drhc0929982005-09-05 19:08:29 +00001163 if( zDirname==0 ) return 0;
1164 if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
drh371de5a2006-10-30 13:37:22 +00001165
1166 zConverted = convertUtf8Filename(zDirname);
1167 if( zConverted==0 ){
1168 return SQLITE_NOMEM;
1169 }
1170 if( isNT() ){
1171 fileAttr = GetFileAttributesW((WCHAR*)zConverted);
drhc0929982005-09-05 19:08:29 +00001172 }else{
drhcc78fea2006-01-06 16:17:05 +00001173#if OS_WINCE
1174 return 0;
1175#else
drh371de5a2006-10-30 13:37:22 +00001176 fileAttr = GetFileAttributesA((char*)zConverted);
drhcc78fea2006-01-06 16:17:05 +00001177#endif
drhc0929982005-09-05 19:08:29 +00001178 }
drh371de5a2006-10-30 13:37:22 +00001179 sqliteFree(zConverted);
tpoindex9a09a3c2004-12-20 19:01:32 +00001180 if( fileAttr == 0xffffffff ) return 0;
drh268283b2005-01-08 15:44:25 +00001181 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
1182 return 0;
1183 }
tpoindex9a09a3c2004-12-20 19:01:32 +00001184 return 1;
1185}
drh268283b2005-01-08 15:44:25 +00001186#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
tpoindex9a09a3c2004-12-20 19:01:32 +00001187
1188/*
drhb3e04342004-06-08 00:47:47 +00001189** Lock the file with the lock specified by parameter locktype - one
1190** of the following:
1191**
1192** (1) SHARED_LOCK
1193** (2) RESERVED_LOCK
1194** (3) PENDING_LOCK
1195** (4) EXCLUSIVE_LOCK
1196**
1197** Sometimes when requesting one lock state, additional lock states
1198** are inserted in between. The locking might fail on one of the later
1199** transitions leaving the lock state different from what it started but
1200** still short of its goal. The following chart shows the allowed
1201** transitions and the inserted intermediate states:
1202**
1203** UNLOCKED -> SHARED
1204** SHARED -> RESERVED
1205** SHARED -> (PENDING) -> EXCLUSIVE
1206** RESERVED -> (PENDING) -> EXCLUSIVE
1207** PENDING -> EXCLUSIVE
1208**
drh9c06c952005-11-26 00:25:00 +00001209** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +00001210** erases all locks at once and returns us immediately to locking level 0.
1211** It is not possible to lower the locking level one step at a time. You
1212** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +00001213*/
drh9c06c952005-11-26 00:25:00 +00001214static int winLock(OsFile *id, int locktype){
drh51c6d962004-06-06 00:42:25 +00001215 int rc = SQLITE_OK; /* Return code from subroutines */
1216 int res = 1; /* Result of a windows lock call */
drhe54ca3f2004-06-07 01:52:14 +00001217 int newLocktype; /* Set id->locktype to this value before exiting */
1218 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +00001219 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +00001220
drh054889e2005-11-30 03:20:31 +00001221 assert( pFile!=0 );
drhe54ca3f2004-06-07 01:52:14 +00001222 TRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +00001223 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +00001224
1225 /* If there is already a lock of this type or more restrictive on the
1226 ** OsFile, do nothing. Don't use the end_lock: exit path, as
1227 ** sqlite3OsEnterMutex() hasn't been called yet.
1228 */
drh054889e2005-11-30 03:20:31 +00001229 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +00001230 return SQLITE_OK;
1231 }
1232
drhb3e04342004-06-08 00:47:47 +00001233 /* Make sure the locking sequence is correct
1234 */
drh054889e2005-11-30 03:20:31 +00001235 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +00001236 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +00001237 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +00001238
drh51c6d962004-06-06 00:42:25 +00001239 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
1240 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
1241 ** the PENDING_LOCK byte is temporary.
1242 */
drh054889e2005-11-30 03:20:31 +00001243 newLocktype = pFile->locktype;
1244 if( pFile->locktype==NO_LOCK
1245 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +00001246 ){
drhb3e04342004-06-08 00:47:47 +00001247 int cnt = 3;
drh054889e2005-11-30 03:20:31 +00001248 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +00001249 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +00001250 ** held by another reader process who will release it momentarily.
1251 */
drhe54ca3f2004-06-07 01:52:14 +00001252 TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +00001253 Sleep(1);
1254 }
drhe54ca3f2004-06-07 01:52:14 +00001255 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +00001256 }
1257
1258 /* Acquire a shared lock
1259 */
drhb3e04342004-06-08 00:47:47 +00001260 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001261 assert( pFile->locktype==NO_LOCK );
1262 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +00001263 if( res ){
1264 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +00001265 }
1266 }
1267
1268 /* Acquire a RESERVED lock
1269 */
drhb3e04342004-06-08 00:47:47 +00001270 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001271 assert( pFile->locktype==SHARED_LOCK );
1272 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +00001273 if( res ){
1274 newLocktype = RESERVED_LOCK;
1275 }
1276 }
1277
1278 /* Acquire a PENDING lock
1279 */
drhb3e04342004-06-08 00:47:47 +00001280 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +00001281 newLocktype = PENDING_LOCK;
1282 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +00001283 }
1284
1285 /* Acquire an EXCLUSIVE lock
1286 */
drhe54ca3f2004-06-07 01:52:14 +00001287 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001288 assert( pFile->locktype>=SHARED_LOCK );
1289 res = unlockReadLock(pFile);
drhb3e04342004-06-08 00:47:47 +00001290 TRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +00001291 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +00001292 if( res ){
1293 newLocktype = EXCLUSIVE_LOCK;
1294 }else{
1295 TRACE2("error-code = %d\n", GetLastError());
1296 }
1297 }
1298
1299 /* If we are holding a PENDING lock that ought to be released, then
1300 ** release it now.
1301 */
drhb3e04342004-06-08 00:47:47 +00001302 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001303 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001304 }
1305
1306 /* Update the state of the lock has held in the file descriptor then
1307 ** return the appropriate result code.
1308 */
1309 if( res ){
drh51c6d962004-06-06 00:42:25 +00001310 rc = SQLITE_OK;
1311 }else{
drh054889e2005-11-30 03:20:31 +00001312 TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +00001313 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +00001314 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +00001315 }
drh054889e2005-11-30 03:20:31 +00001316 pFile->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +00001317 return rc;
1318}
1319
1320/*
drh51c6d962004-06-06 00:42:25 +00001321** This routine checks if there is a RESERVED lock held on the specified
1322** file by this or any other process. If such a lock is held, return
1323** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +00001324*/
drh9c06c952005-11-26 00:25:00 +00001325static int winCheckReservedLock(OsFile *id){
drhbbd42a62004-05-22 17:41:58 +00001326 int rc;
drh054889e2005-11-30 03:20:31 +00001327 winFile *pFile = (winFile*)id;
1328 assert( pFile!=0 );
1329 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +00001330 rc = 1;
drh054889e2005-11-30 03:20:31 +00001331 TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001332 }else{
drh054889e2005-11-30 03:20:31 +00001333 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001334 if( rc ){
drh054889e2005-11-30 03:20:31 +00001335 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +00001336 }
drh2ac3ee92004-06-07 16:27:46 +00001337 rc = !rc;
drh054889e2005-11-30 03:20:31 +00001338 TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001339 }
drh2ac3ee92004-06-07 16:27:46 +00001340 return rc;
drhbbd42a62004-05-22 17:41:58 +00001341}
1342
1343/*
drha6abd042004-06-09 17:37:22 +00001344** Lower the locking level on file descriptor id to locktype. locktype
1345** must be either NO_LOCK or SHARED_LOCK.
1346**
1347** If the locking level of the file descriptor is already at or below
1348** the requested locking level, this routine is a no-op.
1349**
drh9c105bb2004-10-02 20:38:28 +00001350** It is not possible for this routine to fail if the second argument
1351** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1352** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +00001353*/
drh9c06c952005-11-26 00:25:00 +00001354static int winUnlock(OsFile *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001355 int type;
1356 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001357 winFile *pFile = (winFile*)id;
1358 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001359 assert( locktype<=SHARED_LOCK );
drh054889e2005-11-30 03:20:31 +00001360 TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
1361 pFile->locktype, pFile->sharedLockByte);
1362 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001363 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001364 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1365 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001366 /* This should never happen. We should always be able to
1367 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +00001368 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +00001369 }
drhbbd42a62004-05-22 17:41:58 +00001370 }
drhe54ca3f2004-06-07 01:52:14 +00001371 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001372 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001373 }
drh9c105bb2004-10-02 20:38:28 +00001374 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001375 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001376 }
drhb3e04342004-06-08 00:47:47 +00001377 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001378 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001379 }
drh054889e2005-11-30 03:20:31 +00001380 pFile->locktype = locktype;
drh9c105bb2004-10-02 20:38:28 +00001381 return rc;
drhbbd42a62004-05-22 17:41:58 +00001382}
1383
1384/*
drh0ccebe72005-06-07 22:22:50 +00001385** Turn a relative pathname into a full pathname. Return a pointer
1386** to the full pathname stored in space obtained from sqliteMalloc().
1387** The calling function is responsible for freeing this space once it
1388** is no longer needed.
1389*/
drh66560ad2006-01-06 14:32:19 +00001390char *sqlite3WinFullPathname(const char *zRelative){
drh0ccebe72005-06-07 22:22:50 +00001391 char *zFull;
drhcc78fea2006-01-06 16:17:05 +00001392#if defined(__CYGWIN__)
drh0ccebe72005-06-07 22:22:50 +00001393 int nByte;
drh0ccebe72005-06-07 22:22:50 +00001394 nByte = strlen(zRelative) + MAX_PATH + 1001;
1395 zFull = sqliteMalloc( nByte );
1396 if( zFull==0 ) return 0;
1397 if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
drhcc78fea2006-01-06 16:17:05 +00001398#elif OS_WINCE
1399 /* WinCE has no concept of a relative pathname, or so I am told. */
danielk1977e7259292006-01-13 06:33:23 +00001400 zFull = sqliteStrDup(zRelative);
drh0ccebe72005-06-07 22:22:50 +00001401#else
drhcc78fea2006-01-06 16:17:05 +00001402 int nByte;
drh371de5a2006-10-30 13:37:22 +00001403 void *zConverted;
1404 zConverted = convertUtf8Filename(zRelative);
1405 if( isNT() ){
drhfb02d262007-01-09 15:32:17 +00001406 WCHAR *zTemp;
1407 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhc0929982005-09-05 19:08:29 +00001408 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
drh371de5a2006-10-30 13:37:22 +00001409 if( zTemp==0 ){
1410 sqliteFree(zConverted);
1411 return 0;
1412 }
drhfb02d262007-01-09 15:32:17 +00001413 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drh371de5a2006-10-30 13:37:22 +00001414 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +00001415 zFull = unicodeToUtf8(zTemp);
1416 sqliteFree(zTemp);
1417 }else{
drhfb02d262007-01-09 15:32:17 +00001418 char *zTemp;
1419 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drh371de5a2006-10-30 13:37:22 +00001420 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
1421 if( zTemp==0 ){
1422 sqliteFree(zConverted);
1423 return 0;
1424 }
drhfb02d262007-01-09 15:32:17 +00001425 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drh371de5a2006-10-30 13:37:22 +00001426 sqliteFree(zConverted);
1427 zFull = mbcsToUtf8(zTemp);
1428 sqliteFree(zTemp);
drhc0929982005-09-05 19:08:29 +00001429 }
drh0ccebe72005-06-07 22:22:50 +00001430#endif
1431 return zFull;
1432}
1433
drh9c06c952005-11-26 00:25:00 +00001434/*
drh9cbe6352005-11-29 03:13:21 +00001435** The fullSync option is meaningless on windows. This is a no-op.
drh18839212005-11-26 03:43:23 +00001436*/
drh9cbe6352005-11-29 03:13:21 +00001437static void winSetFullSync(OsFile *id, int v){
1438 return;
1439}
1440
1441/*
1442** Return the underlying file handle for an OsFile
1443*/
1444static int winFileHandle(OsFile *id){
drh054889e2005-11-30 03:20:31 +00001445 return (int)((winFile*)id)->h;
drh9cbe6352005-11-29 03:13:21 +00001446}
1447
1448/*
1449** Return an integer that indices the type of lock currently held
1450** by this handle. (Used for testing and analysis only.)
1451*/
1452static int winLockState(OsFile *id){
drh054889e2005-11-30 03:20:31 +00001453 return ((winFile*)id)->locktype;
drh18839212005-11-26 03:43:23 +00001454}
1455
drh18839212005-11-26 03:43:23 +00001456/*
drh054889e2005-11-30 03:20:31 +00001457** This vector defines all the methods that can operate on an OsFile
1458** for win32.
drh9c06c952005-11-26 00:25:00 +00001459*/
drh054889e2005-11-30 03:20:31 +00001460static const IoMethod sqlite3WinIoMethod = {
drh9c06c952005-11-26 00:25:00 +00001461 winClose,
drh054889e2005-11-30 03:20:31 +00001462 winOpenDirectory,
drh9c06c952005-11-26 00:25:00 +00001463 winRead,
1464 winWrite,
1465 winSeek,
drh9c06c952005-11-26 00:25:00 +00001466 winTruncate,
drh054889e2005-11-30 03:20:31 +00001467 winSync,
drh9cbe6352005-11-29 03:13:21 +00001468 winSetFullSync,
1469 winFileHandle,
drh054889e2005-11-30 03:20:31 +00001470 winFileSize,
1471 winLock,
1472 winUnlock,
drh9cbe6352005-11-29 03:13:21 +00001473 winLockState,
drh054889e2005-11-30 03:20:31 +00001474 winCheckReservedLock,
drh9c06c952005-11-26 00:25:00 +00001475};
1476
drh054889e2005-11-30 03:20:31 +00001477/*
1478** Allocate memory for an OsFile. Initialize the new OsFile
1479** to the value given in pInit and return a pointer to the new
1480** OsFile. If we run out of memory, close the file and return NULL.
1481*/
danielk1977f0113002006-01-24 12:09:17 +00001482static int allocateWinFile(winFile *pInit, OsFile **pId){
drh054889e2005-11-30 03:20:31 +00001483 winFile *pNew;
1484 pNew = sqliteMalloc( sizeof(*pNew) );
1485 if( pNew==0 ){
1486 CloseHandle(pInit->h);
drhcc78fea2006-01-06 16:17:05 +00001487#if OS_WINCE
1488 sqliteFree(pInit->zDeleteOnClose);
1489#endif
drh054889e2005-11-30 03:20:31 +00001490 *pId = 0;
1491 return SQLITE_NOMEM;
1492 }else{
1493 *pNew = *pInit;
1494 pNew->pMethod = &sqlite3WinIoMethod;
drhbe1f84c2006-01-23 16:25:22 +00001495 pNew->locktype = NO_LOCK;
1496 pNew->sharedLockByte = 0;
drh66560ad2006-01-06 14:32:19 +00001497 *pId = (OsFile*)pNew;
drhbe1f84c2006-01-23 16:25:22 +00001498 OpenCounter(+1);
drh054889e2005-11-30 03:20:31 +00001499 return SQLITE_OK;
1500 }
1501}
1502
1503
drh0ccebe72005-06-07 22:22:50 +00001504#endif /* SQLITE_OMIT_DISKIO */
1505/***************************************************************************
1506** Everything above deals with file I/O. Everything that follows deals
1507** with other miscellanous aspects of the operating system interface
1508****************************************************************************/
1509
drh761df872006-12-21 01:29:22 +00001510#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
1511/*
1512** Interfaces for opening a shared library, finding entry points
1513** within the shared library, and closing the shared library.
1514*/
1515void *sqlite3WinDlopen(const char *zFilename){
1516 HANDLE h;
1517 void *zConverted = convertUtf8Filename(zFilename);
1518 if( zConverted==0 ){
1519 return 0;
1520 }
1521 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00001522 h = LoadLibraryW((WCHAR*)zConverted);
drh761df872006-12-21 01:29:22 +00001523 }else{
1524#if OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00001525 return 0;
drh761df872006-12-21 01:29:22 +00001526#else
drh584c0942006-12-21 03:20:40 +00001527 h = LoadLibraryA((char*)zConverted);
drh761df872006-12-21 01:29:22 +00001528#endif
1529 }
1530 sqliteFree(zConverted);
1531 return (void*)h;
1532
1533}
1534void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
drh2a4d54b2006-12-21 02:21:56 +00001535#if OS_WINCE
1536 /* The GetProcAddressA() routine is only available on wince. */
1537 return GetProcAddressA((HANDLE)pHandle, zSymbol);
1538#else
1539 /* All other windows platforms expect GetProcAddress() to take
1540 ** an Ansi string regardless of the _UNICODE setting */
drh761df872006-12-21 01:29:22 +00001541 return GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001542#endif
drh761df872006-12-21 01:29:22 +00001543}
1544int sqlite3WinDlclose(void *pHandle){
1545 return FreeLibrary((HANDLE)pHandle);
1546}
1547#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
1548
drh0ccebe72005-06-07 22:22:50 +00001549/*
drhbbd42a62004-05-22 17:41:58 +00001550** Get information to seed the random number generator. The seed
1551** is written into the buffer zBuf[256]. The calling function must
1552** supply a sufficiently large buffer.
1553*/
drh66560ad2006-01-06 14:32:19 +00001554int sqlite3WinRandomSeed(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +00001555 /* We have to initialize zBuf to prevent valgrind from reporting
1556 ** errors. The reports issued by valgrind are incorrect - we would
1557 ** prefer that the randomness be increased by making use of the
1558 ** uninitialized space in zBuf - but valgrind errors tend to worry
1559 ** some users. Rather than argue, it seems easier just to initialize
1560 ** the whole array and silence valgrind, even if that means less randomness
1561 ** in the random seed.
1562 **
1563 ** When testing, initializing zBuf[] to zero is all we do. That means
1564 ** that we always use the same random number sequence.* This makes the
1565 ** tests repeatable.
1566 */
1567 memset(zBuf, 0, 256);
1568 GetSystemTime((LPSYSTEMTIME)zBuf);
1569 return SQLITE_OK;
1570}
1571
1572/*
1573** Sleep for a little while. Return the amount of time slept.
1574*/
drh66560ad2006-01-06 14:32:19 +00001575int sqlite3WinSleep(int ms){
drhbbd42a62004-05-22 17:41:58 +00001576 Sleep(ms);
1577 return ms;
1578}
1579
1580/*
1581** Static variables used for thread synchronization
1582*/
1583static int inMutex = 0;
1584#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001585 static DWORD mutexOwner;
drhbbd42a62004-05-22 17:41:58 +00001586 static CRITICAL_SECTION cs;
1587#endif
1588
1589/*
drh757b04e2006-01-18 17:25:45 +00001590** The following pair of routines implement mutual exclusion for
drhbbd42a62004-05-22 17:41:58 +00001591** multi-threaded processes. Only a single thread is allowed to
1592** executed code that is surrounded by EnterMutex() and LeaveMutex().
1593**
1594** SQLite uses only a single Mutex. There is not much critical
1595** code and what little there is executes quickly and without blocking.
drh757b04e2006-01-18 17:25:45 +00001596**
1597** Version 3.3.1 and earlier used a simple mutex. Beginning with
1598** version 3.3.2, a recursive mutex is required.
drhbbd42a62004-05-22 17:41:58 +00001599*/
drh66560ad2006-01-06 14:32:19 +00001600void sqlite3WinEnterMutex(){
drhbbd42a62004-05-22 17:41:58 +00001601#ifdef SQLITE_W32_THREADS
1602 static int isInit = 0;
1603 while( !isInit ){
1604 static long lock = 0;
1605 if( InterlockedIncrement(&lock)==1 ){
1606 InitializeCriticalSection(&cs);
1607 isInit = 1;
1608 }else{
1609 Sleep(1);
1610 }
1611 }
1612 EnterCriticalSection(&cs);
drh757b04e2006-01-18 17:25:45 +00001613 mutexOwner = GetCurrentThreadId();
drhbbd42a62004-05-22 17:41:58 +00001614#endif
drh332b1fe2006-01-18 14:20:17 +00001615 inMutex++;
drhbbd42a62004-05-22 17:41:58 +00001616}
drh66560ad2006-01-06 14:32:19 +00001617void sqlite3WinLeaveMutex(){
drhbbd42a62004-05-22 17:41:58 +00001618 assert( inMutex );
drh332b1fe2006-01-18 14:20:17 +00001619 inMutex--;
drhbbd42a62004-05-22 17:41:58 +00001620#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001621 assert( mutexOwner==GetCurrentThreadId() );
drhbbd42a62004-05-22 17:41:58 +00001622 LeaveCriticalSection(&cs);
1623#endif
1624}
1625
1626/*
drh757b04e2006-01-18 17:25:45 +00001627** Return TRUE if the mutex is currently held.
1628**
1629** If the thisThreadOnly parameter is true, return true if and only if the
1630** calling thread holds the mutex. If the parameter is false, return
1631** true if any thread holds the mutex.
drh88f474a2006-01-02 20:00:12 +00001632*/
drh757b04e2006-01-18 17:25:45 +00001633int sqlite3WinInMutex(int thisThreadOnly){
drh332b1fe2006-01-18 14:20:17 +00001634#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001635 return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId());
drh332b1fe2006-01-18 14:20:17 +00001636#else
drh757b04e2006-01-18 17:25:45 +00001637 return inMutex>0;
drh332b1fe2006-01-18 14:20:17 +00001638#endif
drh88f474a2006-01-02 20:00:12 +00001639}
1640
1641
1642/*
drhbbd42a62004-05-22 17:41:58 +00001643** The following variable, if set to a non-zero value, becomes the result
1644** returned from sqlite3OsCurrentTime(). This is used for testing.
1645*/
1646#ifdef SQLITE_TEST
1647int sqlite3_current_time = 0;
1648#endif
1649
1650/*
1651** Find the current time (in Universal Coordinated Time). Write the
1652** current time and date as a Julian Day number into *prNow and
1653** return 0. Return 1 if the time and date cannot be found.
1654*/
drh66560ad2006-01-06 14:32:19 +00001655int sqlite3WinCurrentTime(double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001656 FILETIME ft;
1657 /* FILETIME structure is a 64-bit value representing the number of
1658 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1659 */
1660 double now;
drhcc78fea2006-01-06 16:17:05 +00001661#if OS_WINCE
1662 SYSTEMTIME time;
1663 GetSystemTime(&time);
1664 SystemTimeToFileTime(&time,&ft);
1665#else
drhbbd42a62004-05-22 17:41:58 +00001666 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001667#endif
drhbbd42a62004-05-22 17:41:58 +00001668 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1669 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1670#ifdef SQLITE_TEST
1671 if( sqlite3_current_time ){
1672 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1673 }
1674#endif
1675 return 0;
1676}
1677
drh6f7adc82006-01-11 21:41:20 +00001678/*
drhb4bc7052006-01-11 23:40:33 +00001679** Remember the number of thread-specific-data blocks allocated.
1680** Use this to verify that we are not leaking thread-specific-data.
1681** Ticket #1601
1682*/
1683#ifdef SQLITE_TEST
1684int sqlite3_tsd_count = 0;
1685# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
1686# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
1687#else
1688# define TSD_COUNTER_INCR /* no-op */
1689# define TSD_COUNTER_DECR /* no-op */
1690#endif
1691
1692
1693
1694/*
drh70ff98a2006-01-12 01:25:18 +00001695** If called with allocateFlag>1, then return a pointer to thread
drh6f7adc82006-01-11 21:41:20 +00001696** specific data for the current thread. Allocate and zero the
1697** thread-specific data if it does not already exist necessary.
drh3fbb0b12006-01-06 00:36:00 +00001698**
drh6f7adc82006-01-11 21:41:20 +00001699** If called with allocateFlag==0, then check the current thread
drh70ff98a2006-01-12 01:25:18 +00001700** specific data. Return it if it exists. If it does not exist,
1701** then return NULL.
1702**
1703** If called with allocateFlag<0, check to see if the thread specific
1704** data is allocated and is all zero. If it is then deallocate it.
drh6f7adc82006-01-11 21:41:20 +00001705** Return a pointer to the thread specific data or NULL if it is
drh70ff98a2006-01-12 01:25:18 +00001706** unallocated or gets deallocated.
danielk197713a68c32005-12-15 10:11:30 +00001707*/
drhb4bc7052006-01-11 23:40:33 +00001708ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
drh3fbb0b12006-01-06 00:36:00 +00001709 static int key;
1710 static int keyInit = 0;
drh0850b532006-01-31 19:31:43 +00001711 static const ThreadData zeroData = {0};
drhb4bc7052006-01-11 23:40:33 +00001712 ThreadData *pTsd;
drh3fbb0b12006-01-06 00:36:00 +00001713
1714 if( !keyInit ){
drh66560ad2006-01-06 14:32:19 +00001715 sqlite3OsEnterMutex();
drh3fbb0b12006-01-06 00:36:00 +00001716 if( !keyInit ){
1717 key = TlsAlloc();
1718 if( key==0xffffffff ){
drh66560ad2006-01-06 14:32:19 +00001719 sqlite3OsLeaveMutex();
drh3fbb0b12006-01-06 00:36:00 +00001720 return 0;
1721 }
1722 keyInit = 1;
1723 }
drh66560ad2006-01-06 14:32:19 +00001724 sqlite3OsLeaveMutex();
danielk197713a68c32005-12-15 10:11:30 +00001725 }
drh3fbb0b12006-01-06 00:36:00 +00001726 pTsd = TlsGetValue(key);
drh70ff98a2006-01-12 01:25:18 +00001727 if( allocateFlag>0 ){
drh6f7adc82006-01-11 21:41:20 +00001728 if( !pTsd ){
drhb4bc7052006-01-11 23:40:33 +00001729 pTsd = sqlite3OsMalloc( sizeof(zeroData) );
drh6f7adc82006-01-11 21:41:20 +00001730 if( pTsd ){
1731 *pTsd = zeroData;
1732 TlsSetValue(key, pTsd);
drhb4bc7052006-01-11 23:40:33 +00001733 TSD_COUNTER_INCR;
drh6f7adc82006-01-11 21:41:20 +00001734 }
drh3fbb0b12006-01-06 00:36:00 +00001735 }
drh70ff98a2006-01-12 01:25:18 +00001736 }else if( pTsd!=0 && allocateFlag<0
danielk19779e128002006-01-18 16:51:35 +00001737 && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
drh6f7adc82006-01-11 21:41:20 +00001738 sqlite3OsFree(pTsd);
1739 TlsSetValue(key, 0);
drhb4bc7052006-01-11 23:40:33 +00001740 TSD_COUNTER_DECR;
drh6f7adc82006-01-11 21:41:20 +00001741 pTsd = 0;
drh3fbb0b12006-01-06 00:36:00 +00001742 }
1743 return pTsd;
danielk197713a68c32005-12-15 10:11:30 +00001744}
drhbbd42a62004-05-22 17:41:58 +00001745#endif /* OS_WIN */