|
1 /* |
|
2 ** 2004 May 22 |
|
3 ** |
|
4 ** The author disclaims copyright to this source code. In place of |
|
5 ** a legal notice, here is a blessing: |
|
6 ** |
|
7 ** May you do good and not evil. |
|
8 ** May you find forgiveness for yourself and forgive others. |
|
9 ** May you share freely, never taking more than you give. |
|
10 ** |
|
11 ****************************************************************************** |
|
12 ** |
|
13 ** This file contains code that is specific to windows. |
|
14 */ |
|
15 #include "sqliteInt.h" |
|
16 #include "os.h" |
|
17 #if OS_WIN /* This file is used for windows only */ |
|
18 |
|
19 #include <winbase.h> |
|
20 |
|
21 #ifdef __CYGWIN__ |
|
22 # include <sys/cygwin.h> |
|
23 #endif |
|
24 |
|
25 /* |
|
26 ** Macros used to determine whether or not to use threads. |
|
27 */ |
|
28 #if defined(THREADSAFE) && THREADSAFE |
|
29 # define SQLITE_W32_THREADS 1 |
|
30 #endif |
|
31 |
|
32 /* |
|
33 ** Include code that is common to all os_*.c files |
|
34 */ |
|
35 #include "os_common.h" |
|
36 |
|
37 /* |
|
38 ** Determine if we are dealing with WindowsCE - which has a much |
|
39 ** reduced API. |
|
40 */ |
|
41 #if defined(_WIN32_WCE) |
|
42 # define OS_WINCE 1 |
|
43 #else |
|
44 # define OS_WINCE 0 |
|
45 #endif |
|
46 |
|
47 /* |
|
48 ** 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 |
|
52 typedef 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 /* |
|
61 ** The winFile structure is a subclass of OsFile specific to the win32 |
|
62 ** portability layer. |
|
63 */ |
|
64 typedef struct winFile winFile; |
|
65 struct winFile { |
|
66 IoMethod const *pMethod;/* Must be first */ |
|
67 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 */ |
|
70 #if OS_WINCE |
|
71 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 */ |
|
76 #endif |
|
77 }; |
|
78 |
|
79 |
|
80 /* |
|
81 ** 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 /* |
|
88 ** 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 */ |
|
99 int sqlite3_os_type = 0; |
|
100 |
|
101 /* |
|
102 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, |
|
103 ** or WinCE. Return false (zero) for Win95, Win98, or WinME. |
|
104 ** |
|
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 */ |
|
112 #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; |
|
123 } |
|
124 #endif /* OS_WINCE */ |
|
125 |
|
126 /* |
|
127 ** Convert a UTF-8 string to UTF-32. Space to hold the returned string |
|
128 ** is obtained from sqliteMalloc. |
|
129 */ |
|
130 static WCHAR *utf8ToUnicode(const char *zFilename){ |
|
131 int nChar; |
|
132 WCHAR *zWideFilename; |
|
133 |
|
134 if( !isNT() ){ |
|
135 return 0; |
|
136 } |
|
137 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
|
138 zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) ); |
|
139 if( zWideFilename==0 ){ |
|
140 return 0; |
|
141 } |
|
142 nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); |
|
143 if( nChar==0 ){ |
|
144 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 */ |
|
154 static 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 |
|
172 #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> |
|
181 struct 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 */ |
|
215 static 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 */ |
|
230 static 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 */ |
|
303 static 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 */ |
|
337 static 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 */ |
|
398 static 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 */ |
|
456 static 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 */ |
|
477 |
|
478 /* |
|
479 ** 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. |
|
489 */ |
|
490 #define MX_DELETION_ATTEMPTS 3 |
|
491 int sqlite3WinDelete(const char *zFilename){ |
|
492 WCHAR *zWide = utf8ToUnicode(zFilename); |
|
493 int cnt = 0; |
|
494 int rc; |
|
495 if( zWide ){ |
|
496 do{ |
|
497 rc = DeleteFileW(zWide); |
|
498 }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); |
|
499 sqliteFree(zWide); |
|
500 }else{ |
|
501 #if OS_WINCE |
|
502 return SQLITE_NOMEM; |
|
503 #else |
|
504 do{ |
|
505 rc = DeleteFileA(zFilename); |
|
506 }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); |
|
507 #endif |
|
508 } |
|
509 TRACE2("DELETE \"%s\"\n", zFilename); |
|
510 return rc==0 ? SQLITE_OK : SQLITE_IOERR; |
|
511 } |
|
512 |
|
513 /* |
|
514 ** Return TRUE if the named file exists. |
|
515 */ |
|
516 int sqlite3WinFileExists(const char *zFilename){ |
|
517 int exists = 0; |
|
518 WCHAR *zWide = utf8ToUnicode(zFilename); |
|
519 if( zWide ){ |
|
520 exists = GetFileAttributesW(zWide) != 0xffffffff; |
|
521 sqliteFree(zWide); |
|
522 }else{ |
|
523 #if OS_WINCE |
|
524 return SQLITE_NOMEM; |
|
525 #else |
|
526 exists = GetFileAttributesA(zFilename) != 0xffffffff; |
|
527 #endif |
|
528 } |
|
529 return exists; |
|
530 } |
|
531 |
|
532 /* Forward declaration */ |
|
533 static int allocateWinFile(winFile *pInit, OsFile **pId); |
|
534 |
|
535 /* |
|
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 */ |
|
548 int sqlite3WinOpenReadWrite( |
|
549 const char *zFilename, |
|
550 OsFile **pId, |
|
551 int *pReadonly |
|
552 ){ |
|
553 winFile f; |
|
554 HANDLE h; |
|
555 WCHAR *zWide = utf8ToUnicode(zFilename); |
|
556 assert( *pId==0 ); |
|
557 if( zWide ){ |
|
558 h = CreateFileW(zWide, |
|
559 GENERIC_READ | GENERIC_WRITE, |
|
560 FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
561 NULL, |
|
562 OPEN_ALWAYS, |
|
563 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, |
|
564 NULL |
|
565 ); |
|
566 if( h==INVALID_HANDLE_VALUE ){ |
|
567 h = CreateFileW(zWide, |
|
568 GENERIC_READ, |
|
569 FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
570 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; |
|
582 } |
|
583 #if OS_WINCE |
|
584 if (!winceCreateLock(zFilename, &f)){ |
|
585 CloseHandle(h); |
|
586 sqliteFree(zWide); |
|
587 return SQLITE_CANTOPEN; |
|
588 } |
|
589 #endif |
|
590 sqliteFree(zWide); |
|
591 }else{ |
|
592 #if OS_WINCE |
|
593 return SQLITE_NOMEM; |
|
594 #else |
|
595 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, |
|
606 FILE_SHARE_READ | FILE_SHARE_WRITE, |
|
607 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 } |
|
619 #endif /* OS_WINCE */ |
|
620 } |
|
621 f.h = h; |
|
622 #if OS_WINCE |
|
623 f.zDeleteOnClose = 0; |
|
624 #endif |
|
625 TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename); |
|
626 return allocateWinFile(&f, pId); |
|
627 } |
|
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. |
|
643 ** |
|
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. |
|
649 */ |
|
650 int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ |
|
651 winFile f; |
|
652 HANDLE h; |
|
653 int fileflags; |
|
654 WCHAR *zWide = utf8ToUnicode(zFilename); |
|
655 assert( *pId == 0 ); |
|
656 fileflags = FILE_FLAG_RANDOM_ACCESS; |
|
657 #if !OS_WINCE |
|
658 if( delFlag ){ |
|
659 fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE; |
|
660 } |
|
661 #endif |
|
662 if( zWide ){ |
|
663 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) ); |
|
674 sqliteFree(zWide); |
|
675 }else{ |
|
676 #if OS_WINCE |
|
677 return SQLITE_NOMEM; |
|
678 #else |
|
679 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) ); |
|
690 #endif /* OS_WINCE */ |
|
691 } |
|
692 if( h==INVALID_HANDLE_VALUE ){ |
|
693 return SQLITE_CANTOPEN; |
|
694 } |
|
695 f.h = h; |
|
696 #if OS_WINCE |
|
697 f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0; |
|
698 f.hMutex = NULL; |
|
699 #endif |
|
700 TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); |
|
701 return allocateWinFile(&f, pId); |
|
702 } |
|
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 */ |
|
711 int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ |
|
712 winFile f; |
|
713 HANDLE h; |
|
714 WCHAR *zWide = utf8ToUnicode(zFilename); |
|
715 assert( *pId==0 ); |
|
716 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{ |
|
727 #if OS_WINCE |
|
728 return SQLITE_NOMEM; |
|
729 #else |
|
730 h = CreateFileA(zFilename, |
|
731 GENERIC_READ, |
|
732 0, |
|
733 NULL, |
|
734 OPEN_EXISTING, |
|
735 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, |
|
736 NULL |
|
737 ); |
|
738 #endif |
|
739 } |
|
740 if( h==INVALID_HANDLE_VALUE ){ |
|
741 return SQLITE_CANTOPEN; |
|
742 } |
|
743 f.h = h; |
|
744 #if OS_WINCE |
|
745 f.zDeleteOnClose = 0; |
|
746 f.hMutex = NULL; |
|
747 #endif |
|
748 TRACE3("OPEN RO %d \"%s\"\n", h, zFilename); |
|
749 return allocateWinFile(&f, pId); |
|
750 } |
|
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 */ |
|
768 static int winOpenDirectory( |
|
769 OsFile *id, |
|
770 const char *zDirname |
|
771 ){ |
|
772 return SQLITE_OK; |
|
773 } |
|
774 |
|
775 /* |
|
776 ** 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 */ |
|
780 char *sqlite3_temp_directory = 0; |
|
781 |
|
782 /* |
|
783 ** Create a temporary file name in zBuf. zBuf must be big enough to |
|
784 ** hold at least SQLITE_TEMPNAME_SIZE characters. |
|
785 */ |
|
786 int sqlite3WinTempFileName(char *zBuf){ |
|
787 static char zChars[] = |
|
788 "abcdefghijklmnopqrstuvwxyz" |
|
789 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
|
790 "0123456789"; |
|
791 int i, j; |
|
792 char zTempPath[SQLITE_TEMPNAME_SIZE]; |
|
793 if( sqlite3_temp_directory ){ |
|
794 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30); |
|
795 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; |
|
796 }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 ){ |
|
802 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30); |
|
803 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0; |
|
804 sqliteFree(zMulti); |
|
805 } |
|
806 }else{ |
|
807 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath); |
|
808 } |
|
809 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; |
|
819 if( !sqlite3OsFileExists(zBuf) ) break; |
|
820 } |
|
821 TRACE2("TEMP FILENAME: %s\n", zBuf); |
|
822 return SQLITE_OK; |
|
823 } |
|
824 |
|
825 /* |
|
826 ** Close a file. |
|
827 ** |
|
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. |
|
834 */ |
|
835 #define MX_CLOSE_ATTEMPT 3 |
|
836 static int winClose(OsFile **pId){ |
|
837 winFile *pFile; |
|
838 int rc = 1; |
|
839 if( pId && (pFile = (winFile*)*pId)!=0 ){ |
|
840 int rc, cnt = 0; |
|
841 TRACE2("CLOSE %d\n", pFile->h); |
|
842 do{ |
|
843 rc = CloseHandle(pFile->h); |
|
844 }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); |
|
845 #if OS_WINCE |
|
846 winceDestroyLock(pFile); |
|
847 if( pFile->zDeleteOnClose ){ |
|
848 DeleteFileW(pFile->zDeleteOnClose); |
|
849 sqliteFree(pFile->zDeleteOnClose); |
|
850 } |
|
851 #endif |
|
852 OpenCounter(-1); |
|
853 sqliteFree(pFile); |
|
854 *pId = 0; |
|
855 } |
|
856 return rc ? SQLITE_OK : SQLITE_IOERR; |
|
857 } |
|
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 */ |
|
864 static int winRead(OsFile *id, void *pBuf, int amt){ |
|
865 DWORD got; |
|
866 assert( id!=0 ); |
|
867 SimulateIOError(SQLITE_IOERR); |
|
868 TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); |
|
869 if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){ |
|
870 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 */ |
|
883 static int winWrite(OsFile *id, const void *pBuf, int amt){ |
|
884 int rc = 0; |
|
885 DWORD wrote; |
|
886 assert( id!=0 ); |
|
887 SimulateIOError(SQLITE_IOERR); |
|
888 SimulateDiskfullError; |
|
889 TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); |
|
890 assert( amt>0 ); |
|
891 while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0 |
|
892 && wrote>0 ){ |
|
893 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 /* |
|
903 ** 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 /* |
|
910 ** Move the read/write pointer in a file. |
|
911 */ |
|
912 static int winSeek(OsFile *id, i64 offset){ |
|
913 LONG upperBits = offset>>32; |
|
914 LONG lowerBits = offset & 0xffffffff; |
|
915 DWORD rc; |
|
916 assert( id!=0 ); |
|
917 #ifdef SQLITE_TEST |
|
918 if( offset ) SimulateDiskfullError |
|
919 #endif |
|
920 SEEK(offset/1024 + 1); |
|
921 rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN); |
|
922 TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset); |
|
923 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ |
|
924 return SQLITE_FULL; |
|
925 } |
|
926 return SQLITE_OK; |
|
927 } |
|
928 |
|
929 /* |
|
930 ** Make sure all writes to a particular file are committed to disk. |
|
931 */ |
|
932 static int winSync(OsFile *id, int dataOnly){ |
|
933 assert( id!=0 ); |
|
934 TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype); |
|
935 if( FlushFileBuffers(((winFile*)id)->h) ){ |
|
936 return SQLITE_OK; |
|
937 }else{ |
|
938 return SQLITE_IOERR; |
|
939 } |
|
940 } |
|
941 |
|
942 /* |
|
943 ** Sync the directory zDirname. This is a no-op on operating systems other |
|
944 ** than UNIX. |
|
945 */ |
|
946 int sqlite3WinSyncDirectory(const char *zDirname){ |
|
947 SimulateIOError(SQLITE_IOERR); |
|
948 return SQLITE_OK; |
|
949 } |
|
950 |
|
951 /* |
|
952 ** Truncate an open file to a specified size |
|
953 */ |
|
954 static int winTruncate(OsFile *id, i64 nByte){ |
|
955 LONG upperBits = nByte>>32; |
|
956 assert( id!=0 ); |
|
957 TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte); |
|
958 SimulateIOError(SQLITE_IOERR); |
|
959 SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN); |
|
960 SetEndOfFile(((winFile*)id)->h); |
|
961 return SQLITE_OK; |
|
962 } |
|
963 |
|
964 /* |
|
965 ** Determine the current size of a file in bytes |
|
966 */ |
|
967 static int winFileSize(OsFile *id, i64 *pSize){ |
|
968 DWORD upperBits, lowerBits; |
|
969 assert( id!=0 ); |
|
970 SimulateIOError(SQLITE_IOERR); |
|
971 lowerBits = GetFileSize(((winFile*)id)->h, &upperBits); |
|
972 *pSize = (((i64)upperBits)<<32) + lowerBits; |
|
973 return SQLITE_OK; |
|
974 } |
|
975 |
|
976 /* |
|
977 ** 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 /* |
|
984 ** Acquire a reader lock. |
|
985 ** Different API routines are called depending on whether or not this |
|
986 ** is Win95 or WinNT. |
|
987 */ |
|
988 static int getReadLock(winFile *id){ |
|
989 int res; |
|
990 if( isNT() ){ |
|
991 OVERLAPPED ovlp; |
|
992 ovlp.Offset = SHARED_FIRST; |
|
993 ovlp.OffsetHigh = 0; |
|
994 ovlp.hEvent = 0; |
|
995 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp); |
|
996 }else{ |
|
997 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); |
|
1001 } |
|
1002 return res; |
|
1003 } |
|
1004 |
|
1005 /* |
|
1006 ** Undo a readlock |
|
1007 */ |
|
1008 static int unlockReadLock(winFile *pFile){ |
|
1009 int res; |
|
1010 if( isNT() ){ |
|
1011 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
|
1012 }else{ |
|
1013 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); |
|
1014 } |
|
1015 return res; |
|
1016 } |
|
1017 |
|
1018 #ifndef SQLITE_OMIT_PAGER_PRAGMAS |
|
1019 /* |
|
1020 ** Check that a given pathname is a directory and is writable |
|
1021 ** |
|
1022 */ |
|
1023 int sqlite3WinIsDirWritable(char *zDirname){ |
|
1024 int fileAttr; |
|
1025 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{ |
|
1033 #if OS_WINCE |
|
1034 return 0; |
|
1035 #else |
|
1036 fileAttr = GetFileAttributesA(zDirname); |
|
1037 #endif |
|
1038 } |
|
1039 if( fileAttr == 0xffffffff ) return 0; |
|
1040 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ |
|
1041 return 0; |
|
1042 } |
|
1043 return 1; |
|
1044 } |
|
1045 #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ |
|
1046 |
|
1047 /* |
|
1048 ** 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 ** |
|
1068 ** This routine will only increase a lock. The winUnlock() routine |
|
1069 ** 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. |
|
1072 */ |
|
1073 static int winLock(OsFile *id, int locktype){ |
|
1074 int rc = SQLITE_OK; /* Return code from subroutines */ |
|
1075 int res = 1; /* Result of a windows lock call */ |
|
1076 int newLocktype; /* Set id->locktype to this value before exiting */ |
|
1077 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ |
|
1078 winFile *pFile = (winFile*)id; |
|
1079 |
|
1080 assert( pFile!=0 ); |
|
1081 TRACE5("LOCK %d %d was %d(%d)\n", |
|
1082 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); |
|
1083 |
|
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 */ |
|
1088 if( pFile->locktype>=locktype ){ |
|
1089 return SQLITE_OK; |
|
1090 } |
|
1091 |
|
1092 /* Make sure the locking sequence is correct |
|
1093 */ |
|
1094 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); |
|
1095 assert( locktype!=PENDING_LOCK ); |
|
1096 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); |
|
1097 |
|
1098 /* 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 */ |
|
1102 newLocktype = pFile->locktype; |
|
1103 if( pFile->locktype==NO_LOCK |
|
1104 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) |
|
1105 ){ |
|
1106 int cnt = 3; |
|
1107 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ |
|
1108 /* Try 3 times to get the pending lock. The pending lock might be |
|
1109 ** held by another reader process who will release it momentarily. |
|
1110 */ |
|
1111 TRACE2("could not get a PENDING lock. cnt=%d\n", cnt); |
|
1112 Sleep(1); |
|
1113 } |
|
1114 gotPendingLock = res; |
|
1115 } |
|
1116 |
|
1117 /* Acquire a shared lock |
|
1118 */ |
|
1119 if( locktype==SHARED_LOCK && res ){ |
|
1120 assert( pFile->locktype==NO_LOCK ); |
|
1121 res = getReadLock(pFile); |
|
1122 if( res ){ |
|
1123 newLocktype = SHARED_LOCK; |
|
1124 } |
|
1125 } |
|
1126 |
|
1127 /* Acquire a RESERVED lock |
|
1128 */ |
|
1129 if( locktype==RESERVED_LOCK && res ){ |
|
1130 assert( pFile->locktype==SHARED_LOCK ); |
|
1131 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
|
1132 if( res ){ |
|
1133 newLocktype = RESERVED_LOCK; |
|
1134 } |
|
1135 } |
|
1136 |
|
1137 /* Acquire a PENDING lock |
|
1138 */ |
|
1139 if( locktype==EXCLUSIVE_LOCK && res ){ |
|
1140 newLocktype = PENDING_LOCK; |
|
1141 gotPendingLock = 0; |
|
1142 } |
|
1143 |
|
1144 /* Acquire an EXCLUSIVE lock |
|
1145 */ |
|
1146 if( locktype==EXCLUSIVE_LOCK && res ){ |
|
1147 assert( pFile->locktype>=SHARED_LOCK ); |
|
1148 res = unlockReadLock(pFile); |
|
1149 TRACE2("unreadlock = %d\n", res); |
|
1150 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
|
1151 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 */ |
|
1161 if( gotPendingLock && locktype==SHARED_LOCK ){ |
|
1162 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); |
|
1163 } |
|
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 ){ |
|
1169 rc = SQLITE_OK; |
|
1170 }else{ |
|
1171 TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h, |
|
1172 locktype, newLocktype); |
|
1173 rc = SQLITE_BUSY; |
|
1174 } |
|
1175 pFile->locktype = newLocktype; |
|
1176 return rc; |
|
1177 } |
|
1178 |
|
1179 /* |
|
1180 ** 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. |
|
1183 */ |
|
1184 static int winCheckReservedLock(OsFile *id){ |
|
1185 int rc; |
|
1186 winFile *pFile = (winFile*)id; |
|
1187 assert( pFile!=0 ); |
|
1188 if( pFile->locktype>=RESERVED_LOCK ){ |
|
1189 rc = 1; |
|
1190 TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); |
|
1191 }else{ |
|
1192 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
|
1193 if( rc ){ |
|
1194 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
|
1195 } |
|
1196 rc = !rc; |
|
1197 TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc); |
|
1198 } |
|
1199 return rc; |
|
1200 } |
|
1201 |
|
1202 /* |
|
1203 ** 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 ** |
|
1209 ** 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; |
|
1212 */ |
|
1213 static int winUnlock(OsFile *id, int locktype){ |
|
1214 int type; |
|
1215 int rc = SQLITE_OK; |
|
1216 winFile *pFile = (winFile*)id; |
|
1217 assert( pFile!=0 ); |
|
1218 assert( locktype<=SHARED_LOCK ); |
|
1219 TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, |
|
1220 pFile->locktype, pFile->sharedLockByte); |
|
1221 type = pFile->locktype; |
|
1222 if( type>=EXCLUSIVE_LOCK ){ |
|
1223 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
|
1224 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
|
1225 /* This should never happen. We should always be able to |
|
1226 ** reacquire the read lock */ |
|
1227 rc = SQLITE_IOERR; |
|
1228 } |
|
1229 } |
|
1230 if( type>=RESERVED_LOCK ){ |
|
1231 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); |
|
1232 } |
|
1233 if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
|
1234 unlockReadLock(pFile); |
|
1235 } |
|
1236 if( type>=PENDING_LOCK ){ |
|
1237 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); |
|
1238 } |
|
1239 pFile->locktype = locktype; |
|
1240 return rc; |
|
1241 } |
|
1242 |
|
1243 /* |
|
1244 ** 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 */ |
|
1249 char *sqlite3WinFullPathname(const char *zRelative){ |
|
1250 char *zFull; |
|
1251 #if defined(__CYGWIN__) |
|
1252 int nByte; |
|
1253 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; |
|
1257 #elif OS_WINCE |
|
1258 /* WinCE has no concept of a relative pathname, or so I am told. */ |
|
1259 zFull = sqliteStrDup(zRelative); |
|
1260 #else |
|
1261 char *zNotUsed; |
|
1262 WCHAR *zWide; |
|
1263 int nByte; |
|
1264 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 } |
|
1280 #endif |
|
1281 return zFull; |
|
1282 } |
|
1283 |
|
1284 /* |
|
1285 ** The fullSync option is meaningless on windows. This is a no-op. |
|
1286 */ |
|
1287 static void winSetFullSync(OsFile *id, int v){ |
|
1288 return; |
|
1289 } |
|
1290 |
|
1291 /* |
|
1292 ** Return the underlying file handle for an OsFile |
|
1293 */ |
|
1294 static int winFileHandle(OsFile *id){ |
|
1295 return (int)((winFile*)id)->h; |
|
1296 } |
|
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 */ |
|
1302 static int winLockState(OsFile *id){ |
|
1303 return ((winFile*)id)->locktype; |
|
1304 } |
|
1305 |
|
1306 /* |
|
1307 ** This vector defines all the methods that can operate on an OsFile |
|
1308 ** for win32. |
|
1309 */ |
|
1310 static const IoMethod sqlite3WinIoMethod = { |
|
1311 winClose, |
|
1312 winOpenDirectory, |
|
1313 winRead, |
|
1314 winWrite, |
|
1315 winSeek, |
|
1316 winTruncate, |
|
1317 winSync, |
|
1318 winSetFullSync, |
|
1319 winFileHandle, |
|
1320 winFileSize, |
|
1321 winLock, |
|
1322 winUnlock, |
|
1323 winLockState, |
|
1324 winCheckReservedLock, |
|
1325 }; |
|
1326 |
|
1327 /* |
|
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 */ |
|
1332 static int allocateWinFile(winFile *pInit, OsFile **pId){ |
|
1333 winFile *pNew; |
|
1334 pNew = sqliteMalloc( sizeof(*pNew) ); |
|
1335 if( pNew==0 ){ |
|
1336 CloseHandle(pInit->h); |
|
1337 #if OS_WINCE |
|
1338 sqliteFree(pInit->zDeleteOnClose); |
|
1339 #endif |
|
1340 *pId = 0; |
|
1341 return SQLITE_NOMEM; |
|
1342 }else{ |
|
1343 *pNew = *pInit; |
|
1344 pNew->pMethod = &sqlite3WinIoMethod; |
|
1345 pNew->locktype = NO_LOCK; |
|
1346 pNew->sharedLockByte = 0; |
|
1347 *pId = (OsFile*)pNew; |
|
1348 OpenCounter(+1); |
|
1349 return SQLITE_OK; |
|
1350 } |
|
1351 } |
|
1352 |
|
1353 |
|
1354 #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 /* |
|
1361 ** 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 */ |
|
1365 int sqlite3WinRandomSeed(char *zBuf){ |
|
1366 /* 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 */ |
|
1386 int sqlite3WinSleep(int ms){ |
|
1387 Sleep(ms); |
|
1388 return ms; |
|
1389 } |
|
1390 |
|
1391 /* |
|
1392 ** Static variables used for thread synchronization |
|
1393 */ |
|
1394 static int inMutex = 0; |
|
1395 #ifdef SQLITE_W32_THREADS |
|
1396 static DWORD mutexOwner; |
|
1397 static CRITICAL_SECTION cs; |
|
1398 #endif |
|
1399 |
|
1400 /* |
|
1401 ** The following pair of routines implement mutual exclusion for |
|
1402 ** 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. |
|
1407 ** |
|
1408 ** Version 3.3.1 and earlier used a simple mutex. Beginning with |
|
1409 ** version 3.3.2, a recursive mutex is required. |
|
1410 */ |
|
1411 void sqlite3WinEnterMutex(){ |
|
1412 #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); |
|
1424 mutexOwner = GetCurrentThreadId(); |
|
1425 #endif |
|
1426 inMutex++; |
|
1427 } |
|
1428 void sqlite3WinLeaveMutex(){ |
|
1429 assert( inMutex ); |
|
1430 inMutex--; |
|
1431 #ifdef SQLITE_W32_THREADS |
|
1432 assert( mutexOwner==GetCurrentThreadId() ); |
|
1433 LeaveCriticalSection(&cs); |
|
1434 #endif |
|
1435 } |
|
1436 |
|
1437 /* |
|
1438 ** 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. |
|
1443 */ |
|
1444 int sqlite3WinInMutex(int thisThreadOnly){ |
|
1445 #ifdef SQLITE_W32_THREADS |
|
1446 return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId()); |
|
1447 #else |
|
1448 return inMutex>0; |
|
1449 #endif |
|
1450 } |
|
1451 |
|
1452 |
|
1453 /* |
|
1454 ** 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 |
|
1458 int 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 */ |
|
1466 int sqlite3WinCurrentTime(double *prNow){ |
|
1467 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; |
|
1472 #if OS_WINCE |
|
1473 SYSTEMTIME time; |
|
1474 GetSystemTime(&time); |
|
1475 SystemTimeToFileTime(&time,&ft); |
|
1476 #else |
|
1477 GetSystemTimeAsFileTime( &ft ); |
|
1478 #endif |
|
1479 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 |
|
1489 /* |
|
1490 ** 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 |
|
1495 int 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 /* |
|
1506 ** If called with allocateFlag>1, then return a pointer to thread |
|
1507 ** specific data for the current thread. Allocate and zero the |
|
1508 ** thread-specific data if it does not already exist necessary. |
|
1509 ** |
|
1510 ** If called with allocateFlag==0, then check the current thread |
|
1511 ** 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. |
|
1516 ** Return a pointer to the thread specific data or NULL if it is |
|
1517 ** unallocated or gets deallocated. |
|
1518 */ |
|
1519 ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){ |
|
1520 static int key; |
|
1521 static int keyInit = 0; |
|
1522 static const ThreadData zeroData = {0}; |
|
1523 ThreadData *pTsd; |
|
1524 |
|
1525 if( !keyInit ){ |
|
1526 sqlite3OsEnterMutex(); |
|
1527 if( !keyInit ){ |
|
1528 key = TlsAlloc(); |
|
1529 if( key==0xffffffff ){ |
|
1530 sqlite3OsLeaveMutex(); |
|
1531 return 0; |
|
1532 } |
|
1533 keyInit = 1; |
|
1534 } |
|
1535 sqlite3OsLeaveMutex(); |
|
1536 } |
|
1537 pTsd = TlsGetValue(key); |
|
1538 if( allocateFlag>0 ){ |
|
1539 if( !pTsd ){ |
|
1540 pTsd = sqlite3OsMalloc( sizeof(zeroData) ); |
|
1541 if( pTsd ){ |
|
1542 *pTsd = zeroData; |
|
1543 TlsSetValue(key, pTsd); |
|
1544 TSD_COUNTER_INCR; |
|
1545 } |
|
1546 } |
|
1547 }else if( pTsd!=0 && allocateFlag<0 |
|
1548 && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){ |
|
1549 sqlite3OsFree(pTsd); |
|
1550 TlsSetValue(key, 0); |
|
1551 TSD_COUNTER_DECR; |
|
1552 pTsd = 0; |
|
1553 } |
|
1554 return pTsd; |
|
1555 } |
|
1556 #endif /* OS_WIN */ |