blob: 6c167ab5b8dc782902646768fa51cdef09884a3b [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/*
127** Convert a UTF-8 string to UTF-32. Space to hold the returned string
128** is obtained from sqliteMalloc.
129*/
130static WCHAR *utf8ToUnicode(const char *zFilename){
drhe3dd8bb2006-02-27 23:44:35 +0000131 int nChar;
drhc0929982005-09-05 19:08:29 +0000132 WCHAR *zWideFilename;
133
134 if( !isNT() ){
135 return 0;
136 }
drhe3dd8bb2006-02-27 23:44:35 +0000137 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
138 zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000139 if( zWideFilename==0 ){
140 return 0;
141 }
drhe3dd8bb2006-02-27 23:44:35 +0000142 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
143 if( nChar==0 ){
drhc0929982005-09-05 19:08:29 +0000144 sqliteFree(zWideFilename);
145 zWideFilename = 0;
146 }
147 return zWideFilename;
148}
149
150/*
151** Convert UTF-32 to UTF-8. Space to hold the returned string is
152** obtained from sqliteMalloc().
153*/
154static char *unicodeToUtf8(const WCHAR *zWideFilename){
155 int nByte;
156 char *zFilename;
157
158 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
159 zFilename = sqliteMalloc( nByte );
160 if( zFilename==0 ){
161 return 0;
162 }
163 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
164 0, 0);
165 if( nByte == 0 ){
166 sqliteFree(zFilename);
167 zFilename = 0;
168 }
169 return zFilename;
170}
171
drh72aead82006-01-23 15:54:25 +0000172#if OS_WINCE
173/*************************************************************************
174** This section contains code for WinCE only.
175*/
176/*
177** WindowsCE does not have a localtime() function. So create a
178** substitute.
179*/
180#include <time.h>
181struct tm *__cdecl localtime(const time_t *t)
182{
183 static struct tm y;
184 FILETIME uTm, lTm;
185 SYSTEMTIME pTm;
186 i64 t64;
187 t64 = *t;
188 t64 = (t64 + 11644473600)*10000000;
189 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
190 uTm.dwHighDateTime= t64 >> 32;
191 FileTimeToLocalFileTime(&uTm,&lTm);
192 FileTimeToSystemTime(&lTm,&pTm);
193 y.tm_year = pTm.wYear - 1900;
194 y.tm_mon = pTm.wMonth - 1;
195 y.tm_wday = pTm.wDayOfWeek;
196 y.tm_mday = pTm.wDay;
197 y.tm_hour = pTm.wHour;
198 y.tm_min = pTm.wMinute;
199 y.tm_sec = pTm.wSecond;
200 return &y;
201}
202
203/* This will never be called, but defined to make the code compile */
204#define GetTempPathA(a,b)
205
206#define LockFile(a,b,c,d,e) winceLockFile(&a, b, c, d, e)
207#define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e)
208#define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f)
209
210#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]
211
212/*
213** Acquire a lock on the handle h
214*/
215static void winceMutexAcquire(HANDLE h){
216 DWORD dwErr;
217 do {
218 dwErr = WaitForSingleObject(h, INFINITE);
219 } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
220}
221/*
222** Release a lock acquired by winceMutexAcquire()
223*/
224#define winceMutexRelease(h) ReleaseMutex(h)
225
226/*
227** Create the mutex and shared memory used for locking in the file
228** descriptor pFile
229*/
230static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
231 WCHAR *zTok;
232 WCHAR *zName = utf8ToUnicode(zFilename);
233 BOOL bInit = TRUE;
234
235 /* Initialize the local lockdata */
236 ZeroMemory(&pFile->local, sizeof(pFile->local));
237
238 /* Replace the backslashes from the filename and lowercase it
239 ** to derive a mutex name. */
240 zTok = CharLowerW(zName);
241 for (;*zTok;zTok++){
242 if (*zTok == '\\') *zTok = '_';
243 }
244
245 /* Create/open the named mutex */
246 pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
247 if (!pFile->hMutex){
248 sqliteFree(zName);
249 return FALSE;
250 }
251
252 /* Acquire the mutex before continuing */
253 winceMutexAcquire(pFile->hMutex);
254
255 /* Since the names of named mutexes, semaphores, file mappings etc are
256 ** case-sensitive, take advantage of that by uppercasing the mutex name
257 ** and using that as the shared filemapping name.
258 */
259 CharUpperW(zName);
260 pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
261 PAGE_READWRITE, 0, sizeof(winceLock),
262 zName);
263
264 /* Set a flag that indicates we're the first to create the memory so it
265 ** must be zero-initialized */
266 if (GetLastError() == ERROR_ALREADY_EXISTS){
267 bInit = FALSE;
268 }
269
270 sqliteFree(zName);
271
272 /* If we succeeded in making the shared memory handle, map it. */
273 if (pFile->hShared){
274 pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,
275 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
276 /* If mapping failed, close the shared memory handle and erase it */
277 if (!pFile->shared){
278 CloseHandle(pFile->hShared);
279 pFile->hShared = NULL;
280 }
281 }
282
283 /* If shared memory could not be created, then close the mutex and fail */
284 if (pFile->hShared == NULL){
285 winceMutexRelease(pFile->hMutex);
286 CloseHandle(pFile->hMutex);
287 pFile->hMutex = NULL;
288 return FALSE;
289 }
290
291 /* Initialize the shared memory if we're supposed to */
292 if (bInit) {
293 ZeroMemory(pFile->shared, sizeof(winceLock));
294 }
295
296 winceMutexRelease(pFile->hMutex);
297 return TRUE;
298}
299
300/*
301** Destroy the part of winFile that deals with wince locks
302*/
303static void winceDestroyLock(winFile *pFile){
304 if (pFile->hMutex){
305 /* Acquire the mutex */
306 winceMutexAcquire(pFile->hMutex);
307
308 /* The following blocks should probably assert in debug mode, but they
309 are to cleanup in case any locks remained open */
310 if (pFile->local.nReaders){
311 pFile->shared->nReaders --;
312 }
313 if (pFile->local.bReserved){
314 pFile->shared->bReserved = FALSE;
315 }
316 if (pFile->local.bPending){
317 pFile->shared->bPending = FALSE;
318 }
319 if (pFile->local.bExclusive){
320 pFile->shared->bExclusive = FALSE;
321 }
322
323 /* De-reference and close our copy of the shared memory handle */
324 UnmapViewOfFile(pFile->shared);
325 CloseHandle(pFile->hShared);
326
327 /* Done with the mutex */
328 winceMutexRelease(pFile->hMutex);
329 CloseHandle(pFile->hMutex);
330 pFile->hMutex = NULL;
331 }
332}
333
334/*
335** An implementation of the LockFile() API of windows for wince
336*/
337static BOOL winceLockFile(
338 HANDLE *phFile,
339 DWORD dwFileOffsetLow,
340 DWORD dwFileOffsetHigh,
341 DWORD nNumberOfBytesToLockLow,
342 DWORD nNumberOfBytesToLockHigh
343){
344 winFile *pFile = HANDLE_TO_WINFILE(phFile);
345 BOOL bReturn = FALSE;
346
347 if (!pFile->hMutex) return TRUE;
348 winceMutexAcquire(pFile->hMutex);
349
350 /* Wanting an exclusive lock? */
351 if (dwFileOffsetLow == SHARED_FIRST
352 && nNumberOfBytesToLockLow == SHARED_SIZE){
353 if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
354 pFile->shared->bExclusive = TRUE;
355 pFile->local.bExclusive = TRUE;
356 bReturn = TRUE;
357 }
358 }
359
360 /* Want a read-only lock? */
361 else if ((dwFileOffsetLow >= SHARED_FIRST &&
362 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&
363 nNumberOfBytesToLockLow == 1){
364 if (pFile->shared->bExclusive == 0){
365 pFile->local.nReaders ++;
366 if (pFile->local.nReaders == 1){
367 pFile->shared->nReaders ++;
368 }
369 bReturn = TRUE;
370 }
371 }
372
373 /* Want a pending lock? */
374 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){
375 /* If no pending lock has been acquired, then acquire it */
376 if (pFile->shared->bPending == 0) {
377 pFile->shared->bPending = TRUE;
378 pFile->local.bPending = TRUE;
379 bReturn = TRUE;
380 }
381 }
382 /* Want a reserved lock? */
383 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
384 if (pFile->shared->bReserved == 0) {
385 pFile->shared->bReserved = TRUE;
386 pFile->local.bReserved = TRUE;
387 bReturn = TRUE;
388 }
389 }
390
391 winceMutexRelease(pFile->hMutex);
392 return bReturn;
393}
394
395/*
396** An implementation of the UnlockFile API of windows for wince
397*/
398static BOOL winceUnlockFile(
399 HANDLE *phFile,
400 DWORD dwFileOffsetLow,
401 DWORD dwFileOffsetHigh,
402 DWORD nNumberOfBytesToUnlockLow,
403 DWORD nNumberOfBytesToUnlockHigh
404){
405 winFile *pFile = HANDLE_TO_WINFILE(phFile);
406 BOOL bReturn = FALSE;
407
408 if (!pFile->hMutex) return TRUE;
409 winceMutexAcquire(pFile->hMutex);
410
411 /* Releasing a reader lock or an exclusive lock */
412 if (dwFileOffsetLow >= SHARED_FIRST &&
413 dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){
414 /* Did we have an exclusive lock? */
415 if (pFile->local.bExclusive){
416 pFile->local.bExclusive = FALSE;
417 pFile->shared->bExclusive = FALSE;
418 bReturn = TRUE;
419 }
420
421 /* Did we just have a reader lock? */
422 else if (pFile->local.nReaders){
423 pFile->local.nReaders --;
424 if (pFile->local.nReaders == 0)
425 {
426 pFile->shared->nReaders --;
427 }
428 bReturn = TRUE;
429 }
430 }
431
432 /* Releasing a pending lock */
433 else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
434 if (pFile->local.bPending){
435 pFile->local.bPending = FALSE;
436 pFile->shared->bPending = FALSE;
437 bReturn = TRUE;
438 }
439 }
440 /* Releasing a reserved lock */
441 else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
442 if (pFile->local.bReserved) {
443 pFile->local.bReserved = FALSE;
444 pFile->shared->bReserved = FALSE;
445 bReturn = TRUE;
446 }
447 }
448
449 winceMutexRelease(pFile->hMutex);
450 return bReturn;
451}
452
453/*
454** An implementation of the LockFileEx() API of windows for wince
455*/
456static BOOL winceLockFileEx(
457 HANDLE *phFile,
458 DWORD dwFlags,
459 DWORD dwReserved,
460 DWORD nNumberOfBytesToLockLow,
461 DWORD nNumberOfBytesToLockHigh,
462 LPOVERLAPPED lpOverlapped
463){
464 /* If the caller wants a shared read lock, forward this call
465 ** to winceLockFile */
466 if (lpOverlapped->Offset == SHARED_FIRST &&
467 dwFlags == 1 &&
468 nNumberOfBytesToLockLow == SHARED_SIZE){
469 return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);
470 }
471 return FALSE;
472}
473/*
474** End of the special code for wince
475*****************************************************************************/
476#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000477
478/*
drh59e63a62006-06-04 23:31:48 +0000479** Delete the named file.
480**
481** Note that windows does not allow a file to be deleted if some other
482** process has it open. Sometimes a virus scanner or indexing program
483** will open a journal file shortly after it is created in order to do
484** whatever it is it does. While this other process is holding the
485** file open, we will be unable to delete it. To work around this
486** problem, we delay 100 milliseconds and try to delete again. Up
487** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
488** up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000489*/
drh59e63a62006-06-04 23:31:48 +0000490#define MX_DELETION_ATTEMPTS 3
drh66560ad2006-01-06 14:32:19 +0000491int sqlite3WinDelete(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000492 WCHAR *zWide = utf8ToUnicode(zFilename);
drheb4fa522006-06-04 23:02:20 +0000493 int cnt = 0;
494 int rc;
drhc0929982005-09-05 19:08:29 +0000495 if( zWide ){
drheb4fa522006-06-04 23:02:20 +0000496 do{
497 rc = DeleteFileW(zWide);
drh59e63a62006-06-04 23:31:48 +0000498 }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
drhc0929982005-09-05 19:08:29 +0000499 sqliteFree(zWide);
500 }else{
drhcc78fea2006-01-06 16:17:05 +0000501#if OS_WINCE
502 return SQLITE_NOMEM;
503#else
drheb4fa522006-06-04 23:02:20 +0000504 do{
505 rc = DeleteFileA(zFilename);
drh59e63a62006-06-04 23:31:48 +0000506 }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000507#endif
drhc0929982005-09-05 19:08:29 +0000508 }
drh51c6d962004-06-06 00:42:25 +0000509 TRACE2("DELETE \"%s\"\n", zFilename);
drheb4fa522006-06-04 23:02:20 +0000510 return rc==0 ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000511}
512
513/*
514** Return TRUE if the named file exists.
515*/
drh66560ad2006-01-06 14:32:19 +0000516int sqlite3WinFileExists(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000517 int exists = 0;
518 WCHAR *zWide = utf8ToUnicode(zFilename);
519 if( zWide ){
520 exists = GetFileAttributesW(zWide) != 0xffffffff;
521 sqliteFree(zWide);
522 }else{
drhcc78fea2006-01-06 16:17:05 +0000523#if OS_WINCE
524 return SQLITE_NOMEM;
525#else
drhc0929982005-09-05 19:08:29 +0000526 exists = GetFileAttributesA(zFilename) != 0xffffffff;
drhcc78fea2006-01-06 16:17:05 +0000527#endif
drhc0929982005-09-05 19:08:29 +0000528 }
529 return exists;
drhbbd42a62004-05-22 17:41:58 +0000530}
531
drh054889e2005-11-30 03:20:31 +0000532/* Forward declaration */
danielk1977f0113002006-01-24 12:09:17 +0000533static int allocateWinFile(winFile *pInit, OsFile **pId);
drh9cbe6352005-11-29 03:13:21 +0000534
drhbbd42a62004-05-22 17:41:58 +0000535/*
536** Attempt to open a file for both reading and writing. If that
537** fails, try opening it read-only. If the file does not exist,
538** try to create it.
539**
540** On success, a handle for the open file is written to *id
541** and *pReadonly is set to 0 if the file was opened for reading and
542** writing or 1 if the file was opened read-only. The function returns
543** SQLITE_OK.
544**
545** On failure, the function returns SQLITE_CANTOPEN and leaves
546** *id and *pReadonly unchanged.
547*/
drh66560ad2006-01-06 14:32:19 +0000548int sqlite3WinOpenReadWrite(
drhbbd42a62004-05-22 17:41:58 +0000549 const char *zFilename,
drh9cbe6352005-11-29 03:13:21 +0000550 OsFile **pId,
drhbbd42a62004-05-22 17:41:58 +0000551 int *pReadonly
552){
drh054889e2005-11-30 03:20:31 +0000553 winFile f;
drhda71ce12004-06-21 18:14:45 +0000554 HANDLE h;
drhc0929982005-09-05 19:08:29 +0000555 WCHAR *zWide = utf8ToUnicode(zFilename);
drh9cbe6352005-11-29 03:13:21 +0000556 assert( *pId==0 );
drhc0929982005-09-05 19:08:29 +0000557 if( zWide ){
558 h = CreateFileW(zWide,
559 GENERIC_READ | GENERIC_WRITE,
560 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhbbd42a62004-05-22 17:41:58 +0000561 NULL,
562 OPEN_ALWAYS,
563 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
564 NULL
565 );
566 if( h==INVALID_HANDLE_VALUE ){
drhc0929982005-09-05 19:08:29 +0000567 h = CreateFileW(zWide,
568 GENERIC_READ,
drh94d57e32006-06-02 12:40:08 +0000569 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhc0929982005-09-05 19:08:29 +0000570 NULL,
571 OPEN_ALWAYS,
572 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
573 NULL
574 );
575 if( h==INVALID_HANDLE_VALUE ){
576 sqliteFree(zWide);
577 return SQLITE_CANTOPEN;
578 }
579 *pReadonly = 1;
580 }else{
581 *pReadonly = 0;
drhbbd42a62004-05-22 17:41:58 +0000582 }
drh72aead82006-01-23 15:54:25 +0000583#if OS_WINCE
584 if (!winceCreateLock(zFilename, &f)){
585 CloseHandle(h);
586 sqliteFree(zWide);
587 return SQLITE_CANTOPEN;
588 }
589#endif
drhc0929982005-09-05 19:08:29 +0000590 sqliteFree(zWide);
drhbbd42a62004-05-22 17:41:58 +0000591 }else{
drhcc78fea2006-01-06 16:17:05 +0000592#if OS_WINCE
593 return SQLITE_NOMEM;
594#else
drhc0929982005-09-05 19:08:29 +0000595 h = CreateFileA(zFilename,
596 GENERIC_READ | GENERIC_WRITE,
597 FILE_SHARE_READ | FILE_SHARE_WRITE,
598 NULL,
599 OPEN_ALWAYS,
600 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
601 NULL
602 );
603 if( h==INVALID_HANDLE_VALUE ){
604 h = CreateFileA(zFilename,
605 GENERIC_READ,
drh94d57e32006-06-02 12:40:08 +0000606 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhc0929982005-09-05 19:08:29 +0000607 NULL,
608 OPEN_ALWAYS,
609 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
610 NULL
611 );
612 if( h==INVALID_HANDLE_VALUE ){
613 return SQLITE_CANTOPEN;
614 }
615 *pReadonly = 1;
616 }else{
617 *pReadonly = 0;
618 }
drhcc78fea2006-01-06 16:17:05 +0000619#endif /* OS_WINCE */
drhbbd42a62004-05-22 17:41:58 +0000620 }
drh9cbe6352005-11-29 03:13:21 +0000621 f.h = h;
drh4bddfd22006-01-07 18:14:48 +0000622#if OS_WINCE
623 f.zDeleteOnClose = 0;
624#endif
drh51c6d962004-06-06 00:42:25 +0000625 TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000626 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000627}
628
629
630/*
631** Attempt to open a new file for exclusive access by this process.
632** The file will be opened for both reading and writing. To avoid
633** a potential security problem, we do not allow the file to have
634** previously existed. Nor do we allow the file to be a symbolic
635** link.
636**
637** If delFlag is true, then make arrangements to automatically delete
638** the file when it is closed.
639**
640** On success, write the file handle into *id and return SQLITE_OK.
641**
642** On failure, return SQLITE_CANTOPEN.
drh59e63a62006-06-04 23:31:48 +0000643**
644** Sometimes if we have just deleted a prior journal file, windows
645** will fail to open a new one because there is a "pending delete".
646** To work around this bug, we pause for 100 milliseconds and attempt
647** a second open after the first one fails. The whole operation only
648** fails if both open attempts are unsuccessful.
drhbbd42a62004-05-22 17:41:58 +0000649*/
drh66560ad2006-01-06 14:32:19 +0000650int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
drh054889e2005-11-30 03:20:31 +0000651 winFile f;
drhbbd42a62004-05-22 17:41:58 +0000652 HANDLE h;
653 int fileflags;
drhc0929982005-09-05 19:08:29 +0000654 WCHAR *zWide = utf8ToUnicode(zFilename);
drh9cbe6352005-11-29 03:13:21 +0000655 assert( *pId == 0 );
drhcc78fea2006-01-06 16:17:05 +0000656 fileflags = FILE_FLAG_RANDOM_ACCESS;
657#if !OS_WINCE
drhbbd42a62004-05-22 17:41:58 +0000658 if( delFlag ){
drhcc78fea2006-01-06 16:17:05 +0000659 fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
drhbbd42a62004-05-22 17:41:58 +0000660 }
drhcc78fea2006-01-06 16:17:05 +0000661#endif
drhc0929982005-09-05 19:08:29 +0000662 if( zWide ){
drheb4fa522006-06-04 23:02:20 +0000663 int cnt = 0;
664 do{
665 h = CreateFileW(zWide,
666 GENERIC_READ | GENERIC_WRITE,
667 0,
668 NULL,
669 CREATE_ALWAYS,
670 fileflags,
671 NULL
672 );
673 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
drhc0929982005-09-05 19:08:29 +0000674 sqliteFree(zWide);
675 }else{
drhcc78fea2006-01-06 16:17:05 +0000676#if OS_WINCE
677 return SQLITE_NOMEM;
678#else
drheb4fa522006-06-04 23:02:20 +0000679 int cnt = 0;
680 do{
681 h = CreateFileA(zFilename,
682 GENERIC_READ | GENERIC_WRITE,
683 0,
684 NULL,
685 CREATE_ALWAYS,
686 fileflags,
687 NULL
688 );
689 }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000690#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000691 }
drhbbd42a62004-05-22 17:41:58 +0000692 if( h==INVALID_HANDLE_VALUE ){
693 return SQLITE_CANTOPEN;
694 }
drh9cbe6352005-11-29 03:13:21 +0000695 f.h = h;
drhcc78fea2006-01-06 16:17:05 +0000696#if OS_WINCE
drh9e9fe6f2006-01-06 21:09:01 +0000697 f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0;
drh36a50052006-01-23 22:15:07 +0000698 f.hMutex = NULL;
drhcc78fea2006-01-06 16:17:05 +0000699#endif
drh51c6d962004-06-06 00:42:25 +0000700 TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000701 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000702}
703
704/*
705** Attempt to open a new file for read-only access.
706**
707** On success, write the file handle into *id and return SQLITE_OK.
708**
709** On failure, return SQLITE_CANTOPEN.
710*/
drh66560ad2006-01-06 14:32:19 +0000711int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000712 winFile f;
drhda71ce12004-06-21 18:14:45 +0000713 HANDLE h;
drhc0929982005-09-05 19:08:29 +0000714 WCHAR *zWide = utf8ToUnicode(zFilename);
drh9cbe6352005-11-29 03:13:21 +0000715 assert( *pId==0 );
drhc0929982005-09-05 19:08:29 +0000716 if( zWide ){
717 h = CreateFileW(zWide,
718 GENERIC_READ,
719 0,
720 NULL,
721 OPEN_EXISTING,
722 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
723 NULL
724 );
725 sqliteFree(zWide);
726 }else{
drhcc78fea2006-01-06 16:17:05 +0000727#if OS_WINCE
728 return SQLITE_NOMEM;
729#else
drhc0929982005-09-05 19:08:29 +0000730 h = CreateFileA(zFilename,
731 GENERIC_READ,
732 0,
733 NULL,
734 OPEN_EXISTING,
735 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
736 NULL
737 );
drhcc78fea2006-01-06 16:17:05 +0000738#endif
drhc0929982005-09-05 19:08:29 +0000739 }
drhbbd42a62004-05-22 17:41:58 +0000740 if( h==INVALID_HANDLE_VALUE ){
741 return SQLITE_CANTOPEN;
742 }
drh9cbe6352005-11-29 03:13:21 +0000743 f.h = h;
drh4bddfd22006-01-07 18:14:48 +0000744#if OS_WINCE
745 f.zDeleteOnClose = 0;
drh36a50052006-01-23 22:15:07 +0000746 f.hMutex = NULL;
drh4bddfd22006-01-07 18:14:48 +0000747#endif
drh51c6d962004-06-06 00:42:25 +0000748 TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000749 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000750}
751
752/*
753** Attempt to open a file descriptor for the directory that contains a
754** file. This file descriptor can be used to fsync() the directory
755** in order to make sure the creation of a new file is actually written
756** to disk.
757**
758** This routine is only meaningful for Unix. It is a no-op under
759** windows since windows does not support hard links.
760**
761** On success, a handle for a previously open file is at *id is
762** updated with the new directory file descriptor and SQLITE_OK is
763** returned.
764**
765** On failure, the function returns SQLITE_CANTOPEN and leaves
766** *id unchanged.
767*/
drh9c06c952005-11-26 00:25:00 +0000768static int winOpenDirectory(
drh054889e2005-11-30 03:20:31 +0000769 OsFile *id,
770 const char *zDirname
drhbbd42a62004-05-22 17:41:58 +0000771){
772 return SQLITE_OK;
773}
774
775/*
drh3d2efea2004-08-28 01:12:56 +0000776** If the following global variable points to a string which is the
777** name of a directory, then that directory will be used to store
778** temporary files.
779*/
tpoindex9a09a3c2004-12-20 19:01:32 +0000780char *sqlite3_temp_directory = 0;
drh3d2efea2004-08-28 01:12:56 +0000781
782/*
drhbbd42a62004-05-22 17:41:58 +0000783** Create a temporary file name in zBuf. zBuf must be big enough to
784** hold at least SQLITE_TEMPNAME_SIZE characters.
785*/
drh66560ad2006-01-06 14:32:19 +0000786int sqlite3WinTempFileName(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +0000787 static char zChars[] =
788 "abcdefghijklmnopqrstuvwxyz"
789 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
790 "0123456789";
791 int i, j;
792 char zTempPath[SQLITE_TEMPNAME_SIZE];
drheffd02b2004-08-29 23:42:13 +0000793 if( sqlite3_temp_directory ){
794 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
drh3d2efea2004-08-28 01:12:56 +0000795 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
drhc0929982005-09-05 19:08:29 +0000796 }else if( isNT() ){
797 char *zMulti;
798 WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
799 GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
800 zMulti = unicodeToUtf8(zWidePath);
801 if( zMulti ){
drhd81bd4e2005-09-05 20:06:49 +0000802 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
drhc0929982005-09-05 19:08:29 +0000803 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
804 sqliteFree(zMulti);
805 }
drh3d2efea2004-08-28 01:12:56 +0000806 }else{
807 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
808 }
drhbbd42a62004-05-22 17:41:58 +0000809 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
810 zTempPath[i] = 0;
811 for(;;){
812 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
813 j = strlen(zBuf);
814 sqlite3Randomness(15, &zBuf[j]);
815 for(i=0; i<15; i++, j++){
816 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
817 }
818 zBuf[j] = 0;
drh66560ad2006-01-06 14:32:19 +0000819 if( !sqlite3OsFileExists(zBuf) ) break;
drhbbd42a62004-05-22 17:41:58 +0000820 }
drh51c6d962004-06-06 00:42:25 +0000821 TRACE2("TEMP FILENAME: %s\n", zBuf);
drhbbd42a62004-05-22 17:41:58 +0000822 return SQLITE_OK;
823}
824
825/*
826** Close a file.
drh59e63a62006-06-04 23:31:48 +0000827**
828** It is reported that an attempt to close a handle might sometimes
829** fail. This is a very unreasonable result, but windows is notorious
830** for being unreasonable so I do not doubt that it might happen. If
831** the close fails, we pause for 100 milliseconds and try again. As
832** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
833** giving up and returning an error.
drhbbd42a62004-05-22 17:41:58 +0000834*/
drh59e63a62006-06-04 23:31:48 +0000835#define MX_CLOSE_ATTEMPT 3
drh9cbe6352005-11-29 03:13:21 +0000836static int winClose(OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000837 winFile *pFile;
drheb4fa522006-06-04 23:02:20 +0000838 int rc = 1;
drh054889e2005-11-30 03:20:31 +0000839 if( pId && (pFile = (winFile*)*pId)!=0 ){
drheb4fa522006-06-04 23:02:20 +0000840 int rc, cnt = 0;
drh054889e2005-11-30 03:20:31 +0000841 TRACE2("CLOSE %d\n", pFile->h);
drheb4fa522006-06-04 23:02:20 +0000842 do{
843 rc = CloseHandle(pFile->h);
drh59e63a62006-06-04 23:31:48 +0000844 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
drhcc78fea2006-01-06 16:17:05 +0000845#if OS_WINCE
drh72aead82006-01-23 15:54:25 +0000846 winceDestroyLock(pFile);
drhcc78fea2006-01-06 16:17:05 +0000847 if( pFile->zDeleteOnClose ){
drh9e9fe6f2006-01-06 21:09:01 +0000848 DeleteFileW(pFile->zDeleteOnClose);
drhcc78fea2006-01-06 16:17:05 +0000849 sqliteFree(pFile->zDeleteOnClose);
850 }
851#endif
drhda71ce12004-06-21 18:14:45 +0000852 OpenCounter(-1);
drh054889e2005-11-30 03:20:31 +0000853 sqliteFree(pFile);
drh9cbe6352005-11-29 03:13:21 +0000854 *pId = 0;
drhda71ce12004-06-21 18:14:45 +0000855 }
drheb4fa522006-06-04 23:02:20 +0000856 return rc ? SQLITE_OK : SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000857}
858
859/*
860** Read data from a file into a buffer. Return SQLITE_OK if all
861** bytes were read successfully and SQLITE_IOERR if anything goes
862** wrong.
863*/
drh9c06c952005-11-26 00:25:00 +0000864static int winRead(OsFile *id, void *pBuf, int amt){
drhbbd42a62004-05-22 17:41:58 +0000865 DWORD got;
drh9cbe6352005-11-29 03:13:21 +0000866 assert( id!=0 );
drhbbd42a62004-05-22 17:41:58 +0000867 SimulateIOError(SQLITE_IOERR);
drh054889e2005-11-30 03:20:31 +0000868 TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
869 if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
drhbbd42a62004-05-22 17:41:58 +0000870 got = 0;
871 }
872 if( got==(DWORD)amt ){
873 return SQLITE_OK;
874 }else{
875 return SQLITE_IOERR;
876 }
877}
878
879/*
880** Write data from a buffer into a file. Return SQLITE_OK on success
881** or some other error code on failure.
882*/
drh9c06c952005-11-26 00:25:00 +0000883static int winWrite(OsFile *id, const void *pBuf, int amt){
drh4c7f9412005-02-03 00:29:47 +0000884 int rc = 0;
drhbbd42a62004-05-22 17:41:58 +0000885 DWORD wrote;
drh9cbe6352005-11-29 03:13:21 +0000886 assert( id!=0 );
drhbbd42a62004-05-22 17:41:58 +0000887 SimulateIOError(SQLITE_IOERR);
dougcurrie0924bba2004-10-01 18:21:43 +0000888 SimulateDiskfullError;
drh054889e2005-11-30 03:20:31 +0000889 TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
drh4c7f9412005-02-03 00:29:47 +0000890 assert( amt>0 );
drh054889e2005-11-30 03:20:31 +0000891 while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
892 && wrote>0 ){
drhbbd42a62004-05-22 17:41:58 +0000893 amt -= wrote;
894 pBuf = &((char*)pBuf)[wrote];
895 }
896 if( !rc || amt>(int)wrote ){
897 return SQLITE_FULL;
898 }
899 return SQLITE_OK;
900}
901
902/*
drhbbdc2b92005-09-19 12:53:18 +0000903** Some microsoft compilers lack this definition.
904*/
905#ifndef INVALID_SET_FILE_POINTER
906# define INVALID_SET_FILE_POINTER ((DWORD)-1)
907#endif
908
909/*
drhbbd42a62004-05-22 17:41:58 +0000910** Move the read/write pointer in a file.
911*/
drh9c06c952005-11-26 00:25:00 +0000912static int winSeek(OsFile *id, i64 offset){
drhbbd42a62004-05-22 17:41:58 +0000913 LONG upperBits = offset>>32;
914 LONG lowerBits = offset & 0xffffffff;
915 DWORD rc;
drh9cbe6352005-11-29 03:13:21 +0000916 assert( id!=0 );
drhb4746b92005-09-09 01:32:06 +0000917#ifdef SQLITE_TEST
918 if( offset ) SimulateDiskfullError
919#endif
drhbbd42a62004-05-22 17:41:58 +0000920 SEEK(offset/1024 + 1);
drh054889e2005-11-30 03:20:31 +0000921 rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
922 TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
drhe08b8142005-09-09 10:17:33 +0000923 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
924 return SQLITE_FULL;
925 }
drhbbd42a62004-05-22 17:41:58 +0000926 return SQLITE_OK;
927}
928
929/*
930** Make sure all writes to a particular file are committed to disk.
931*/
drh9c06c952005-11-26 00:25:00 +0000932static int winSync(OsFile *id, int dataOnly){
drh9cbe6352005-11-29 03:13:21 +0000933 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +0000934 TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
935 if( FlushFileBuffers(((winFile*)id)->h) ){
drhbbd42a62004-05-22 17:41:58 +0000936 return SQLITE_OK;
937 }else{
938 return SQLITE_IOERR;
939 }
940}
941
942/*
danielk1977962398d2004-06-14 09:35:16 +0000943** Sync the directory zDirname. This is a no-op on operating systems other
944** than UNIX.
945*/
drh66560ad2006-01-06 14:32:19 +0000946int sqlite3WinSyncDirectory(const char *zDirname){
danielk1977369f27e2004-06-15 11:40:04 +0000947 SimulateIOError(SQLITE_IOERR);
danielk1977962398d2004-06-14 09:35:16 +0000948 return SQLITE_OK;
949}
950
951/*
drhbbd42a62004-05-22 17:41:58 +0000952** Truncate an open file to a specified size
953*/
drh9c06c952005-11-26 00:25:00 +0000954static int winTruncate(OsFile *id, i64 nByte){
drhbbd42a62004-05-22 17:41:58 +0000955 LONG upperBits = nByte>>32;
drh9cbe6352005-11-29 03:13:21 +0000956 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +0000957 TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
drhbbd42a62004-05-22 17:41:58 +0000958 SimulateIOError(SQLITE_IOERR);
drh054889e2005-11-30 03:20:31 +0000959 SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
960 SetEndOfFile(((winFile*)id)->h);
drhbbd42a62004-05-22 17:41:58 +0000961 return SQLITE_OK;
962}
963
964/*
965** Determine the current size of a file in bytes
966*/
drh9c06c952005-11-26 00:25:00 +0000967static int winFileSize(OsFile *id, i64 *pSize){
drhbbd42a62004-05-22 17:41:58 +0000968 DWORD upperBits, lowerBits;
drh9cbe6352005-11-29 03:13:21 +0000969 assert( id!=0 );
drhbbd42a62004-05-22 17:41:58 +0000970 SimulateIOError(SQLITE_IOERR);
drh054889e2005-11-30 03:20:31 +0000971 lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
drheb206252004-10-01 02:00:31 +0000972 *pSize = (((i64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000973 return SQLITE_OK;
974}
975
976/*
drh602bbd32006-01-06 20:22:29 +0000977** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
978*/
979#ifndef LOCKFILE_FAIL_IMMEDIATELY
980# define LOCKFILE_FAIL_IMMEDIATELY 1
981#endif
982
983/*
drh9c105bb2004-10-02 20:38:28 +0000984** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000985** Different API routines are called depending on whether or not this
986** is Win95 or WinNT.
987*/
drh054889e2005-11-30 03:20:31 +0000988static int getReadLock(winFile *id){
drh51c6d962004-06-06 00:42:25 +0000989 int res;
990 if( isNT() ){
991 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000992 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000993 ovlp.OffsetHigh = 0;
994 ovlp.hEvent = 0;
drh9c105bb2004-10-02 20:38:28 +0000995 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
drhbbd42a62004-05-22 17:41:58 +0000996 }else{
drh9c105bb2004-10-02 20:38:28 +0000997 int lk;
998 sqlite3Randomness(sizeof(lk), &lk);
999 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
1000 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001001 }
1002 return res;
1003}
1004
1005/*
1006** Undo a readlock
1007*/
drh054889e2005-11-30 03:20:31 +00001008static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +00001009 int res;
1010 if( isNT() ){
drh054889e2005-11-30 03:20:31 +00001011 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drh51c6d962004-06-06 00:42:25 +00001012 }else{
drh054889e2005-11-30 03:20:31 +00001013 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001014 }
1015 return res;
1016}
1017
drh268283b2005-01-08 15:44:25 +00001018#ifndef SQLITE_OMIT_PAGER_PRAGMAS
drh51c6d962004-06-06 00:42:25 +00001019/*
tpoindex9a09a3c2004-12-20 19:01:32 +00001020** Check that a given pathname is a directory and is writable
1021**
1022*/
drh66560ad2006-01-06 14:32:19 +00001023int sqlite3WinIsDirWritable(char *zDirname){
tpoindex9a09a3c2004-12-20 19:01:32 +00001024 int fileAttr;
drhc0929982005-09-05 19:08:29 +00001025 WCHAR *zWide;
1026 if( zDirname==0 ) return 0;
1027 if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
1028 zWide = utf8ToUnicode(zDirname);
1029 if( zWide ){
1030 fileAttr = GetFileAttributesW(zWide);
1031 sqliteFree(zWide);
1032 }else{
drhcc78fea2006-01-06 16:17:05 +00001033#if OS_WINCE
1034 return 0;
1035#else
drhc0929982005-09-05 19:08:29 +00001036 fileAttr = GetFileAttributesA(zDirname);
drhcc78fea2006-01-06 16:17:05 +00001037#endif
drhc0929982005-09-05 19:08:29 +00001038 }
tpoindex9a09a3c2004-12-20 19:01:32 +00001039 if( fileAttr == 0xffffffff ) return 0;
drh268283b2005-01-08 15:44:25 +00001040 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
1041 return 0;
1042 }
tpoindex9a09a3c2004-12-20 19:01:32 +00001043 return 1;
1044}
drh268283b2005-01-08 15:44:25 +00001045#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
tpoindex9a09a3c2004-12-20 19:01:32 +00001046
1047/*
drhb3e04342004-06-08 00:47:47 +00001048** Lock the file with the lock specified by parameter locktype - one
1049** of the following:
1050**
1051** (1) SHARED_LOCK
1052** (2) RESERVED_LOCK
1053** (3) PENDING_LOCK
1054** (4) EXCLUSIVE_LOCK
1055**
1056** Sometimes when requesting one lock state, additional lock states
1057** are inserted in between. The locking might fail on one of the later
1058** transitions leaving the lock state different from what it started but
1059** still short of its goal. The following chart shows the allowed
1060** transitions and the inserted intermediate states:
1061**
1062** UNLOCKED -> SHARED
1063** SHARED -> RESERVED
1064** SHARED -> (PENDING) -> EXCLUSIVE
1065** RESERVED -> (PENDING) -> EXCLUSIVE
1066** PENDING -> EXCLUSIVE
1067**
drh9c06c952005-11-26 00:25:00 +00001068** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +00001069** erases all locks at once and returns us immediately to locking level 0.
1070** It is not possible to lower the locking level one step at a time. You
1071** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +00001072*/
drh9c06c952005-11-26 00:25:00 +00001073static int winLock(OsFile *id, int locktype){
drh51c6d962004-06-06 00:42:25 +00001074 int rc = SQLITE_OK; /* Return code from subroutines */
1075 int res = 1; /* Result of a windows lock call */
drhe54ca3f2004-06-07 01:52:14 +00001076 int newLocktype; /* Set id->locktype to this value before exiting */
1077 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +00001078 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +00001079
drh054889e2005-11-30 03:20:31 +00001080 assert( pFile!=0 );
drhe54ca3f2004-06-07 01:52:14 +00001081 TRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +00001082 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +00001083
1084 /* If there is already a lock of this type or more restrictive on the
1085 ** OsFile, do nothing. Don't use the end_lock: exit path, as
1086 ** sqlite3OsEnterMutex() hasn't been called yet.
1087 */
drh054889e2005-11-30 03:20:31 +00001088 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +00001089 return SQLITE_OK;
1090 }
1091
drhb3e04342004-06-08 00:47:47 +00001092 /* Make sure the locking sequence is correct
1093 */
drh054889e2005-11-30 03:20:31 +00001094 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +00001095 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +00001096 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +00001097
drh51c6d962004-06-06 00:42:25 +00001098 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
1099 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
1100 ** the PENDING_LOCK byte is temporary.
1101 */
drh054889e2005-11-30 03:20:31 +00001102 newLocktype = pFile->locktype;
1103 if( pFile->locktype==NO_LOCK
1104 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +00001105 ){
drhb3e04342004-06-08 00:47:47 +00001106 int cnt = 3;
drh054889e2005-11-30 03:20:31 +00001107 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +00001108 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +00001109 ** held by another reader process who will release it momentarily.
1110 */
drhe54ca3f2004-06-07 01:52:14 +00001111 TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +00001112 Sleep(1);
1113 }
drhe54ca3f2004-06-07 01:52:14 +00001114 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +00001115 }
1116
1117 /* Acquire a shared lock
1118 */
drhb3e04342004-06-08 00:47:47 +00001119 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001120 assert( pFile->locktype==NO_LOCK );
1121 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +00001122 if( res ){
1123 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +00001124 }
1125 }
1126
1127 /* Acquire a RESERVED lock
1128 */
drhb3e04342004-06-08 00:47:47 +00001129 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001130 assert( pFile->locktype==SHARED_LOCK );
1131 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +00001132 if( res ){
1133 newLocktype = RESERVED_LOCK;
1134 }
1135 }
1136
1137 /* Acquire a PENDING lock
1138 */
drhb3e04342004-06-08 00:47:47 +00001139 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +00001140 newLocktype = PENDING_LOCK;
1141 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +00001142 }
1143
1144 /* Acquire an EXCLUSIVE lock
1145 */
drhe54ca3f2004-06-07 01:52:14 +00001146 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +00001147 assert( pFile->locktype>=SHARED_LOCK );
1148 res = unlockReadLock(pFile);
drhb3e04342004-06-08 00:47:47 +00001149 TRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +00001150 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +00001151 if( res ){
1152 newLocktype = EXCLUSIVE_LOCK;
1153 }else{
1154 TRACE2("error-code = %d\n", GetLastError());
1155 }
1156 }
1157
1158 /* If we are holding a PENDING lock that ought to be released, then
1159 ** release it now.
1160 */
drhb3e04342004-06-08 00:47:47 +00001161 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001162 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001163 }
1164
1165 /* Update the state of the lock has held in the file descriptor then
1166 ** return the appropriate result code.
1167 */
1168 if( res ){
drh51c6d962004-06-06 00:42:25 +00001169 rc = SQLITE_OK;
1170 }else{
drh054889e2005-11-30 03:20:31 +00001171 TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +00001172 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +00001173 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +00001174 }
drh054889e2005-11-30 03:20:31 +00001175 pFile->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +00001176 return rc;
1177}
1178
1179/*
drh51c6d962004-06-06 00:42:25 +00001180** This routine checks if there is a RESERVED lock held on the specified
1181** file by this or any other process. If such a lock is held, return
1182** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +00001183*/
drh9c06c952005-11-26 00:25:00 +00001184static int winCheckReservedLock(OsFile *id){
drhbbd42a62004-05-22 17:41:58 +00001185 int rc;
drh054889e2005-11-30 03:20:31 +00001186 winFile *pFile = (winFile*)id;
1187 assert( pFile!=0 );
1188 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +00001189 rc = 1;
drh054889e2005-11-30 03:20:31 +00001190 TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001191 }else{
drh054889e2005-11-30 03:20:31 +00001192 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001193 if( rc ){
drh054889e2005-11-30 03:20:31 +00001194 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +00001195 }
drh2ac3ee92004-06-07 16:27:46 +00001196 rc = !rc;
drh054889e2005-11-30 03:20:31 +00001197 TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +00001198 }
drh2ac3ee92004-06-07 16:27:46 +00001199 return rc;
drhbbd42a62004-05-22 17:41:58 +00001200}
1201
1202/*
drha6abd042004-06-09 17:37:22 +00001203** Lower the locking level on file descriptor id to locktype. locktype
1204** must be either NO_LOCK or SHARED_LOCK.
1205**
1206** If the locking level of the file descriptor is already at or below
1207** the requested locking level, this routine is a no-op.
1208**
drh9c105bb2004-10-02 20:38:28 +00001209** It is not possible for this routine to fail if the second argument
1210** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
1211** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +00001212*/
drh9c06c952005-11-26 00:25:00 +00001213static int winUnlock(OsFile *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +00001214 int type;
1215 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +00001216 winFile *pFile = (winFile*)id;
1217 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +00001218 assert( locktype<=SHARED_LOCK );
drh054889e2005-11-30 03:20:31 +00001219 TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
1220 pFile->locktype, pFile->sharedLockByte);
1221 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +00001222 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +00001223 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
1224 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +00001225 /* This should never happen. We should always be able to
1226 ** reacquire the read lock */
1227 rc = SQLITE_IOERR;
1228 }
drhbbd42a62004-05-22 17:41:58 +00001229 }
drhe54ca3f2004-06-07 01:52:14 +00001230 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001231 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +00001232 }
drh9c105bb2004-10-02 20:38:28 +00001233 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +00001234 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +00001235 }
drhb3e04342004-06-08 00:47:47 +00001236 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +00001237 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +00001238 }
drh054889e2005-11-30 03:20:31 +00001239 pFile->locktype = locktype;
drh9c105bb2004-10-02 20:38:28 +00001240 return rc;
drhbbd42a62004-05-22 17:41:58 +00001241}
1242
1243/*
drh0ccebe72005-06-07 22:22:50 +00001244** Turn a relative pathname into a full pathname. Return a pointer
1245** to the full pathname stored in space obtained from sqliteMalloc().
1246** The calling function is responsible for freeing this space once it
1247** is no longer needed.
1248*/
drh66560ad2006-01-06 14:32:19 +00001249char *sqlite3WinFullPathname(const char *zRelative){
drh0ccebe72005-06-07 22:22:50 +00001250 char *zFull;
drhcc78fea2006-01-06 16:17:05 +00001251#if defined(__CYGWIN__)
drh0ccebe72005-06-07 22:22:50 +00001252 int nByte;
drh0ccebe72005-06-07 22:22:50 +00001253 nByte = strlen(zRelative) + MAX_PATH + 1001;
1254 zFull = sqliteMalloc( nByte );
1255 if( zFull==0 ) return 0;
1256 if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
drhcc78fea2006-01-06 16:17:05 +00001257#elif OS_WINCE
1258 /* WinCE has no concept of a relative pathname, or so I am told. */
danielk1977e7259292006-01-13 06:33:23 +00001259 zFull = sqliteStrDup(zRelative);
drh0ccebe72005-06-07 22:22:50 +00001260#else
drhcc78fea2006-01-06 16:17:05 +00001261 char *zNotUsed;
1262 WCHAR *zWide;
1263 int nByte;
drhc0929982005-09-05 19:08:29 +00001264 zWide = utf8ToUnicode(zRelative);
1265 if( zWide ){
1266 WCHAR *zTemp, *zNotUsedW;
1267 nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
1268 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
1269 if( zTemp==0 ) return 0;
1270 GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
1271 sqliteFree(zWide);
1272 zFull = unicodeToUtf8(zTemp);
1273 sqliteFree(zTemp);
1274 }else{
1275 nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
1276 zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
1277 if( zFull==0 ) return 0;
1278 GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
1279 }
drh0ccebe72005-06-07 22:22:50 +00001280#endif
1281 return zFull;
1282}
1283
drh9c06c952005-11-26 00:25:00 +00001284/*
drh9cbe6352005-11-29 03:13:21 +00001285** The fullSync option is meaningless on windows. This is a no-op.
drh18839212005-11-26 03:43:23 +00001286*/
drh9cbe6352005-11-29 03:13:21 +00001287static void winSetFullSync(OsFile *id, int v){
1288 return;
1289}
1290
1291/*
1292** Return the underlying file handle for an OsFile
1293*/
1294static int winFileHandle(OsFile *id){
drh054889e2005-11-30 03:20:31 +00001295 return (int)((winFile*)id)->h;
drh9cbe6352005-11-29 03:13:21 +00001296}
1297
1298/*
1299** Return an integer that indices the type of lock currently held
1300** by this handle. (Used for testing and analysis only.)
1301*/
1302static int winLockState(OsFile *id){
drh054889e2005-11-30 03:20:31 +00001303 return ((winFile*)id)->locktype;
drh18839212005-11-26 03:43:23 +00001304}
1305
drh18839212005-11-26 03:43:23 +00001306/*
drh054889e2005-11-30 03:20:31 +00001307** This vector defines all the methods that can operate on an OsFile
1308** for win32.
drh9c06c952005-11-26 00:25:00 +00001309*/
drh054889e2005-11-30 03:20:31 +00001310static const IoMethod sqlite3WinIoMethod = {
drh9c06c952005-11-26 00:25:00 +00001311 winClose,
drh054889e2005-11-30 03:20:31 +00001312 winOpenDirectory,
drh9c06c952005-11-26 00:25:00 +00001313 winRead,
1314 winWrite,
1315 winSeek,
drh9c06c952005-11-26 00:25:00 +00001316 winTruncate,
drh054889e2005-11-30 03:20:31 +00001317 winSync,
drh9cbe6352005-11-29 03:13:21 +00001318 winSetFullSync,
1319 winFileHandle,
drh054889e2005-11-30 03:20:31 +00001320 winFileSize,
1321 winLock,
1322 winUnlock,
drh9cbe6352005-11-29 03:13:21 +00001323 winLockState,
drh054889e2005-11-30 03:20:31 +00001324 winCheckReservedLock,
drh9c06c952005-11-26 00:25:00 +00001325};
1326
drh054889e2005-11-30 03:20:31 +00001327/*
1328** Allocate memory for an OsFile. Initialize the new OsFile
1329** to the value given in pInit and return a pointer to the new
1330** OsFile. If we run out of memory, close the file and return NULL.
1331*/
danielk1977f0113002006-01-24 12:09:17 +00001332static int allocateWinFile(winFile *pInit, OsFile **pId){
drh054889e2005-11-30 03:20:31 +00001333 winFile *pNew;
1334 pNew = sqliteMalloc( sizeof(*pNew) );
1335 if( pNew==0 ){
1336 CloseHandle(pInit->h);
drhcc78fea2006-01-06 16:17:05 +00001337#if OS_WINCE
1338 sqliteFree(pInit->zDeleteOnClose);
1339#endif
drh054889e2005-11-30 03:20:31 +00001340 *pId = 0;
1341 return SQLITE_NOMEM;
1342 }else{
1343 *pNew = *pInit;
1344 pNew->pMethod = &sqlite3WinIoMethod;
drhbe1f84c2006-01-23 16:25:22 +00001345 pNew->locktype = NO_LOCK;
1346 pNew->sharedLockByte = 0;
drh66560ad2006-01-06 14:32:19 +00001347 *pId = (OsFile*)pNew;
drhbe1f84c2006-01-23 16:25:22 +00001348 OpenCounter(+1);
drh054889e2005-11-30 03:20:31 +00001349 return SQLITE_OK;
1350 }
1351}
1352
1353
drh0ccebe72005-06-07 22:22:50 +00001354#endif /* SQLITE_OMIT_DISKIO */
1355/***************************************************************************
1356** Everything above deals with file I/O. Everything that follows deals
1357** with other miscellanous aspects of the operating system interface
1358****************************************************************************/
1359
1360/*
drhbbd42a62004-05-22 17:41:58 +00001361** Get information to seed the random number generator. The seed
1362** is written into the buffer zBuf[256]. The calling function must
1363** supply a sufficiently large buffer.
1364*/
drh66560ad2006-01-06 14:32:19 +00001365int sqlite3WinRandomSeed(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +00001366 /* We have to initialize zBuf to prevent valgrind from reporting
1367 ** errors. The reports issued by valgrind are incorrect - we would
1368 ** prefer that the randomness be increased by making use of the
1369 ** uninitialized space in zBuf - but valgrind errors tend to worry
1370 ** some users. Rather than argue, it seems easier just to initialize
1371 ** the whole array and silence valgrind, even if that means less randomness
1372 ** in the random seed.
1373 **
1374 ** When testing, initializing zBuf[] to zero is all we do. That means
1375 ** that we always use the same random number sequence.* This makes the
1376 ** tests repeatable.
1377 */
1378 memset(zBuf, 0, 256);
1379 GetSystemTime((LPSYSTEMTIME)zBuf);
1380 return SQLITE_OK;
1381}
1382
1383/*
1384** Sleep for a little while. Return the amount of time slept.
1385*/
drh66560ad2006-01-06 14:32:19 +00001386int sqlite3WinSleep(int ms){
drhbbd42a62004-05-22 17:41:58 +00001387 Sleep(ms);
1388 return ms;
1389}
1390
1391/*
1392** Static variables used for thread synchronization
1393*/
1394static int inMutex = 0;
1395#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001396 static DWORD mutexOwner;
drhbbd42a62004-05-22 17:41:58 +00001397 static CRITICAL_SECTION cs;
1398#endif
1399
1400/*
drh757b04e2006-01-18 17:25:45 +00001401** The following pair of routines implement mutual exclusion for
drhbbd42a62004-05-22 17:41:58 +00001402** multi-threaded processes. Only a single thread is allowed to
1403** executed code that is surrounded by EnterMutex() and LeaveMutex().
1404**
1405** SQLite uses only a single Mutex. There is not much critical
1406** code and what little there is executes quickly and without blocking.
drh757b04e2006-01-18 17:25:45 +00001407**
1408** Version 3.3.1 and earlier used a simple mutex. Beginning with
1409** version 3.3.2, a recursive mutex is required.
drhbbd42a62004-05-22 17:41:58 +00001410*/
drh66560ad2006-01-06 14:32:19 +00001411void sqlite3WinEnterMutex(){
drhbbd42a62004-05-22 17:41:58 +00001412#ifdef SQLITE_W32_THREADS
1413 static int isInit = 0;
1414 while( !isInit ){
1415 static long lock = 0;
1416 if( InterlockedIncrement(&lock)==1 ){
1417 InitializeCriticalSection(&cs);
1418 isInit = 1;
1419 }else{
1420 Sleep(1);
1421 }
1422 }
1423 EnterCriticalSection(&cs);
drh757b04e2006-01-18 17:25:45 +00001424 mutexOwner = GetCurrentThreadId();
drhbbd42a62004-05-22 17:41:58 +00001425#endif
drh332b1fe2006-01-18 14:20:17 +00001426 inMutex++;
drhbbd42a62004-05-22 17:41:58 +00001427}
drh66560ad2006-01-06 14:32:19 +00001428void sqlite3WinLeaveMutex(){
drhbbd42a62004-05-22 17:41:58 +00001429 assert( inMutex );
drh332b1fe2006-01-18 14:20:17 +00001430 inMutex--;
drhbbd42a62004-05-22 17:41:58 +00001431#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001432 assert( mutexOwner==GetCurrentThreadId() );
drhbbd42a62004-05-22 17:41:58 +00001433 LeaveCriticalSection(&cs);
1434#endif
1435}
1436
1437/*
drh757b04e2006-01-18 17:25:45 +00001438** Return TRUE if the mutex is currently held.
1439**
1440** If the thisThreadOnly parameter is true, return true if and only if the
1441** calling thread holds the mutex. If the parameter is false, return
1442** true if any thread holds the mutex.
drh88f474a2006-01-02 20:00:12 +00001443*/
drh757b04e2006-01-18 17:25:45 +00001444int sqlite3WinInMutex(int thisThreadOnly){
drh332b1fe2006-01-18 14:20:17 +00001445#ifdef SQLITE_W32_THREADS
drh757b04e2006-01-18 17:25:45 +00001446 return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId());
drh332b1fe2006-01-18 14:20:17 +00001447#else
drh757b04e2006-01-18 17:25:45 +00001448 return inMutex>0;
drh332b1fe2006-01-18 14:20:17 +00001449#endif
drh88f474a2006-01-02 20:00:12 +00001450}
1451
1452
1453/*
drhbbd42a62004-05-22 17:41:58 +00001454** The following variable, if set to a non-zero value, becomes the result
1455** returned from sqlite3OsCurrentTime(). This is used for testing.
1456*/
1457#ifdef SQLITE_TEST
1458int sqlite3_current_time = 0;
1459#endif
1460
1461/*
1462** Find the current time (in Universal Coordinated Time). Write the
1463** current time and date as a Julian Day number into *prNow and
1464** return 0. Return 1 if the time and date cannot be found.
1465*/
drh66560ad2006-01-06 14:32:19 +00001466int sqlite3WinCurrentTime(double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001467 FILETIME ft;
1468 /* FILETIME structure is a 64-bit value representing the number of
1469 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1470 */
1471 double now;
drhcc78fea2006-01-06 16:17:05 +00001472#if OS_WINCE
1473 SYSTEMTIME time;
1474 GetSystemTime(&time);
1475 SystemTimeToFileTime(&time,&ft);
1476#else
drhbbd42a62004-05-22 17:41:58 +00001477 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001478#endif
drhbbd42a62004-05-22 17:41:58 +00001479 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1480 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1481#ifdef SQLITE_TEST
1482 if( sqlite3_current_time ){
1483 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1484 }
1485#endif
1486 return 0;
1487}
1488
drh6f7adc82006-01-11 21:41:20 +00001489/*
drhb4bc7052006-01-11 23:40:33 +00001490** Remember the number of thread-specific-data blocks allocated.
1491** Use this to verify that we are not leaking thread-specific-data.
1492** Ticket #1601
1493*/
1494#ifdef SQLITE_TEST
1495int sqlite3_tsd_count = 0;
1496# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
1497# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
1498#else
1499# define TSD_COUNTER_INCR /* no-op */
1500# define TSD_COUNTER_DECR /* no-op */
1501#endif
1502
1503
1504
1505/*
drh70ff98a2006-01-12 01:25:18 +00001506** If called with allocateFlag>1, then return a pointer to thread
drh6f7adc82006-01-11 21:41:20 +00001507** specific data for the current thread. Allocate and zero the
1508** thread-specific data if it does not already exist necessary.
drh3fbb0b12006-01-06 00:36:00 +00001509**
drh6f7adc82006-01-11 21:41:20 +00001510** If called with allocateFlag==0, then check the current thread
drh70ff98a2006-01-12 01:25:18 +00001511** specific data. Return it if it exists. If it does not exist,
1512** then return NULL.
1513**
1514** If called with allocateFlag<0, check to see if the thread specific
1515** data is allocated and is all zero. If it is then deallocate it.
drh6f7adc82006-01-11 21:41:20 +00001516** Return a pointer to the thread specific data or NULL if it is
drh70ff98a2006-01-12 01:25:18 +00001517** unallocated or gets deallocated.
danielk197713a68c32005-12-15 10:11:30 +00001518*/
drhb4bc7052006-01-11 23:40:33 +00001519ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
drh3fbb0b12006-01-06 00:36:00 +00001520 static int key;
1521 static int keyInit = 0;
drh0850b532006-01-31 19:31:43 +00001522 static const ThreadData zeroData = {0};
drhb4bc7052006-01-11 23:40:33 +00001523 ThreadData *pTsd;
drh3fbb0b12006-01-06 00:36:00 +00001524
1525 if( !keyInit ){
drh66560ad2006-01-06 14:32:19 +00001526 sqlite3OsEnterMutex();
drh3fbb0b12006-01-06 00:36:00 +00001527 if( !keyInit ){
1528 key = TlsAlloc();
1529 if( key==0xffffffff ){
drh66560ad2006-01-06 14:32:19 +00001530 sqlite3OsLeaveMutex();
drh3fbb0b12006-01-06 00:36:00 +00001531 return 0;
1532 }
1533 keyInit = 1;
1534 }
drh66560ad2006-01-06 14:32:19 +00001535 sqlite3OsLeaveMutex();
danielk197713a68c32005-12-15 10:11:30 +00001536 }
drh3fbb0b12006-01-06 00:36:00 +00001537 pTsd = TlsGetValue(key);
drh70ff98a2006-01-12 01:25:18 +00001538 if( allocateFlag>0 ){
drh6f7adc82006-01-11 21:41:20 +00001539 if( !pTsd ){
drhb4bc7052006-01-11 23:40:33 +00001540 pTsd = sqlite3OsMalloc( sizeof(zeroData) );
drh6f7adc82006-01-11 21:41:20 +00001541 if( pTsd ){
1542 *pTsd = zeroData;
1543 TlsSetValue(key, pTsd);
drhb4bc7052006-01-11 23:40:33 +00001544 TSD_COUNTER_INCR;
drh6f7adc82006-01-11 21:41:20 +00001545 }
drh3fbb0b12006-01-06 00:36:00 +00001546 }
drh70ff98a2006-01-12 01:25:18 +00001547 }else if( pTsd!=0 && allocateFlag<0
danielk19779e128002006-01-18 16:51:35 +00001548 && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
drh6f7adc82006-01-11 21:41:20 +00001549 sqlite3OsFree(pTsd);
1550 TlsSetValue(key, 0);
drhb4bc7052006-01-11 23:40:33 +00001551 TSD_COUNTER_DECR;
drh6f7adc82006-01-11 21:41:20 +00001552 pTsd = 0;
drh3fbb0b12006-01-06 00:36:00 +00001553 }
1554 return pTsd;
danielk197713a68c32005-12-15 10:11:30 +00001555}
drhbbd42a62004-05-22 17:41:58 +00001556#endif /* OS_WIN */