blob: e5cf7ad5c16e1950a05b8d720e4cbb0f89c34f67 [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
drhd2832bf2007-01-10 18:56:15 +000043# define AreFileApisANSI() 1
drhcc78fea2006-01-06 16:17:05 +000044#else
45# define OS_WINCE 0
46#endif
47
48/*
drh72aead82006-01-23 15:54:25 +000049** 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/*
drh054889e2005-11-30 03:20:31 +000062** The winFile structure is a subclass of OsFile specific to the win32
63** portability layer.
drh9cbe6352005-11-29 03:13:21 +000064*/
drh054889e2005-11-30 03:20:31 +000065typedef struct winFile winFile;
66struct winFile {
67 IoMethod const *pMethod;/* Must be first */
drh9cbe6352005-11-29 03:13:21 +000068 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 */
drhcc78fea2006-01-06 16:17:05 +000071#if OS_WINCE
drh72aead82006-01-23 15:54:25 +000072 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 */
drhcc78fea2006-01-06 16:17:05 +000077#endif
drh9cbe6352005-11-29 03:13:21 +000078};
79
80
drh9cbe6352005-11-29 03:13:21 +000081/*
drh0ccebe72005-06-07 22:22:50 +000082** 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/*
drhc0929982005-09-05 19:08:29 +000089** 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/*
drhcc78fea2006-01-06 16:17:05 +0000103** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
104** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +0000105**
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*/
drhcc78fea2006-01-06 16:17:05 +0000113#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;
drhc0929982005-09-05 19:08:29 +0000124 }
drhcc78fea2006-01-06 16:17:05 +0000125#endif /* OS_WINCE */
126
drhc0929982005-09-05 19:08:29 +0000127/*
drh584c0942006-12-21 03:20:40 +0000128** Convert a UTF-8 string to microsoft unicode (UTF-16?).
129**
130** Space to hold the returned string is obtained from sqliteMalloc.
drhc0929982005-09-05 19:08:29 +0000131*/
132static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000133 int nChar;
drhc0929982005-09-05 19:08:29 +0000134 WCHAR *zWideFilename;
135
drhe3dd8bb2006-02-27 23:44:35 +0000136 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
137 zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000138 if( zWideFilename==0 ){
139 return 0;
140 }
drhe3dd8bb2006-02-27 23:44:35 +0000141 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
142 if( nChar==0 ){
drhc0929982005-09-05 19:08:29 +0000143 sqliteFree(zWideFilename);
144 zWideFilename = 0;
145 }
146 return zWideFilename;
147}
148
149/*
drh584c0942006-12-21 03:20:40 +0000150** Convert microsoft unicode to UTF-8. Space to hold the returned string is
drhc0929982005-09-05 19:08:29 +0000151** 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
drh371de5a2006-10-30 13:37:22 +0000171/*
drh584c0942006-12-21 03:20:40 +0000172** 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
drh371de5a2006-10-30 13:37:22 +0000176** from sqliteMalloc.
177*/
178static WCHAR *mbcsToUnicode(const char *zFilename){
179 int nByte;
180 WCHAR *zMbcsFilename;
drh584c0942006-12-21 03:20:40 +0000181 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000182
drh584c0942006-12-21 03:20:40 +0000183 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
drh371de5a2006-10-30 13:37:22 +0000184 zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) );
185 if( zMbcsFilename==0 ){
186 return 0;
187 }
drh584c0942006-12-21 03:20:40 +0000188 nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
drh371de5a2006-10-30 13:37:22 +0000189 if( nByte==0 ){
190 sqliteFree(zMbcsFilename);
191 zMbcsFilename = 0;
192 }
193 return zMbcsFilename;
194}
195
196/*
drh584c0942006-12-21 03:20:40 +0000197** 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
drh371de5a2006-10-30 13:37:22 +0000201** sqliteMalloc().
202*/
203static char *unicodeToMbcs(const WCHAR *zWideFilename){
204 int nByte;
205 char *zFilename;
drh584c0942006-12-21 03:20:40 +0000206 int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
drh371de5a2006-10-30 13:37:22 +0000207
drh584c0942006-12-21 03:20:40 +0000208 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
drh371de5a2006-10-30 13:37:22 +0000209 zFilename = sqliteMalloc( nByte );
210 if( zFilename==0 ){
211 return 0;
212 }
drh584c0942006-12-21 03:20:40 +0000213 nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
drh371de5a2006-10-30 13:37:22 +0000214 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
drh72aead82006-01-23 15:54:25 +0000256#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 /* Done with the mutex */
412 winceMutexRelease(pFile->hMutex);
413 CloseHandle(pFile->hMutex);
414 pFile->hMutex = NULL;
415 }
416}
417
418/*
419** An implementation of the LockFile() API of windows for wince
420*/
421static BOOL winceLockFile(
422 HANDLE *phFile,
423 DWORD dwFileOffsetLow,
424 DWORD dwFileOffsetHigh,
425 DWORD nNumberOfBytesToLockLow,
426 DWORD nNumberOfBytesToLockHigh
427){
428 winFile *pFile = HANDLE_TO_WINFILE(phFile);
429 BOOL bReturn = FALSE;
430
431 if (!pFile->hMutex) return TRUE;
432 winceMutexAcquire(pFile->hMutex);
433
434 /* Wanting an exclusive lock? */
435 if (dwFileOffsetLow == SHARED_FIRST
436 && nNumberOfBytesToLockLow == SHARED_SIZE){
437 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
438 pFile->shared->bExclusive = TRUE;
439 pFile->local.bExclusive = TRUE;
440 bReturn = TRUE;
441 }
442 }
443
444 /* Want a read-only lock? */
445 else if ((dwFileOffsetLow >= SHARED_FIRST &&
446 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
447 nNumberOfBytesToLockLow == 1){
448 if (pFile->shared->bExclusive == 0){
449 pFile->local.nReaders ++;
450 if (pFile->local.nReaders == 1){
451 pFile->shared->nReaders ++;
452 }
453 bReturn = TRUE;
454 }
455 }
456
457 /* Want a pending lock? */
458 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
459 /* If no pending lock has been acquired, then acquire it */
460 if (pFile->shared->bPending == 0) {
461 pFile->shared->bPending = TRUE;
462 pFile->local.bPending = TRUE;
463 bReturn = TRUE;
464 }
465 }
466 /* Want a reserved lock? */
467 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
468 if (pFile->shared->bReserved == 0) {
469 pFile->shared->bReserved = TRUE;
470 pFile->local.bReserved = TRUE;
471 bReturn = TRUE;
472 }
473 }
474
475 winceMutexRelease(pFile->hMutex);
476 return bReturn;
477}
478
479/*
480** An implementation of the UnlockFile API of windows for wince
481*/
482static BOOL winceUnlockFile(
483 HANDLE *phFile,
484 DWORD dwFileOffsetLow,
485 DWORD dwFileOffsetHigh,
486 DWORD nNumberOfBytesToUnlockLow,
487 DWORD nNumberOfBytesToUnlockHigh
488){
489 winFile *pFile = HANDLE_TO_WINFILE(phFile);
490 BOOL bReturn = FALSE;
491
492 if (!pFile->hMutex) return TRUE;
493 winceMutexAcquire(pFile->hMutex);
494
495 /* Releasing a reader lock or an exclusive lock */
496 if (dwFileOffsetLow >= SHARED_FIRST &&
497 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
498 /* Did we have an exclusive lock? */
499 if (pFile->local.bExclusive){
500 pFile->local.bExclusive = FALSE;
501 pFile->shared->bExclusive = FALSE;
502 bReturn = TRUE;
503 }
504
505 /* Did we just have a reader lock? */
506 else if (pFile->local.nReaders){
507 pFile->local.nReaders --;
508 if (pFile->local.nReaders == 0)
509 {
510 pFile->shared->nReaders --;
511 }
512 bReturn = TRUE;
513 }
514 }
515
516 /* Releasing a pending lock */
517 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
518 if (pFile->local.bPending){
519 pFile->local.bPending = FALSE;
520 pFile->shared->bPending = FALSE;
521 bReturn = TRUE;
522 }
523 }
524 /* Releasing a reserved lock */
525 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
526 if (pFile->local.bReserved) {
527 pFile->local.bReserved = FALSE;
528 pFile->shared->bReserved = FALSE;
529 bReturn = TRUE;
530 }
531 }
532
533 winceMutexRelease(pFile->hMutex);
534 return bReturn;
535}
536
537/*
538** An implementation of the LockFileEx() API of windows for wince
539*/
540static BOOL winceLockFileEx(
541 HANDLE *phFile,
542 DWORD dwFlags,
543 DWORD dwReserved,
544 DWORD nNumberOfBytesToLockLow,
545 DWORD nNumberOfBytesToLockHigh,
546 LPOVERLAPPED lpOverlapped
547){
548 /* If the caller wants a shared read lock, forward this call
549 ** to winceLockFile */
550 if (lpOverlapped->Offset == SHARED_FIRST &&
551 dwFlags == 1 &&
552 nNumberOfBytesToLockLow == SHARED_SIZE){
553 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
554 }
555 return FALSE;
556}
557/*
558** End of the special code for wince
559*****************************************************************************/
560#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000561
562/*
drh371de5a2006-10-30 13:37:22 +0000563** Convert a UTF-8 filename into whatever form the underlying
564** operating system wants filenames in. Space to hold the result
565** is obtained from sqliteMalloc and must be freed by the calling
566** function.
567*/
568static void *convertUtf8Filename(const char *zFilename){
569 void *zConverted = 0;
570 if( isNT() ){
571 zConverted = utf8ToUnicode(zFilename);
572 }else{
573 zConverted = utf8ToMbcs(zFilename);
574 }
575 /* caller will handle out of memory */
576 return zConverted;
577}
578
579/*
drh59e63a62006-06-04 23:31:48 +0000580** Delete the named file.
581**
582** Note that windows does not allow a file to be deleted if some other
583** process has it open. Sometimes a virus scanner or indexing program
584** will open a journal file shortly after it is created in order to do
585** whatever it is it does. While this other process is holding the
586** file open, we will be unable to delete it. To work around this
587** problem, we delay 100 milliseconds and try to delete again. Up
588** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
589** up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000590*/
drh59e63a62006-06-04 23:31:48 +0000591#define MX_DELETION_ATTEMPTS 3
drh66560ad2006-01-06 14:32:19 +0000592int sqlite3WinDelete(const char *zFilename){
drheb4fa522006-06-04 23:02:20 +0000593 int cnt = 0;
594 int rc;
drh371de5a2006-10-30 13:37:22 +0000595 void *zConverted = convertUtf8Filename(zFilename);
596 if( zConverted==0 ){
597 return SQLITE_NOMEM;
598 }
danielk1977979f38e2007-03-27 16:19:51 +0000599 SimulateIOError(return SQLITE_IOERR_DELETE);
drh371de5a2006-10-30 13:37:22 +0000600 if( isNT() ){
drheb4fa522006-06-04 23:02:20 +0000601 do{
drh371de5a2006-10-30 13:37:22 +0000602 rc = DeleteFileW(zConverted);
603 }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff
drh50c2b352006-09-26 00:34:17 +0000604 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
drhc0929982005-09-05 19:08:29 +0000605 }else{
drhcc78fea2006-01-06 16:17:05 +0000606#if OS_WINCE
607 return SQLITE_NOMEM;
608#else
drheb4fa522006-06-04 23:02:20 +0000609 do{
drh371de5a2006-10-30 13:37:22 +0000610 rc = DeleteFileA(zConverted);
611 }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
drh50c2b352006-09-26 00:34:17 +0000612 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000613#endif
drhc0929982005-09-05 19:08:29 +0000614 }
drh371de5a2006-10-30 13:37:22 +0000615 sqliteFree(zConverted);
drh4f0c5872007-03-26 22:05:01 +0000616 OSTRACE2("DELETE \"%s\"\n", zFilename);
drh50c2b352006-09-26 00:34:17 +0000617 return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000618}
619
620/*
621** Return TRUE if the named file exists.
622*/
drh66560ad2006-01-06 14:32:19 +0000623int sqlite3WinFileExists(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000624 int exists = 0;
drh371de5a2006-10-30 13:37:22 +0000625 void *zConverted = convertUtf8Filename(zFilename);
626 if( zConverted==0 ){
627 return SQLITE_NOMEM;
628 }
629 if( isNT() ){
630 exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff;
drhc0929982005-09-05 19:08:29 +0000631 }else{
drhcc78fea2006-01-06 16:17:05 +0000632#if OS_WINCE
633 return SQLITE_NOMEM;
634#else
drh371de5a2006-10-30 13:37:22 +0000635 exists = GetFileAttributesA((char*)zConverted) != 0xffffffff;
drhcc78fea2006-01-06 16:17:05 +0000636#endif
drhc0929982005-09-05 19:08:29 +0000637 }
drh371de5a2006-10-30 13:37:22 +0000638 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +0000639 return exists;
drhbbd42a62004-05-22 17:41:58 +0000640}
641
drh054889e2005-11-30 03:20:31 +0000642/* Forward declaration */
danielk1977f0113002006-01-24 12:09:17 +0000643static int allocateWinFile(winFile *pInit, OsFile **pId);
drh9cbe6352005-11-29 03:13:21 +0000644
drhbbd42a62004-05-22 17:41:58 +0000645/*
646** Attempt to open a file for both reading and writing. If that
647** fails, try opening it read-only. If the file does not exist,
648** try to create it.
649**
650** On success, a handle for the open file is written to *id
651** and *pReadonly is set to 0 if the file was opened for reading and
652** writing or 1 if the file was opened read-only. The function returns
653** SQLITE_OK.
654**
655** On failure, the function returns SQLITE_CANTOPEN and leaves
656** *id and *pReadonly unchanged.
657*/
drh66560ad2006-01-06 14:32:19 +0000658int sqlite3WinOpenReadWrite(
drhbbd42a62004-05-22 17:41:58 +0000659 const char *zFilename,
drh9cbe6352005-11-29 03:13:21 +0000660 OsFile **pId,
drhbbd42a62004-05-22 17:41:58 +0000661 int *pReadonly
662){
drh054889e2005-11-30 03:20:31 +0000663 winFile f;
drhda71ce12004-06-21 18:14:45 +0000664 HANDLE h;
drh371de5a2006-10-30 13:37:22 +0000665 void *zConverted = convertUtf8Filename(zFilename);
666 if( zConverted==0 ){
667 return SQLITE_NOMEM;
668 }
drh9cbe6352005-11-29 03:13:21 +0000669 assert( *pId==0 );
drh371de5a2006-10-30 13:37:22 +0000670
671 if( isNT() ){
672 h = CreateFileW((WCHAR*)zConverted,
drhc0929982005-09-05 19:08:29 +0000673 GENERIC_READ | GENERIC_WRITE,
674 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhbbd42a62004-05-22 17:41:58 +0000675 NULL,
676 OPEN_ALWAYS,
677 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
678 NULL
679 );
680 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000681 h = CreateFileW((WCHAR*)zConverted,
drhc0929982005-09-05 19:08:29 +0000682 GENERIC_READ,
drh94d57e32006-06-02 12:40:08 +0000683 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhc0929982005-09-05 19:08:29 +0000684 NULL,
685 OPEN_ALWAYS,
686 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
687 NULL
688 );
689 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000690 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +0000691 return SQLITE_CANTOPEN;
692 }
693 *pReadonly = 1;
694 }else{
695 *pReadonly = 0;
drhbbd42a62004-05-22 17:41:58 +0000696 }
drh72aead82006-01-23 15:54:25 +0000697#if OS_WINCE
698 if (!winceCreateLock(zFilename, &f)){
699 CloseHandle(h);
drh371de5a2006-10-30 13:37:22 +0000700 sqliteFree(zConverted);
drh72aead82006-01-23 15:54:25 +0000701 return SQLITE_CANTOPEN;
702 }
703#endif
drhbbd42a62004-05-22 17:41:58 +0000704 }else{
drhcc78fea2006-01-06 16:17:05 +0000705#if OS_WINCE
706 return SQLITE_NOMEM;
707#else
drh371de5a2006-10-30 13:37:22 +0000708 h = CreateFileA((char*)zConverted,
drhc0929982005-09-05 19:08:29 +0000709 GENERIC_READ | GENERIC_WRITE,
710 FILE_SHARE_READ | FILE_SHARE_WRITE,
711 NULL,
712 OPEN_ALWAYS,
713 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
714 NULL
715 );
716 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000717 h = CreateFileA((char*)zConverted,
drhc0929982005-09-05 19:08:29 +0000718 GENERIC_READ,
drh94d57e32006-06-02 12:40:08 +0000719 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhc0929982005-09-05 19:08:29 +0000720 NULL,
721 OPEN_ALWAYS,
722 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
723 NULL
724 );
725 if( h==INVALID_HANDLE_VALUE ){
drh371de5a2006-10-30 13:37:22 +0000726 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +0000727 return SQLITE_CANTOPEN;
728 }
729 *pReadonly = 1;
730 }else{
731 *pReadonly = 0;
732 }
drhcc78fea2006-01-06 16:17:05 +0000733#endif /* OS_WINCE */
drhbbd42a62004-05-22 17:41:58 +0000734 }
drh371de5a2006-10-30 13:37:22 +0000735
736 sqliteFree(zConverted);
737
drh9cbe6352005-11-29 03:13:21 +0000738 f.h = h;
drh4bddfd22006-01-07 18:14:48 +0000739#if OS_WINCE
740 f.zDeleteOnClose = 0;
741#endif
drh4f0c5872007-03-26 22:05:01 +0000742 OSTRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000743 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000744}
745
746
747/*
748** Attempt to open a new file for exclusive access by this process.
749** The file will be opened for both reading and writing. To avoid
750** a potential security problem, we do not allow the file to have
751** previously existed. Nor do we allow the file to be a symbolic
752** link.
753**
754** If delFlag is true, then make arrangements to automatically delete
755** the file when it is closed.
756**
757** On success, write the file handle into *id and return SQLITE_OK.
758**
759** On failure, return SQLITE_CANTOPEN.
drh59e63a62006-06-04 23:31:48 +0000760**
761** Sometimes if we have just deleted a prior journal file, windows
762** will fail to open a new one because there is a "pending delete".
763** To work around this bug, we pause for 100 milliseconds and attempt
764** a second open after the first one fails. The whole operation only
765** fails if both open attempts are unsuccessful.
drhbbd42a62004-05-22 17:41:58 +0000766*/
drh66560ad2006-01-06 14:32:19 +0000767int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
drh054889e2005-11-30 03:20:31 +0000768 winFile f;
drhbbd42a62004-05-22 17:41:58 +0000769 HANDLE h;
drhec4d88f2006-12-21 00:46:42 +0000770 DWORD fileflags;
drh371de5a2006-10-30 13:37:22 +0000771 void *zConverted = convertUtf8Filename(zFilename);
772 if( zConverted==0 ){
773 return SQLITE_NOMEM;
774 }
drh9cbe6352005-11-29 03:13:21 +0000775 assert( *pId == 0 );
drhcc78fea2006-01-06 16:17:05 +0000776 fileflags = FILE_FLAG_RANDOM_ACCESS;
777#if !OS_WINCE
drhbbd42a62004-05-22 17:41:58 +0000778 if( delFlag ){
drhcc78fea2006-01-06 16:17:05 +0000779 fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
drhbbd42a62004-05-22 17:41:58 +0000780 }
drhcc78fea2006-01-06 16:17:05 +0000781#endif
drh371de5a2006-10-30 13:37:22 +0000782 if( isNT() ){
drheb4fa522006-06-04 23:02:20 +0000783 int cnt = 0;
784 do{
drh371de5a2006-10-30 13:37:22 +0000785 h = CreateFileW((WCHAR*)zConverted,
drheb4fa522006-06-04 23:02:20 +0000786 GENERIC_READ | GENERIC_WRITE,
787 0,
788 NULL,
789 CREATE_ALWAYS,
790 fileflags,
791 NULL
792 );
793 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
drhc0929982005-09-05 19:08:29 +0000794 }else{
drhcc78fea2006-01-06 16:17:05 +0000795#if OS_WINCE
796 return SQLITE_NOMEM;
797#else
drheb4fa522006-06-04 23:02:20 +0000798 int cnt = 0;
799 do{
drh371de5a2006-10-30 13:37:22 +0000800 h = CreateFileA((char*)zConverted,
drheb4fa522006-06-04 23:02:20 +0000801 GENERIC_READ | GENERIC_WRITE,
802 0,
803 NULL,
804 CREATE_ALWAYS,
805 fileflags,
806 NULL
807 );
808 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000809#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000810 }
drhc96d4982006-12-21 01:37:39 +0000811#if OS_WINCE
812 if( delFlag && h!=INVALID_HANDLE_VALUE ){
813 f.zDeleteOnClose = zConverted;
814 zConverted = 0;
815 }
816 f.hMutex = NULL;
817#endif
drh371de5a2006-10-30 13:37:22 +0000818 sqliteFree(zConverted);
drhbbd42a62004-05-22 17:41:58 +0000819 if( h==INVALID_HANDLE_VALUE ){
820 return SQLITE_CANTOPEN;
821 }
drh9cbe6352005-11-29 03:13:21 +0000822 f.h = h;
drh4f0c5872007-03-26 22:05:01 +0000823 OSTRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000824 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000825}
826
827/*
828** Attempt to open a new file for read-only access.
829**
830** On success, write the file handle into *id and return SQLITE_OK.
831**
832** On failure, return SQLITE_CANTOPEN.
833*/
drh66560ad2006-01-06 14:32:19 +0000834int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000835 winFile f;
drhda71ce12004-06-21 18:14:45 +0000836 HANDLE h;
drh371de5a2006-10-30 13:37:22 +0000837 void *zConverted = convertUtf8Filename(zFilename);
838 if( zConverted==0 ){
839 return SQLITE_NOMEM;
840 }
drh9cbe6352005-11-29 03:13:21 +0000841 assert( *pId==0 );
drh371de5a2006-10-30 13:37:22 +0000842 if( isNT() ){
843 h = CreateFileW((WCHAR*)zConverted,
drhc0929982005-09-05 19:08:29 +0000844 GENERIC_READ,
845 0,
846 NULL,
847 OPEN_EXISTING,
848 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
849 NULL
850 );
drhc0929982005-09-05 19:08:29 +0000851 }else{
drhcc78fea2006-01-06 16:17:05 +0000852#if OS_WINCE
853 return SQLITE_NOMEM;
854#else
drh371de5a2006-10-30 13:37:22 +0000855 h = CreateFileA((char*)zConverted,
drhc0929982005-09-05 19:08:29 +0000856 GENERIC_READ,
857 0,
858 NULL,
859 OPEN_EXISTING,
860 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
861 NULL
862 );
drhcc78fea2006-01-06 16:17:05 +0000863#endif
drhc0929982005-09-05 19:08:29 +0000864 }
drh371de5a2006-10-30 13:37:22 +0000865 sqliteFree(zConverted);
drhbbd42a62004-05-22 17:41:58 +0000866 if( h==INVALID_HANDLE_VALUE ){
867 return SQLITE_CANTOPEN;
868 }
drh9cbe6352005-11-29 03:13:21 +0000869 f.h = h;
drh4bddfd22006-01-07 18:14:48 +0000870#if OS_WINCE
871 f.zDeleteOnClose = 0;
drh36a50052006-01-23 22:15:07 +0000872 f.hMutex = NULL;
drh4bddfd22006-01-07 18:14:48 +0000873#endif
drh4f0c5872007-03-26 22:05:01 +0000874 OSTRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000875 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000876}
877
878/*
879** Attempt to open a file descriptor for the directory that contains a
880** file. This file descriptor can be used to fsync() the directory
881** in order to make sure the creation of a new file is actually written
882** to disk.
883**
884** This routine is only meaningful for Unix. It is a no-op under
885** windows since windows does not support hard links.
886**
887** On success, a handle for a previously open file is at *id is
888** updated with the new directory file descriptor and SQLITE_OK is
889** returned.
890**
891** On failure, the function returns SQLITE_CANTOPEN and leaves
892** *id unchanged.
893*/
drh9c06c952005-11-26 00:25:00 +0000894static int winOpenDirectory(
drh054889e2005-11-30 03:20:31 +0000895 OsFile *id,
896 const char *zDirname
drhbbd42a62004-05-22 17:41:58 +0000897){
898 return SQLITE_OK;
899}
900
901/*
drh3d2efea2004-08-28 01:12:56 +0000902** If the following global variable points to a string which is the
903** name of a directory, then that directory will be used to store
904** temporary files.
905*/
tpoindex9a09a3c2004-12-20 19:01:32 +0000906char *sqlite3_temp_directory = 0;
drh3d2efea2004-08-28 01:12:56 +0000907
908/*
drhbbd42a62004-05-22 17:41:58 +0000909** Create a temporary file name in zBuf. zBuf must be big enough to
910** hold at least SQLITE_TEMPNAME_SIZE characters.
911*/
drh66560ad2006-01-06 14:32:19 +0000912int sqlite3WinTempFileName(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +0000913 static char zChars[] =
914 "abcdefghijklmnopqrstuvwxyz"
915 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
916 "0123456789";
917 int i, j;
918 char zTempPath[SQLITE_TEMPNAME_SIZE];
drheffd02b2004-08-29 23:42:13 +0000919 if( sqlite3_temp_directory ){
920 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
drh3d2efea2004-08-28 01:12:56 +0000921 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
drhc0929982005-09-05 19:08:29 +0000922 }else if( isNT() ){
923 char *zMulti;
924 WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
925 GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
926 zMulti = unicodeToUtf8(zWidePath);
927 if( zMulti ){
drhd81bd4e2005-09-05 20:06:49 +0000928 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
drhc0929982005-09-05 19:08:29 +0000929 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
930 sqliteFree(zMulti);
drh371de5a2006-10-30 13:37:22 +0000931 }else{
932 return SQLITE_NOMEM;
drhc0929982005-09-05 19:08:29 +0000933 }
drh3d2efea2004-08-28 01:12:56 +0000934 }else{
drh371de5a2006-10-30 13:37:22 +0000935 char *zUtf8;
936 char zMbcsPath[SQLITE_TEMPNAME_SIZE];
937 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath);
938 zUtf8 = mbcsToUtf8(zMbcsPath);
939 if( zUtf8 ){
940 strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30);
941 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
942 sqliteFree(zUtf8);
943 }else{
944 return SQLITE_NOMEM;
945 }
drh3d2efea2004-08-28 01:12:56 +0000946 }
drhbbd42a62004-05-22 17:41:58 +0000947 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
948 zTempPath[i] = 0;
949 for(;;){
950 sprintf(zBuf, "%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;
drh66560ad2006-01-06 14:32:19 +0000957 if( !sqlite3OsFileExists(zBuf) ) break;
drhbbd42a62004-05-22 17:41:58 +0000958 }
drh4f0c5872007-03-26 22:05:01 +0000959 OSTRACE2("TEMP FILENAME: %s\n", zBuf);
drhbbd42a62004-05-22 17:41:58 +0000960 return SQLITE_OK;
961}
962
963/*
964** Close a file.
drh59e63a62006-06-04 23:31:48 +0000965**
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.
drhbbd42a62004-05-22 17:41:58 +0000972*/
drh59e63a62006-06-04 23:31:48 +0000973#define MX_CLOSE_ATTEMPT 3
drh9cbe6352005-11-29 03:13:21 +0000974static int winClose(OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000975 winFile *pFile;
drheb4fa522006-06-04 23:02:20 +0000976 int rc = 1;
drh054889e2005-11-30 03:20:31 +0000977 if( pId && (pFile = (winFile*)*pId)!=0 ){
drheb4fa522006-06-04 23:02:20 +0000978 int rc, cnt = 0;
drh4f0c5872007-03-26 22:05:01 +0000979 OSTRACE2("CLOSE %d\n", pFile->h);
drheb4fa522006-06-04 23:02:20 +0000980 do{
981 rc = CloseHandle(pFile->h);
drh59e63a62006-06-04 23:31:48 +0000982 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000983#if OS_WINCE
drh72aead82006-01-23 15:54:25 +0000984 winceDestroyLock(pFile);
drhcc78fea2006-01-06 16:17:05 +0000985 if( pFile->zDeleteOnClose ){
drh9e9fe6f2006-01-06 21:09:01 +0000986 DeleteFileW(pFile->zDeleteOnClose);
drhcc78fea2006-01-06 16:17:05 +0000987 sqliteFree(pFile->zDeleteOnClose);
988 }
989#endif
drhda71ce12004-06-21 18:14:45 +0000990 OpenCounter(-1);
drh054889e2005-11-30 03:20:31 +0000991 sqliteFree(pFile);
drh9cbe6352005-11-29 03:13:21 +0000992 *pId = 0;
drhda71ce12004-06-21 18:14:45 +0000993 }
drheb4fa522006-06-04 23:02:20 +0000994 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000995}
996
997/*
998** Read data from a file into a buffer. Return SQLITE_OK if all
999** bytes were read successfully and SQLITE_IOERR if anything goes
1000** wrong.
1001*/
drh9c06c952005-11-26 00:25:00 +00001002static int winRead(OsFile *id, void *pBuf, int amt){
drhbbd42a62004-05-22 17:41:58 +00001003 DWORD got;
drh9cbe6352005-11-29 03:13:21 +00001004 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +00001005 SimulateIOError(return SQLITE_IOERR_READ);
drh4f0c5872007-03-26 22:05:01 +00001006 OSTRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
drh054889e2005-11-30 03:20:31 +00001007 if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
drhaedd8922007-01-05 14:38:54 +00001008 return SQLITE_IOERR_READ;
drhbbd42a62004-05-22 17:41:58 +00001009 }
1010 if( got==(DWORD)amt ){
1011 return SQLITE_OK;
1012 }else{
drhbafda092007-01-03 23:36:22 +00001013 memset(&((char*)pBuf)[got], 0, amt-got);
drh551b7732006-11-06 21:20:25 +00001014 return SQLITE_IOERR_SHORT_READ;
drhbbd42a62004-05-22 17:41:58 +00001015 }
1016}
1017
1018/*
1019** Write data from a buffer into a file. Return SQLITE_OK on success
1020** or some other error code on failure.
1021*/
drh9c06c952005-11-26 00:25:00 +00001022static int winWrite(OsFile *id, const void *pBuf, int amt){
drh4c7f9412005-02-03 00:29:47 +00001023 int rc = 0;
drhbbd42a62004-05-22 17:41:58 +00001024 DWORD wrote;
drh9cbe6352005-11-29 03:13:21 +00001025 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +00001026 SimulateIOError(return SQLITE_IOERR_READ);
drh59685932006-09-14 13:47:11 +00001027 SimulateDiskfullError(return SQLITE_FULL);
drh4f0c5872007-03-26 22:05:01 +00001028 OSTRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
drh4c7f9412005-02-03 00:29:47 +00001029 assert( amt>0 );
drh054889e2005-11-30 03:20:31 +00001030 while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
1031 && wrote>0 ){
drhbbd42a62004-05-22 17:41:58 +00001032 amt -= wrote;
1033 pBuf = &((char*)pBuf)[wrote];
1034 }
1035 if( !rc || amt>(int)wrote ){
1036 return SQLITE_FULL;
1037 }
1038 return SQLITE_OK;
1039}
1040
1041/*
drhbbdc2b92005-09-19 12:53:18 +00001042** Some microsoft compilers lack this definition.
1043*/
1044#ifndef INVALID_SET_FILE_POINTER
1045# define INVALID_SET_FILE_POINTER ((DWORD)-1)
1046#endif
1047
1048/*
drhbbd42a62004-05-22 17:41:58 +00001049** Move the read/write pointer in a file.
1050*/
drh9c06c952005-11-26 00:25:00 +00001051static int winSeek(OsFile *id, i64 offset){
drhbbd42a62004-05-22 17:41:58 +00001052 LONG upperBits = offset>>32;
1053 LONG lowerBits = offset & 0xffffffff;
1054 DWORD rc;
drh9cbe6352005-11-29 03:13:21 +00001055 assert( id!=0 );
drhb4746b92005-09-09 01:32:06 +00001056#ifdef SQLITE_TEST
drh59685932006-09-14 13:47:11 +00001057 if( offset ) SimulateDiskfullError(return SQLITE_FULL);
drhb4746b92005-09-09 01:32:06 +00001058#endif
drhbbd42a62004-05-22 17:41:58 +00001059 SEEK(offset/1024 + 1);
drh054889e2005-11-30 03:20:31 +00001060 rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
drh4f0c5872007-03-26 22:05:01 +00001061 OSTRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
drhe08b8142005-09-09 10:17:33 +00001062 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
1063 return SQLITE_FULL;
1064 }
drhbbd42a62004-05-22 17:41:58 +00001065 return SQLITE_OK;
1066}
1067
1068/*
1069** Make sure all writes to a particular file are committed to disk.
1070*/
drh9c06c952005-11-26 00:25:00 +00001071static int winSync(OsFile *id, int dataOnly){
drh9cbe6352005-11-29 03:13:21 +00001072 assert( id!=0 );
drh4f0c5872007-03-26 22:05:01 +00001073 OSTRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
drh054889e2005-11-30 03:20:31 +00001074 if( FlushFileBuffers(((winFile*)id)->h) ){
drhbbd42a62004-05-22 17:41:58 +00001075 return SQLITE_OK;
1076 }else{
1077 return SQLITE_IOERR;
1078 }
1079}
1080
1081/*
danielk1977962398d2004-06-14 09:35:16 +00001082** Sync the directory zDirname. This is a no-op on operating systems other
1083** than UNIX.
1084*/
drh66560ad2006-01-06 14:32:19 +00001085int sqlite3WinSyncDirectory(const char *zDirname){
drh9cce7102007-01-09 17:18:19 +00001086 SimulateIOError(return SQLITE_IOERR_READ);
danielk1977962398d2004-06-14 09:35:16 +00001087 return SQLITE_OK;
1088}
1089
1090/*
drhbbd42a62004-05-22 17:41:58 +00001091** Truncate an open file to a specified size
1092*/
drh9c06c952005-11-26 00:25:00 +00001093static int winTruncate(OsFile *id, i64 nByte){
drhbbd42a62004-05-22 17:41:58 +00001094 LONG upperBits = nByte>>32;
drh9cbe6352005-11-29 03:13:21 +00001095 assert( id!=0 );
drh4f0c5872007-03-26 22:05:01 +00001096 OSTRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
drh9cce7102007-01-09 17:18:19 +00001097 SimulateIOError(return SQLITE_IOERR_TRUNCATE);
drh054889e2005-11-30 03:20:31 +00001098 SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
1099 SetEndOfFile(((winFile*)id)->h);
drhbbd42a62004-05-22 17:41:58 +00001100 return SQLITE_OK;
1101}
1102
1103/*
1104** Determine the current size of a file in bytes
1105*/
drh9c06c952005-11-26 00:25:00 +00001106static int winFileSize(OsFile *id, i64 *pSize){
drhbbd42a62004-05-22 17:41:58 +00001107 DWORD upperBits, lowerBits;
drh9cbe6352005-11-29 03:13:21 +00001108 assert( id!=0 );
drh9cce7102007-01-09 17:18:19 +00001109 SimulateIOError(return SQLITE_IOERR_FSTAT);
drh054889e2005-11-30 03:20:31 +00001110 lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
drheb206252004-10-01 02:00:31 +00001111 *pSize = (((i64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +00001112 return SQLITE_OK;
1113}
1114
1115/*
drh602bbd32006-01-06 20:22:29 +00001116** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
1117*/
1118#ifndef LOCKFILE_FAIL_IMMEDIATELY
1119# define LOCKFILE_FAIL_IMMEDIATELY 1
1120#endif
1121
1122/*
drh9c105bb2004-10-02 20:38:28 +00001123** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +00001124** Different API routines are called depending on whether or not this
1125** is Win95 or WinNT.
1126*/
drh054889e2005-11-30 03:20:31 +00001127static int getReadLock(winFile *id){
drh51c6d962004-06-06 00:42:25 +00001128 int res;
1129 if( isNT() ){
1130 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +00001131 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +00001132 ovlp.OffsetHigh = 0;
1133 ovlp.hEvent = 0;
drh9c105bb2004-10-02 20:38:28 +00001134 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
drhbbd42a62004-05-22 17:41:58 +00001135 }else{
drh9c105bb2004-10-02 20:38:28 +00001136 int lk;
1137 sqlite3Randomness(sizeof(lk), &lk);
1138 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
1139 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001140 }
1141 return res;
1142}
1143
1144/*
1145** Undo a readlock
1146*/
drh054889e2005-11-30 03:20:31 +00001147static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +00001148 int res;
1149 if( isNT() ){
drh054889e2005-11-30 03:20:31 +00001150 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drh51c6d962004-06-06 00:42:25 +00001151 }else{
drh054889e2005-11-30 03:20:31 +00001152 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001153 }
1154 return res;
1155}
1156
drh268283b2005-01-08 15:44:25 +00001157#ifndef SQLITE_OMIT_PAGER_PRAGMAS
drh51c6d962004-06-06 00:42:25 +00001158/*
tpoindex9a09a3c2004-12-20 19:01:32 +00001159** Check that a given pathname is a directory and is writable
1160**
1161*/
drh66560ad2006-01-06 14:32:19 +00001162int sqlite3WinIsDirWritable(char *zDirname){
tpoindex9a09a3c2004-12-20 19:01:32 +00001163 int fileAttr;
drh371de5a2006-10-30 13:37:22 +00001164 void *zConverted;
drhc0929982005-09-05 19:08:29 +00001165 if( zDirname==0 ) return 0;
1166 if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
drh371de5a2006-10-30 13:37:22 +00001167
1168 zConverted = convertUtf8Filename(zDirname);
1169 if( zConverted==0 ){
1170 return SQLITE_NOMEM;
1171 }
1172 if( isNT() ){
1173 fileAttr = GetFileAttributesW((WCHAR*)zConverted);
drhc0929982005-09-05 19:08:29 +00001174 }else{
drhcc78fea2006-01-06 16:17:05 +00001175#if OS_WINCE
1176 return 0;
1177#else
drh371de5a2006-10-30 13:37:22 +00001178 fileAttr = GetFileAttributesA((char*)zConverted);
drhcc78fea2006-01-06 16:17:05 +00001179#endif
drhc0929982005-09-05 19:08:29 +00001180 }
drh371de5a2006-10-30 13:37:22 +00001181 sqliteFree(zConverted);
tpoindex9a09a3c2004-12-20 19:01:32 +00001182 if( fileAttr == 0xffffffff ) return 0;
drh268283b2005-01-08 15:44:25 +00001183 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
1184 return 0;
1185 }
tpoindex9a09a3c2004-12-20 19:01:32 +00001186 return 1;
1187}
drh268283b2005-01-08 15:44:25 +00001188#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
tpoindex9a09a3c2004-12-20 19:01:32 +00001189
1190/*
drhb3e04342004-06-08 00:47:47 +00001191** Lock the file with the lock specified by parameter locktype - one
1192** of the following:
1193**
1194** (1) SHARED_LOCK
1195** (2) RESERVED_LOCK
1196** (3) PENDING_LOCK
1197** (4) EXCLUSIVE_LOCK
1198**
1199** Sometimes when requesting one lock state, additional lock states
1200** are inserted in between. The locking might fail on one of the later
1201** transitions leaving the lock state different from what it started but
1202** still short of its goal. The following chart shows the allowed
1203** transitions and the inserted intermediate states:
1204**
1205** UNLOCKED -> SHARED
1206** SHARED -> RESERVED
1207** SHARED -> (PENDING) -> EXCLUSIVE
1208** RESERVED -> (PENDING) -> EXCLUSIVE
1209** PENDING -> EXCLUSIVE
1210**
drh9c06c952005-11-26 00:25:00 +00001211** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +00001212** erases all locks at once and returns us immediately to locking level 0.
1213** It is not possible to lower the locking level one step at a time. You
1214** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +00001215*/
drh9c06c952005-11-26 00:25:00 +00001216static int winLock(OsFile *id, int locktype){
drh51c6d962004-06-06 00:42:25 +00001217 int rc = SQLITE_OK; /* Return code from subroutines */
1218 int res = 1; /* Result of a windows lock call */
drhe54ca3f2004-06-07 01:52:14 +00001219 int newLocktype; /* Set id->locktype to this value before exiting */
1220 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +00001221 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +00001222
drh054889e2005-11-30 03:20:31 +00001223 assert( pFile!=0 );
drh4f0c5872007-03-26 22:05:01 +00001224 OSTRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +00001225 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +00001226
1227 /* If there is already a lock of this type or more restrictive on the
1228 ** OsFile, do nothing. Don't use the end_lock: exit path, as
1229 ** sqlite3OsEnterMutex() hasn't been called yet.
1230 */
drh054889e2005-11-30 03:20:31 +00001231 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +00001232 return SQLITE_OK;
1233 }
1234
drhb3e04342004-06-08 00:47:47 +00001235 /* Make sure the locking sequence is correct
1236 */
drh054889e2005-11-30 03:20:31 +00001237 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +00001238 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +00001239 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +00001240
drh51c6d962004-06-06 00:42:25 +00001241 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
1242 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
1243 ** the PENDING_LOCK byte is temporary.
1244 */
drh054889e2005-11-30 03:20:31 +00001245 newLocktype = pFile->locktype;
1246 if( pFile->locktype==NO_LOCK
1247 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +00001248 ){
drhb3e04342004-06-08 00:47:47 +00001249 int cnt = 3;
drh054889e2005-11-30 03:20:31 +00001250 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +00001251 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +00001252 ** held by another reader process who will release it momentarily.
1253 */
drh4f0c5872007-03-26 22:05:01 +00001254 OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +00001255 Sleep(1);
1256 }
drhe54ca3f2004-06-07 01:52:14 +00001257 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +00001258 }
1259
1260 /* Acquire a shared lock
1261 */
drhb3e04342004-06-08 00:47:47 +00001262 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001263 assert( pFile->locktype==NO_LOCK );
1264 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +00001265 if( res ){
1266 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +00001267 }
1268 }
1269
1270 /* Acquire a RESERVED lock
1271 */
drhb3e04342004-06-08 00:47:47 +00001272 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001273 assert( pFile->locktype==SHARED_LOCK );
1274 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +00001275 if( res ){
1276 newLocktype = RESERVED_LOCK;
1277 }
1278 }
1279
1280 /* Acquire a PENDING lock
1281 */
drhb3e04342004-06-08 00:47:47 +00001282 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +00001283 newLocktype = PENDING_LOCK;
1284 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +00001285 }
1286
1287 /* Acquire an EXCLUSIVE lock
1288 */
drhe54ca3f2004-06-07 01:52:14 +00001289 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001290 assert( pFile->locktype>=SHARED_LOCK );
1291 res = unlockReadLock(pFile);
drh4f0c5872007-03-26 22:05:01 +00001292 OSTRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +00001293 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +00001294 if( res ){
1295 newLocktype = EXCLUSIVE_LOCK;
1296 }else{
drh4f0c5872007-03-26 22:05:01 +00001297 OSTRACE2("error-code = %d\n", GetLastError());
drhe54ca3f2004-06-07 01:52:14 +00001298 }
1299 }
1300
1301 /* If we are holding a PENDING lock that ought to be released, then
1302 ** release it now.
1303 */
drhb3e04342004-06-08 00:47:47 +00001304 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001305 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001306 }
1307
1308 /* Update the state of the lock has held in the file descriptor then
1309 ** return the appropriate result code.
1310 */
1311 if( res ){
drh51c6d962004-06-06 00:42:25 +00001312 rc = SQLITE_OK;
1313 }else{
drh4f0c5872007-03-26 22:05:01 +00001314 OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +00001315 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +00001316 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +00001317 }
drh054889e2005-11-30 03:20:31 +00001318 pFile->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +00001319 return rc;
1320}
1321
1322/*
drh51c6d962004-06-06 00:42:25 +00001323** This routine checks if there is a RESERVED lock held on the specified
1324** file by this or any other process. If such a lock is held, return
1325** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +00001326*/
drh9c06c952005-11-26 00:25:00 +00001327static int winCheckReservedLock(OsFile *id){
drhbbd42a62004-05-22 17:41:58 +00001328 int rc;
drh054889e2005-11-30 03:20:31 +00001329 winFile *pFile = (winFile*)id;
1330 assert( pFile!=0 );
1331 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +00001332 rc = 1;
drh4f0c5872007-03-26 22:05:01 +00001333 OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001334 }else{
drh054889e2005-11-30 03:20:31 +00001335 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001336 if( rc ){
drh054889e2005-11-30 03:20:31 +00001337 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +00001338 }
drh2ac3ee92004-06-07 16:27:46 +00001339 rc = !rc;
drh4f0c5872007-03-26 22:05:01 +00001340 OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001341 }
drh2ac3ee92004-06-07 16:27:46 +00001342 return rc;
drhbbd42a62004-05-22 17:41:58 +00001343}
1344
1345/*
drha6abd042004-06-09 17:37:22 +00001346** Lower the locking level on file descriptor id to locktype. locktype
1347** must be either NO_LOCK or SHARED_LOCK.
1348**
1349** If the locking level of the file descriptor is already at or below
1350** the requested locking level, this routine is a no-op.
1351**
drh9c105bb2004-10-02 20:38:28 +00001352** It is not possible for this routine to fail if the second argument
1353** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1354** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +00001355*/
drh9c06c952005-11-26 00:25:00 +00001356static int winUnlock(OsFile *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001357 int type;
1358 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001359 winFile *pFile = (winFile*)id;
1360 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001361 assert( locktype<=SHARED_LOCK );
drh4f0c5872007-03-26 22:05:01 +00001362 OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
drh054889e2005-11-30 03:20:31 +00001363 pFile->locktype, pFile->sharedLockByte);
1364 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001365 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001366 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1367 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001368 /* This should never happen. We should always be able to
1369 ** reacquire the read lock */
drh9cce7102007-01-09 17:18:19 +00001370 rc = SQLITE_IOERR_UNLOCK;
drh9c105bb2004-10-02 20:38:28 +00001371 }
drhbbd42a62004-05-22 17:41:58 +00001372 }
drhe54ca3f2004-06-07 01:52:14 +00001373 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001374 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001375 }
drh9c105bb2004-10-02 20:38:28 +00001376 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001377 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001378 }
drhb3e04342004-06-08 00:47:47 +00001379 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001380 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001381 }
drh054889e2005-11-30 03:20:31 +00001382 pFile->locktype = locktype;
drh9c105bb2004-10-02 20:38:28 +00001383 return rc;
drhbbd42a62004-05-22 17:41:58 +00001384}
1385
1386/*
drh0ccebe72005-06-07 22:22:50 +00001387** Turn a relative pathname into a full pathname. Return a pointer
1388** to the full pathname stored in space obtained from sqliteMalloc().
1389** The calling function is responsible for freeing this space once it
1390** is no longer needed.
1391*/
drh66560ad2006-01-06 14:32:19 +00001392char *sqlite3WinFullPathname(const char *zRelative){
drh0ccebe72005-06-07 22:22:50 +00001393 char *zFull;
drhcc78fea2006-01-06 16:17:05 +00001394#if defined(__CYGWIN__)
drh0ccebe72005-06-07 22:22:50 +00001395 int nByte;
drh0ccebe72005-06-07 22:22:50 +00001396 nByte = strlen(zRelative) + MAX_PATH + 1001;
1397 zFull = sqliteMalloc( nByte );
1398 if( zFull==0 ) return 0;
1399 if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
drhcc78fea2006-01-06 16:17:05 +00001400#elif OS_WINCE
1401 /* WinCE has no concept of a relative pathname, or so I am told. */
danielk1977e7259292006-01-13 06:33:23 +00001402 zFull = sqliteStrDup(zRelative);
drh0ccebe72005-06-07 22:22:50 +00001403#else
drhcc78fea2006-01-06 16:17:05 +00001404 int nByte;
drh371de5a2006-10-30 13:37:22 +00001405 void *zConverted;
1406 zConverted = convertUtf8Filename(zRelative);
1407 if( isNT() ){
drhfb02d262007-01-09 15:32:17 +00001408 WCHAR *zTemp;
1409 nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
drhc0929982005-09-05 19:08:29 +00001410 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
drh371de5a2006-10-30 13:37:22 +00001411 if( zTemp==0 ){
1412 sqliteFree(zConverted);
1413 return 0;
1414 }
drhfb02d262007-01-09 15:32:17 +00001415 GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
drh371de5a2006-10-30 13:37:22 +00001416 sqliteFree(zConverted);
drhc0929982005-09-05 19:08:29 +00001417 zFull = unicodeToUtf8(zTemp);
1418 sqliteFree(zTemp);
1419 }else{
drhfb02d262007-01-09 15:32:17 +00001420 char *zTemp;
1421 nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
drh371de5a2006-10-30 13:37:22 +00001422 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
1423 if( zTemp==0 ){
1424 sqliteFree(zConverted);
1425 return 0;
1426 }
drhfb02d262007-01-09 15:32:17 +00001427 GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
drh371de5a2006-10-30 13:37:22 +00001428 sqliteFree(zConverted);
1429 zFull = mbcsToUtf8(zTemp);
1430 sqliteFree(zTemp);
drhc0929982005-09-05 19:08:29 +00001431 }
drh0ccebe72005-06-07 22:22:50 +00001432#endif
1433 return zFull;
1434}
1435
drh9c06c952005-11-26 00:25:00 +00001436/*
drh9cbe6352005-11-29 03:13:21 +00001437** The fullSync option is meaningless on windows. This is a no-op.
drh18839212005-11-26 03:43:23 +00001438*/
drh9cbe6352005-11-29 03:13:21 +00001439static void winSetFullSync(OsFile *id, int v){
1440 return;
1441}
1442
1443/*
1444** Return the underlying file handle for an OsFile
1445*/
1446static int winFileHandle(OsFile *id){
drh054889e2005-11-30 03:20:31 +00001447 return (int)((winFile*)id)->h;
drh9cbe6352005-11-29 03:13:21 +00001448}
1449
1450/*
1451** Return an integer that indices the type of lock currently held
1452** by this handle. (Used for testing and analysis only.)
1453*/
1454static int winLockState(OsFile *id){
drh054889e2005-11-30 03:20:31 +00001455 return ((winFile*)id)->locktype;
drh18839212005-11-26 03:43:23 +00001456}
1457
drh18839212005-11-26 03:43:23 +00001458/*
danielk1977a3d4c882007-03-23 10:08:38 +00001459** Return the sector size in bytes of the underlying block device for
1460** the specified file. This is almost always 512 bytes, but may be
1461** larger for some devices.
1462**
1463** SQLite code assumes this function cannot fail. It also assumes that
1464** if two files are created in the same file-system directory (i.e.
1465** a database and it's journal file) that the sector size will be the
1466** same for both.
1467*/
1468static int winSectorSize(OsFile *id){
1469 return PAGER_SECTOR_SIZE;
1470}
1471
1472/*
drh054889e2005-11-30 03:20:31 +00001473** This vector defines all the methods that can operate on an OsFile
1474** for win32.
drh9c06c952005-11-26 00:25:00 +00001475*/
drh054889e2005-11-30 03:20:31 +00001476static const IoMethod sqlite3WinIoMethod = {
drh9c06c952005-11-26 00:25:00 +00001477 winClose,
drh054889e2005-11-30 03:20:31 +00001478 winOpenDirectory,
drh9c06c952005-11-26 00:25:00 +00001479 winRead,
1480 winWrite,
1481 winSeek,
drh9c06c952005-11-26 00:25:00 +00001482 winTruncate,
drh054889e2005-11-30 03:20:31 +00001483 winSync,
drh9cbe6352005-11-29 03:13:21 +00001484 winSetFullSync,
1485 winFileHandle,
drh054889e2005-11-30 03:20:31 +00001486 winFileSize,
1487 winLock,
1488 winUnlock,
drh9cbe6352005-11-29 03:13:21 +00001489 winLockState,
drh054889e2005-11-30 03:20:31 +00001490 winCheckReservedLock,
danielk1977a3d4c882007-03-23 10:08:38 +00001491 winSectorSize,
drh9c06c952005-11-26 00:25:00 +00001492};
1493
drh054889e2005-11-30 03:20:31 +00001494/*
1495** Allocate memory for an OsFile. Initialize the new OsFile
1496** to the value given in pInit and return a pointer to the new
1497** OsFile. If we run out of memory, close the file and return NULL.
1498*/
danielk1977f0113002006-01-24 12:09:17 +00001499static int allocateWinFile(winFile *pInit, OsFile **pId){
drh054889e2005-11-30 03:20:31 +00001500 winFile *pNew;
1501 pNew = sqliteMalloc( sizeof(*pNew) );
1502 if( pNew==0 ){
1503 CloseHandle(pInit->h);
drhcc78fea2006-01-06 16:17:05 +00001504#if OS_WINCE
1505 sqliteFree(pInit->zDeleteOnClose);
1506#endif
drh054889e2005-11-30 03:20:31 +00001507 *pId = 0;
1508 return SQLITE_NOMEM;
1509 }else{
1510 *pNew = *pInit;
1511 pNew->pMethod = &sqlite3WinIoMethod;
drhbe1f84c2006-01-23 16:25:22 +00001512 pNew->locktype = NO_LOCK;
1513 pNew->sharedLockByte = 0;
drh66560ad2006-01-06 14:32:19 +00001514 *pId = (OsFile*)pNew;
drhbe1f84c2006-01-23 16:25:22 +00001515 OpenCounter(+1);
drh054889e2005-11-30 03:20:31 +00001516 return SQLITE_OK;
1517 }
1518}
1519
1520
drh0ccebe72005-06-07 22:22:50 +00001521#endif /* SQLITE_OMIT_DISKIO */
1522/***************************************************************************
1523** Everything above deals with file I/O. Everything that follows deals
1524** with other miscellanous aspects of the operating system interface
1525****************************************************************************/
1526
drh761df872006-12-21 01:29:22 +00001527#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
1528/*
1529** Interfaces for opening a shared library, finding entry points
1530** within the shared library, and closing the shared library.
1531*/
1532void *sqlite3WinDlopen(const char *zFilename){
1533 HANDLE h;
1534 void *zConverted = convertUtf8Filename(zFilename);
1535 if( zConverted==0 ){
1536 return 0;
1537 }
1538 if( isNT() ){
drh584c0942006-12-21 03:20:40 +00001539 h = LoadLibraryW((WCHAR*)zConverted);
drh761df872006-12-21 01:29:22 +00001540 }else{
1541#if OS_WINCE
drh2a4d54b2006-12-21 02:21:56 +00001542 return 0;
drh761df872006-12-21 01:29:22 +00001543#else
drh584c0942006-12-21 03:20:40 +00001544 h = LoadLibraryA((char*)zConverted);
drh761df872006-12-21 01:29:22 +00001545#endif
1546 }
1547 sqliteFree(zConverted);
1548 return (void*)h;
1549
1550}
1551void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
drh2a4d54b2006-12-21 02:21:56 +00001552#if OS_WINCE
1553 /* The GetProcAddressA() routine is only available on wince. */
1554 return GetProcAddressA((HANDLE)pHandle, zSymbol);
1555#else
1556 /* All other windows platforms expect GetProcAddress() to take
1557 ** an Ansi string regardless of the _UNICODE setting */
drh761df872006-12-21 01:29:22 +00001558 return GetProcAddress((HANDLE)pHandle, zSymbol);
drh2a4d54b2006-12-21 02:21:56 +00001559#endif
drh761df872006-12-21 01:29:22 +00001560}
1561int sqlite3WinDlclose(void *pHandle){
1562 return FreeLibrary((HANDLE)pHandle);
1563}
1564#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
1565
drh0ccebe72005-06-07 22:22:50 +00001566/*
drhbbd42a62004-05-22 17:41:58 +00001567** Get information to seed the random number generator. The seed
1568** is written into the buffer zBuf[256]. The calling function must
1569** supply a sufficiently large buffer.
1570*/
drh66560ad2006-01-06 14:32:19 +00001571int sqlite3WinRandomSeed(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +00001572 /* We have to initialize zBuf to prevent valgrind from reporting
1573 ** errors. The reports issued by valgrind are incorrect - we would
1574 ** prefer that the randomness be increased by making use of the
1575 ** uninitialized space in zBuf - but valgrind errors tend to worry
1576 ** some users. Rather than argue, it seems easier just to initialize
1577 ** the whole array and silence valgrind, even if that means less randomness
1578 ** in the random seed.
1579 **
1580 ** When testing, initializing zBuf[] to zero is all we do. That means
1581 ** that we always use the same random number sequence.* This makes the
1582 ** tests repeatable.
1583 */
1584 memset(zBuf, 0, 256);
1585 GetSystemTime((LPSYSTEMTIME)zBuf);
1586 return SQLITE_OK;
1587}
1588
1589/*
1590** Sleep for a little while. Return the amount of time slept.
1591*/
drh66560ad2006-01-06 14:32:19 +00001592int sqlite3WinSleep(int ms){
drhbbd42a62004-05-22 17:41:58 +00001593 Sleep(ms);
1594 return ms;
1595}
1596
1597/*
1598** Static variables used for thread synchronization
1599*/
1600static int inMutex = 0;
1601#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001602 static DWORD mutexOwner;
drhbbd42a62004-05-22 17:41:58 +00001603 static CRITICAL_SECTION cs;
1604#endif
1605
1606/*
drh757b04e2006-01-18 17:25:45 +00001607** The following pair of routines implement mutual exclusion for
drhbbd42a62004-05-22 17:41:58 +00001608** multi-threaded processes. Only a single thread is allowed to
1609** executed code that is surrounded by EnterMutex() and LeaveMutex().
1610**
1611** SQLite uses only a single Mutex. There is not much critical
1612** code and what little there is executes quickly and without blocking.
drh757b04e2006-01-18 17:25:45 +00001613**
1614** Version 3.3.1 and earlier used a simple mutex. Beginning with
1615** version 3.3.2, a recursive mutex is required.
drhbbd42a62004-05-22 17:41:58 +00001616*/
drh66560ad2006-01-06 14:32:19 +00001617void sqlite3WinEnterMutex(){
drhbbd42a62004-05-22 17:41:58 +00001618#ifdef SQLITE_W32_THREADS
1619 static int isInit = 0;
1620 while( !isInit ){
1621 static long lock = 0;
1622 if( InterlockedIncrement(&lock)==1 ){
1623 InitializeCriticalSection(&cs);
1624 isInit = 1;
1625 }else{
1626 Sleep(1);
1627 }
1628 }
1629 EnterCriticalSection(&cs);
drh757b04e2006-01-18 17:25:45 +00001630 mutexOwner = GetCurrentThreadId();
drhbbd42a62004-05-22 17:41:58 +00001631#endif
drh332b1fe2006-01-18 14:20:17 +00001632 inMutex++;
drhbbd42a62004-05-22 17:41:58 +00001633}
drh66560ad2006-01-06 14:32:19 +00001634void sqlite3WinLeaveMutex(){
drhbbd42a62004-05-22 17:41:58 +00001635 assert( inMutex );
drh332b1fe2006-01-18 14:20:17 +00001636 inMutex--;
drhbbd42a62004-05-22 17:41:58 +00001637#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001638 assert( mutexOwner==GetCurrentThreadId() );
drhbbd42a62004-05-22 17:41:58 +00001639 LeaveCriticalSection(&cs);
1640#endif
1641}
1642
1643/*
drh757b04e2006-01-18 17:25:45 +00001644** Return TRUE if the mutex is currently held.
1645**
1646** If the thisThreadOnly parameter is true, return true if and only if the
1647** calling thread holds the mutex. If the parameter is false, return
1648** true if any thread holds the mutex.
drh88f474a2006-01-02 20:00:12 +00001649*/
drh757b04e2006-01-18 17:25:45 +00001650int sqlite3WinInMutex(int thisThreadOnly){
drh332b1fe2006-01-18 14:20:17 +00001651#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001652 return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId());
drh332b1fe2006-01-18 14:20:17 +00001653#else
drh757b04e2006-01-18 17:25:45 +00001654 return inMutex>0;
drh332b1fe2006-01-18 14:20:17 +00001655#endif
drh88f474a2006-01-02 20:00:12 +00001656}
1657
1658
1659/*
drhbbd42a62004-05-22 17:41:58 +00001660** The following variable, if set to a non-zero value, becomes the result
1661** returned from sqlite3OsCurrentTime(). This is used for testing.
1662*/
1663#ifdef SQLITE_TEST
1664int sqlite3_current_time = 0;
1665#endif
1666
1667/*
1668** Find the current time (in Universal Coordinated Time). Write the
1669** current time and date as a Julian Day number into *prNow and
1670** return 0. Return 1 if the time and date cannot be found.
1671*/
drh66560ad2006-01-06 14:32:19 +00001672int sqlite3WinCurrentTime(double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001673 FILETIME ft;
1674 /* FILETIME structure is a 64-bit value representing the number of
1675 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1676 */
1677 double now;
drhcc78fea2006-01-06 16:17:05 +00001678#if OS_WINCE
1679 SYSTEMTIME time;
1680 GetSystemTime(&time);
1681 SystemTimeToFileTime(&time,&ft);
1682#else
drhbbd42a62004-05-22 17:41:58 +00001683 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001684#endif
drhbbd42a62004-05-22 17:41:58 +00001685 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1686 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1687#ifdef SQLITE_TEST
1688 if( sqlite3_current_time ){
1689 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1690 }
1691#endif
1692 return 0;
1693}
1694
drh6f7adc82006-01-11 21:41:20 +00001695/*
drhb4bc7052006-01-11 23:40:33 +00001696** Remember the number of thread-specific-data blocks allocated.
1697** Use this to verify that we are not leaking thread-specific-data.
1698** Ticket #1601
1699*/
1700#ifdef SQLITE_TEST
1701int sqlite3_tsd_count = 0;
1702# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
1703# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
1704#else
1705# define TSD_COUNTER_INCR /* no-op */
1706# define TSD_COUNTER_DECR /* no-op */
1707#endif
1708
1709
1710
1711/*
drh70ff98a2006-01-12 01:25:18 +00001712** If called with allocateFlag>1, then return a pointer to thread
drh6f7adc82006-01-11 21:41:20 +00001713** specific data for the current thread. Allocate and zero the
1714** thread-specific data if it does not already exist necessary.
drh3fbb0b12006-01-06 00:36:00 +00001715**
drh6f7adc82006-01-11 21:41:20 +00001716** If called with allocateFlag==0, then check the current thread
drh70ff98a2006-01-12 01:25:18 +00001717** specific data. Return it if it exists. If it does not exist,
1718** then return NULL.
1719**
1720** If called with allocateFlag<0, check to see if the thread specific
1721** data is allocated and is all zero. If it is then deallocate it.
drh6f7adc82006-01-11 21:41:20 +00001722** Return a pointer to the thread specific data or NULL if it is
drh70ff98a2006-01-12 01:25:18 +00001723** unallocated or gets deallocated.
danielk197713a68c32005-12-15 10:11:30 +00001724*/
drhb4bc7052006-01-11 23:40:33 +00001725ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
drh3fbb0b12006-01-06 00:36:00 +00001726 static int key;
1727 static int keyInit = 0;
drh0850b532006-01-31 19:31:43 +00001728 static const ThreadData zeroData = {0};
drhb4bc7052006-01-11 23:40:33 +00001729 ThreadData *pTsd;
drh3fbb0b12006-01-06 00:36:00 +00001730
1731 if( !keyInit ){
drh66560ad2006-01-06 14:32:19 +00001732 sqlite3OsEnterMutex();
drh3fbb0b12006-01-06 00:36:00 +00001733 if( !keyInit ){
1734 key = TlsAlloc();
1735 if( key==0xffffffff ){
drh66560ad2006-01-06 14:32:19 +00001736 sqlite3OsLeaveMutex();
drh3fbb0b12006-01-06 00:36:00 +00001737 return 0;
1738 }
1739 keyInit = 1;
1740 }
drh66560ad2006-01-06 14:32:19 +00001741 sqlite3OsLeaveMutex();
danielk197713a68c32005-12-15 10:11:30 +00001742 }
drh3fbb0b12006-01-06 00:36:00 +00001743 pTsd = TlsGetValue(key);
drh70ff98a2006-01-12 01:25:18 +00001744 if( allocateFlag>0 ){
drh6f7adc82006-01-11 21:41:20 +00001745 if( !pTsd ){
drhb4bc7052006-01-11 23:40:33 +00001746 pTsd = sqlite3OsMalloc( sizeof(zeroData) );
drh6f7adc82006-01-11 21:41:20 +00001747 if( pTsd ){
1748 *pTsd = zeroData;
1749 TlsSetValue(key, pTsd);
drhb4bc7052006-01-11 23:40:33 +00001750 TSD_COUNTER_INCR;
drh6f7adc82006-01-11 21:41:20 +00001751 }
drh3fbb0b12006-01-06 00:36:00 +00001752 }
drh70ff98a2006-01-12 01:25:18 +00001753 }else if( pTsd!=0 && allocateFlag<0
danielk19779e128002006-01-18 16:51:35 +00001754 && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
drh6f7adc82006-01-11 21:41:20 +00001755 sqlite3OsFree(pTsd);
1756 TlsSetValue(key, 0);
drhb4bc7052006-01-11 23:40:33 +00001757 TSD_COUNTER_DECR;
drh6f7adc82006-01-11 21:41:20 +00001758 pTsd = 0;
drh3fbb0b12006-01-06 00:36:00 +00001759 }
1760 return pTsd;
danielk197713a68c32005-12-15 10:11:30 +00001761}
drhbbd42a62004-05-22 17:41:58 +00001762#endif /* OS_WIN */