blob: 9a29c2553f8fdd28311e206ae710b74778a55386 [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
21/*
22** Macros used to determine whether or not to use threads.
23*/
24#if defined(THREADSAFE) && THREADSAFE
25# define SQLITE_W32_THREADS 1
26#endif
27
28/*
29** Include code that is common to all os_*.c files
30*/
31#include "os_common.h"
32
33/*
34** Delete the named file
35*/
36int sqlite3OsDelete(const char *zFilename){
drh93d648d2004-06-30 14:28:59 +000037 DeleteFileA(zFilename);
drh51c6d962004-06-06 00:42:25 +000038 TRACE2("DELETE \"%s\"\n", zFilename);
drhbbd42a62004-05-22 17:41:58 +000039 return SQLITE_OK;
40}
41
42/*
43** Return TRUE if the named file exists.
44*/
45int sqlite3OsFileExists(const char *zFilename){
drh93d648d2004-06-30 14:28:59 +000046 return GetFileAttributesA(zFilename) != 0xffffffff;
drhbbd42a62004-05-22 17:41:58 +000047}
48
49/*
50** Attempt to open a file for both reading and writing. If that
51** fails, try opening it read-only. If the file does not exist,
52** try to create it.
53**
54** On success, a handle for the open file is written to *id
55** and *pReadonly is set to 0 if the file was opened for reading and
56** writing or 1 if the file was opened read-only. The function returns
57** SQLITE_OK.
58**
59** On failure, the function returns SQLITE_CANTOPEN and leaves
60** *id and *pReadonly unchanged.
61*/
62int sqlite3OsOpenReadWrite(
63 const char *zFilename,
64 OsFile *id,
65 int *pReadonly
66){
drhda71ce12004-06-21 18:14:45 +000067 HANDLE h;
68 assert( !id->isOpen );
drh93d648d2004-06-30 14:28:59 +000069 h = CreateFileA(zFilename,
drhbbd42a62004-05-22 17:41:58 +000070 GENERIC_READ | GENERIC_WRITE,
71 FILE_SHARE_READ | FILE_SHARE_WRITE,
72 NULL,
73 OPEN_ALWAYS,
74 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
75 NULL
76 );
77 if( h==INVALID_HANDLE_VALUE ){
drh93d648d2004-06-30 14:28:59 +000078 h = CreateFileA(zFilename,
drhbbd42a62004-05-22 17:41:58 +000079 GENERIC_READ,
80 FILE_SHARE_READ,
81 NULL,
82 OPEN_ALWAYS,
83 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
84 NULL
85 );
86 if( h==INVALID_HANDLE_VALUE ){
87 return SQLITE_CANTOPEN;
88 }
89 *pReadonly = 1;
90 }else{
91 *pReadonly = 0;
92 }
93 id->h = h;
drh51c6d962004-06-06 00:42:25 +000094 id->locktype = NO_LOCK;
drhe54ca3f2004-06-07 01:52:14 +000095 id->sharedLockByte = 0;
drhda71ce12004-06-21 18:14:45 +000096 id->isOpen = 1;
drhbbd42a62004-05-22 17:41:58 +000097 OpenCounter(+1);
drh51c6d962004-06-06 00:42:25 +000098 TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
drhbbd42a62004-05-22 17:41:58 +000099 return SQLITE_OK;
100}
101
102
103/*
104** Attempt to open a new file for exclusive access by this process.
105** The file will be opened for both reading and writing. To avoid
106** a potential security problem, we do not allow the file to have
107** previously existed. Nor do we allow the file to be a symbolic
108** link.
109**
110** If delFlag is true, then make arrangements to automatically delete
111** the file when it is closed.
112**
113** On success, write the file handle into *id and return SQLITE_OK.
114**
115** On failure, return SQLITE_CANTOPEN.
116*/
117int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
118 HANDLE h;
119 int fileflags;
drhda71ce12004-06-21 18:14:45 +0000120 assert( !id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000121 if( delFlag ){
122 fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
123 | FILE_FLAG_DELETE_ON_CLOSE;
124 }else{
125 fileflags = FILE_FLAG_RANDOM_ACCESS;
126 }
drh93d648d2004-06-30 14:28:59 +0000127 h = CreateFileA(zFilename,
drhbbd42a62004-05-22 17:41:58 +0000128 GENERIC_READ | GENERIC_WRITE,
129 0,
130 NULL,
131 CREATE_ALWAYS,
132 fileflags,
133 NULL
134 );
135 if( h==INVALID_HANDLE_VALUE ){
136 return SQLITE_CANTOPEN;
137 }
138 id->h = h;
drh51c6d962004-06-06 00:42:25 +0000139 id->locktype = NO_LOCK;
drhe54ca3f2004-06-07 01:52:14 +0000140 id->sharedLockByte = 0;
drhda71ce12004-06-21 18:14:45 +0000141 id->isOpen = 1;
drhbbd42a62004-05-22 17:41:58 +0000142 OpenCounter(+1);
drh51c6d962004-06-06 00:42:25 +0000143 TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
drhbbd42a62004-05-22 17:41:58 +0000144 return SQLITE_OK;
145}
146
147/*
148** Attempt to open a new file for read-only access.
149**
150** On success, write the file handle into *id and return SQLITE_OK.
151**
152** On failure, return SQLITE_CANTOPEN.
153*/
154int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
drhda71ce12004-06-21 18:14:45 +0000155 HANDLE h;
156 assert( !id->isOpen );
drh93d648d2004-06-30 14:28:59 +0000157 h = CreateFileA(zFilename,
drhbbd42a62004-05-22 17:41:58 +0000158 GENERIC_READ,
159 0,
160 NULL,
161 OPEN_EXISTING,
162 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
163 NULL
164 );
165 if( h==INVALID_HANDLE_VALUE ){
166 return SQLITE_CANTOPEN;
167 }
168 id->h = h;
drh51c6d962004-06-06 00:42:25 +0000169 id->locktype = NO_LOCK;
drhe54ca3f2004-06-07 01:52:14 +0000170 id->sharedLockByte = 0;
drhda71ce12004-06-21 18:14:45 +0000171 id->isOpen = 1;
drhbbd42a62004-05-22 17:41:58 +0000172 OpenCounter(+1);
drh51c6d962004-06-06 00:42:25 +0000173 TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
drhbbd42a62004-05-22 17:41:58 +0000174 return SQLITE_OK;
175}
176
177/*
178** Attempt to open a file descriptor for the directory that contains a
179** file. This file descriptor can be used to fsync() the directory
180** in order to make sure the creation of a new file is actually written
181** to disk.
182**
183** This routine is only meaningful for Unix. It is a no-op under
184** windows since windows does not support hard links.
185**
186** On success, a handle for a previously open file is at *id is
187** updated with the new directory file descriptor and SQLITE_OK is
188** returned.
189**
190** On failure, the function returns SQLITE_CANTOPEN and leaves
191** *id unchanged.
192*/
193int sqlite3OsOpenDirectory(
194 const char *zDirname,
195 OsFile *id
196){
197 return SQLITE_OK;
198}
199
200/*
drh3d2efea2004-08-28 01:12:56 +0000201** If the following global variable points to a string which is the
202** name of a directory, then that directory will be used to store
203** temporary files.
204*/
drheffd02b2004-08-29 23:42:13 +0000205const char *sqlite3_temp_directory = 0;
drh3d2efea2004-08-28 01:12:56 +0000206
207/*
drhbbd42a62004-05-22 17:41:58 +0000208** Create a temporary file name in zBuf. zBuf must be big enough to
209** hold at least SQLITE_TEMPNAME_SIZE characters.
210*/
211int sqlite3OsTempFileName(char *zBuf){
212 static char zChars[] =
213 "abcdefghijklmnopqrstuvwxyz"
214 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
215 "0123456789";
216 int i, j;
217 char zTempPath[SQLITE_TEMPNAME_SIZE];
drheffd02b2004-08-29 23:42:13 +0000218 if( sqlite3_temp_directory ){
219 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
drh3d2efea2004-08-28 01:12:56 +0000220 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
221 }else{
222 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
223 }
drhbbd42a62004-05-22 17:41:58 +0000224 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
225 zTempPath[i] = 0;
226 for(;;){
227 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
228 j = strlen(zBuf);
229 sqlite3Randomness(15, &zBuf[j]);
230 for(i=0; i<15; i++, j++){
231 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
232 }
233 zBuf[j] = 0;
234 if( !sqlite3OsFileExists(zBuf) ) break;
235 }
drh51c6d962004-06-06 00:42:25 +0000236 TRACE2("TEMP FILENAME: %s\n", zBuf);
drhbbd42a62004-05-22 17:41:58 +0000237 return SQLITE_OK;
238}
239
240/*
241** Close a file.
242*/
243int sqlite3OsClose(OsFile *id){
drhda71ce12004-06-21 18:14:45 +0000244 if( id->isOpen ){
245 TRACE2("CLOSE %d\n", id->h);
246 CloseHandle(id->h);
247 OpenCounter(-1);
248 id->isOpen = 0;
249 }
drhbbd42a62004-05-22 17:41:58 +0000250 return SQLITE_OK;
251}
252
253/*
254** Read data from a file into a buffer. Return SQLITE_OK if all
255** bytes were read successfully and SQLITE_IOERR if anything goes
256** wrong.
257*/
258int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
259 DWORD got;
drhda71ce12004-06-21 18:14:45 +0000260 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000261 SimulateIOError(SQLITE_IOERR);
drhe54ca3f2004-06-07 01:52:14 +0000262 TRACE3("READ %d lock=%d\n", id->h, id->locktype);
drhbbd42a62004-05-22 17:41:58 +0000263 if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
264 got = 0;
265 }
266 if( got==(DWORD)amt ){
267 return SQLITE_OK;
268 }else{
269 return SQLITE_IOERR;
270 }
271}
272
273/*
274** Write data from a buffer into a file. Return SQLITE_OK on success
275** or some other error code on failure.
276*/
277int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
278 int rc;
279 DWORD wrote;
drhda71ce12004-06-21 18:14:45 +0000280 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000281 SimulateIOError(SQLITE_IOERR);
drhe54ca3f2004-06-07 01:52:14 +0000282 TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
drhbbd42a62004-05-22 17:41:58 +0000283 while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
284 amt -= wrote;
285 pBuf = &((char*)pBuf)[wrote];
286 }
287 if( !rc || amt>(int)wrote ){
288 return SQLITE_FULL;
289 }
290 return SQLITE_OK;
291}
292
293/*
294** Move the read/write pointer in a file.
295*/
drheb206252004-10-01 02:00:31 +0000296int sqlite3OsSeek(OsFile *id, i64 offset){
drhbbd42a62004-05-22 17:41:58 +0000297 LONG upperBits = offset>>32;
298 LONG lowerBits = offset & 0xffffffff;
299 DWORD rc;
drhda71ce12004-06-21 18:14:45 +0000300 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000301 SEEK(offset/1024 + 1);
302 rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
drh51c6d962004-06-06 00:42:25 +0000303 TRACE3("SEEK %d %lld\n", id->h, offset);
drhbbd42a62004-05-22 17:41:58 +0000304 return SQLITE_OK;
305}
306
307/*
308** Make sure all writes to a particular file are committed to disk.
309*/
310int sqlite3OsSync(OsFile *id){
drhda71ce12004-06-21 18:14:45 +0000311 assert( id->isOpen );
drhe54ca3f2004-06-07 01:52:14 +0000312 TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
drhbbd42a62004-05-22 17:41:58 +0000313 if( FlushFileBuffers(id->h) ){
314 return SQLITE_OK;
315 }else{
316 return SQLITE_IOERR;
317 }
318}
319
320/*
danielk1977962398d2004-06-14 09:35:16 +0000321** Sync the directory zDirname. This is a no-op on operating systems other
322** than UNIX.
323*/
324int sqlite3OsSyncDirectory(const char *zDirname){
danielk1977369f27e2004-06-15 11:40:04 +0000325 SimulateIOError(SQLITE_IOERR);
danielk1977962398d2004-06-14 09:35:16 +0000326 return SQLITE_OK;
327}
328
329/*
drhbbd42a62004-05-22 17:41:58 +0000330** Truncate an open file to a specified size
331*/
drheb206252004-10-01 02:00:31 +0000332int sqlite3OsTruncate(OsFile *id, i64 nByte){
drhbbd42a62004-05-22 17:41:58 +0000333 LONG upperBits = nByte>>32;
drhda71ce12004-06-21 18:14:45 +0000334 assert( id->isOpen );
drh51c6d962004-06-06 00:42:25 +0000335 TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
drhbbd42a62004-05-22 17:41:58 +0000336 SimulateIOError(SQLITE_IOERR);
337 SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
338 SetEndOfFile(id->h);
339 return SQLITE_OK;
340}
341
342/*
343** Determine the current size of a file in bytes
344*/
drheb206252004-10-01 02:00:31 +0000345int sqlite3OsFileSize(OsFile *id, i64 *pSize){
drhbbd42a62004-05-22 17:41:58 +0000346 DWORD upperBits, lowerBits;
drhda71ce12004-06-21 18:14:45 +0000347 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000348 SimulateIOError(SQLITE_IOERR);
349 lowerBits = GetFileSize(id->h, &upperBits);
drheb206252004-10-01 02:00:31 +0000350 *pSize = (((i64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000351 return SQLITE_OK;
352}
353
354/*
drh51c6d962004-06-06 00:42:25 +0000355** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
356** Return false (zero) for Win95, Win98, or WinME.
drhbbd42a62004-05-22 17:41:58 +0000357**
drh51c6d962004-06-06 00:42:25 +0000358** Here is an interesting observation: Win95, Win98, and WinME lack
359** the LockFileEx() API. But we can still statically link against that
360** API as long as we don't call it win running Win95/98/ME. A call to
361** this routine is used to determine if the host is Win95/98/ME or
362** WinNT/2K/XP so that we will know whether or not we can safely call
363** the LockFileEx() API.
drhbbd42a62004-05-22 17:41:58 +0000364*/
drh51c6d962004-06-06 00:42:25 +0000365static int isNT(void){
366 static int osType = 0; /* 0=unknown 1=win95 2=winNT */
367 if( osType==0 ){
368 OSVERSIONINFO sInfo;
369 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
370 GetVersionEx(&sInfo);
371 osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
372 }
373 return osType==2;
374}
375
376/*
377** Acquire a reader lock on the range of bytes from iByte...iByte+nByte-1.
378** Different API routines are called depending on whether or not this
379** is Win95 or WinNT.
380*/
381static int getReadLock(HANDLE h, unsigned int iByte, unsigned int nByte){
382 int res;
383 if( isNT() ){
384 OVERLAPPED ovlp;
385 ovlp.Offset = iByte;
386 ovlp.OffsetHigh = 0;
387 ovlp.hEvent = 0;
388 res = LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0, nByte, 0, &ovlp);
drhbbd42a62004-05-22 17:41:58 +0000389 }else{
drh51c6d962004-06-06 00:42:25 +0000390 res = LockFile(h, iByte, 0, nByte, 0);
391 }
392 return res;
393}
394
395/*
396** Undo a readlock
397*/
398static int unlockReadLock(OsFile *id){
399 int res;
400 if( isNT() ){
401 res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
402 }else{
403 res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
404 }
405 return res;
406}
407
408/*
drhb3e04342004-06-08 00:47:47 +0000409** Lock the file with the lock specified by parameter locktype - one
410** of the following:
411**
412** (1) SHARED_LOCK
413** (2) RESERVED_LOCK
414** (3) PENDING_LOCK
415** (4) EXCLUSIVE_LOCK
416**
417** Sometimes when requesting one lock state, additional lock states
418** are inserted in between. The locking might fail on one of the later
419** transitions leaving the lock state different from what it started but
420** still short of its goal. The following chart shows the allowed
421** transitions and the inserted intermediate states:
422**
423** UNLOCKED -> SHARED
424** SHARED -> RESERVED
425** SHARED -> (PENDING) -> EXCLUSIVE
426** RESERVED -> (PENDING) -> EXCLUSIVE
427** PENDING -> EXCLUSIVE
428**
429** This routine will only increase a lock. The sqlite3OsUnlock() routine
430** erases all locks at once and returns us immediately to locking level 0.
431** It is not possible to lower the locking level one step at a time. You
432** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000433*/
434int sqlite3OsLock(OsFile *id, int locktype){
435 int rc = SQLITE_OK; /* Return code from subroutines */
436 int res = 1; /* Result of a windows lock call */
drhe54ca3f2004-06-07 01:52:14 +0000437 int newLocktype; /* Set id->locktype to this value before exiting */
438 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh51c6d962004-06-06 00:42:25 +0000439
drhda71ce12004-06-21 18:14:45 +0000440 assert( id->isOpen );
drhe54ca3f2004-06-07 01:52:14 +0000441 TRACE5("LOCK %d %d was %d(%d)\n",
442 id->h, locktype, id->locktype, id->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000443
444 /* If there is already a lock of this type or more restrictive on the
445 ** OsFile, do nothing. Don't use the end_lock: exit path, as
446 ** sqlite3OsEnterMutex() hasn't been called yet.
447 */
448 if( id->locktype>=locktype ){
449 return SQLITE_OK;
450 }
451
drhb3e04342004-06-08 00:47:47 +0000452 /* Make sure the locking sequence is correct
453 */
454 assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
455 assert( locktype!=PENDING_LOCK );
456 assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
457
drh51c6d962004-06-06 00:42:25 +0000458 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
459 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
460 ** the PENDING_LOCK byte is temporary.
461 */
drh3cde3bb2004-06-12 02:17:14 +0000462 newLocktype = id->locktype;
drhe54ca3f2004-06-07 01:52:14 +0000463 if( id->locktype==NO_LOCK
drhb3e04342004-06-08 00:47:47 +0000464 || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +0000465 ){
drhb3e04342004-06-08 00:47:47 +0000466 int cnt = 3;
drh51c6d962004-06-06 00:42:25 +0000467 while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000468 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000469 ** held by another reader process who will release it momentarily.
470 */
drhe54ca3f2004-06-07 01:52:14 +0000471 TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000472 Sleep(1);
473 }
drhe54ca3f2004-06-07 01:52:14 +0000474 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +0000475 }
476
477 /* Acquire a shared lock
478 */
drhb3e04342004-06-08 00:47:47 +0000479 if( locktype==SHARED_LOCK && res ){
480 assert( id->locktype==NO_LOCK );
drh51c6d962004-06-06 00:42:25 +0000481 if( isNT() ){
482 res = getReadLock(id->h, SHARED_FIRST, SHARED_SIZE);
drhbbd42a62004-05-22 17:41:58 +0000483 }else{
drh51c6d962004-06-06 00:42:25 +0000484 int lk;
485 sqlite3Randomness(sizeof(lk), &lk);
486 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
487 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000488 }
drhe54ca3f2004-06-07 01:52:14 +0000489 if( res ){
490 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +0000491 }
492 }
493
494 /* Acquire a RESERVED lock
495 */
drhb3e04342004-06-08 00:47:47 +0000496 if( locktype==RESERVED_LOCK && res ){
497 assert( id->locktype==SHARED_LOCK );
drhe54ca3f2004-06-07 01:52:14 +0000498 res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
499 if( res ){
500 newLocktype = RESERVED_LOCK;
501 }
502 }
503
504 /* Acquire a PENDING lock
505 */
drhb3e04342004-06-08 00:47:47 +0000506 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000507 newLocktype = PENDING_LOCK;
508 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000509 }
510
511 /* Acquire an EXCLUSIVE lock
512 */
drhe54ca3f2004-06-07 01:52:14 +0000513 if( locktype==EXCLUSIVE_LOCK && res ){
drhb3e04342004-06-08 00:47:47 +0000514 assert( id->locktype>=SHARED_LOCK );
515 res = unlockReadLock(id);
516 TRACE2("unreadlock = %d\n", res);
517 res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +0000518 if( res ){
519 newLocktype = EXCLUSIVE_LOCK;
520 }else{
521 TRACE2("error-code = %d\n", GetLastError());
522 }
523 }
524
525 /* If we are holding a PENDING lock that ought to be released, then
526 ** release it now.
527 */
drhb3e04342004-06-08 00:47:47 +0000528 if( gotPendingLock && locktype==SHARED_LOCK ){
drhe54ca3f2004-06-07 01:52:14 +0000529 UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000530 }
531
532 /* Update the state of the lock has held in the file descriptor then
533 ** return the appropriate result code.
534 */
535 if( res ){
drh51c6d962004-06-06 00:42:25 +0000536 rc = SQLITE_OK;
537 }else{
drhe54ca3f2004-06-07 01:52:14 +0000538 TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
539 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +0000540 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +0000541 }
drhe54ca3f2004-06-07 01:52:14 +0000542 id->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +0000543 return rc;
544}
545
546/*
drh51c6d962004-06-06 00:42:25 +0000547** This routine checks if there is a RESERVED lock held on the specified
548** file by this or any other process. If such a lock is held, return
549** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +0000550*/
drha6abd042004-06-09 17:37:22 +0000551int sqlite3OsCheckReservedLock(OsFile *id){
drhbbd42a62004-05-22 17:41:58 +0000552 int rc;
drhda71ce12004-06-21 18:14:45 +0000553 assert( id->isOpen );
drh51c6d962004-06-06 00:42:25 +0000554 if( id->locktype>=RESERVED_LOCK ){
555 rc = 1;
drh2ac3ee92004-06-07 16:27:46 +0000556 TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000557 }else{
drhe54ca3f2004-06-07 01:52:14 +0000558 rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000559 if( rc ){
560 UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000561 }
drh2ac3ee92004-06-07 16:27:46 +0000562 rc = !rc;
563 TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000564 }
drh2ac3ee92004-06-07 16:27:46 +0000565 return rc;
drhbbd42a62004-05-22 17:41:58 +0000566}
567
568/*
drha6abd042004-06-09 17:37:22 +0000569** Lower the locking level on file descriptor id to locktype. locktype
570** must be either NO_LOCK or SHARED_LOCK.
571**
572** If the locking level of the file descriptor is already at or below
573** the requested locking level, this routine is a no-op.
574**
575** It is not possible for this routine to fail.
drhbbd42a62004-05-22 17:41:58 +0000576*/
drha6abd042004-06-09 17:37:22 +0000577int sqlite3OsUnlock(OsFile *id, int locktype){
drhe54ca3f2004-06-07 01:52:14 +0000578 int rc, type;
drhda71ce12004-06-21 18:14:45 +0000579 assert( id->isOpen );
drha6abd042004-06-09 17:37:22 +0000580 assert( locktype<=SHARED_LOCK );
drh3cde3bb2004-06-12 02:17:14 +0000581 TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
drha6abd042004-06-09 17:37:22 +0000582 id->locktype, id->sharedLockByte);
drhe54ca3f2004-06-07 01:52:14 +0000583 type = id->locktype;
584 if( type>=EXCLUSIVE_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000585 UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhbbd42a62004-05-22 17:41:58 +0000586 }
drhe54ca3f2004-06-07 01:52:14 +0000587 if( type>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000588 UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
589 }
drha6abd042004-06-09 17:37:22 +0000590 if( locktype==NO_LOCK && type>=SHARED_LOCK && type<EXCLUSIVE_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000591 unlockReadLock(id);
592 }
drhb3e04342004-06-08 00:47:47 +0000593 if( type>=PENDING_LOCK ){
594 UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
595 }
drha6abd042004-06-09 17:37:22 +0000596 id->locktype = locktype;
drh51c6d962004-06-06 00:42:25 +0000597 return SQLITE_OK;
drhbbd42a62004-05-22 17:41:58 +0000598}
599
600/*
601** Get information to seed the random number generator. The seed
602** is written into the buffer zBuf[256]. The calling function must
603** supply a sufficiently large buffer.
604*/
605int sqlite3OsRandomSeed(char *zBuf){
606 /* We have to initialize zBuf to prevent valgrind from reporting
607 ** errors. The reports issued by valgrind are incorrect - we would
608 ** prefer that the randomness be increased by making use of the
609 ** uninitialized space in zBuf - but valgrind errors tend to worry
610 ** some users. Rather than argue, it seems easier just to initialize
611 ** the whole array and silence valgrind, even if that means less randomness
612 ** in the random seed.
613 **
614 ** When testing, initializing zBuf[] to zero is all we do. That means
615 ** that we always use the same random number sequence.* This makes the
616 ** tests repeatable.
617 */
618 memset(zBuf, 0, 256);
619 GetSystemTime((LPSYSTEMTIME)zBuf);
620 return SQLITE_OK;
621}
622
623/*
624** Sleep for a little while. Return the amount of time slept.
625*/
626int sqlite3OsSleep(int ms){
627 Sleep(ms);
628 return ms;
629}
630
631/*
632** Static variables used for thread synchronization
633*/
634static int inMutex = 0;
635#ifdef SQLITE_W32_THREADS
636 static CRITICAL_SECTION cs;
637#endif
638
639/*
640** The following pair of routine implement mutual exclusion for
641** multi-threaded processes. Only a single thread is allowed to
642** executed code that is surrounded by EnterMutex() and LeaveMutex().
643**
644** SQLite uses only a single Mutex. There is not much critical
645** code and what little there is executes quickly and without blocking.
646*/
647void sqlite3OsEnterMutex(){
648#ifdef SQLITE_W32_THREADS
649 static int isInit = 0;
650 while( !isInit ){
651 static long lock = 0;
652 if( InterlockedIncrement(&lock)==1 ){
653 InitializeCriticalSection(&cs);
654 isInit = 1;
655 }else{
656 Sleep(1);
657 }
658 }
659 EnterCriticalSection(&cs);
660#endif
661 assert( !inMutex );
662 inMutex = 1;
663}
664void sqlite3OsLeaveMutex(){
665 assert( inMutex );
666 inMutex = 0;
667#ifdef SQLITE_W32_THREADS
668 LeaveCriticalSection(&cs);
669#endif
670}
671
672/*
673** Turn a relative pathname into a full pathname. Return a pointer
674** to the full pathname stored in space obtained from sqliteMalloc().
675** The calling function is responsible for freeing this space once it
676** is no longer needed.
677*/
678char *sqlite3OsFullPathname(const char *zRelative){
679 char *zNotUsed;
680 char *zFull;
681 int nByte;
drh93d648d2004-06-30 14:28:59 +0000682 nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
drhbbd42a62004-05-22 17:41:58 +0000683 zFull = sqliteMalloc( nByte );
684 if( zFull==0 ) return 0;
drh93d648d2004-06-30 14:28:59 +0000685 GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
drhbbd42a62004-05-22 17:41:58 +0000686 return zFull;
687}
688
689/*
690** The following variable, if set to a non-zero value, becomes the result
691** returned from sqlite3OsCurrentTime(). This is used for testing.
692*/
693#ifdef SQLITE_TEST
694int sqlite3_current_time = 0;
695#endif
696
697/*
698** Find the current time (in Universal Coordinated Time). Write the
699** current time and date as a Julian Day number into *prNow and
700** return 0. Return 1 if the time and date cannot be found.
701*/
702int sqlite3OsCurrentTime(double *prNow){
703 FILETIME ft;
704 /* FILETIME structure is a 64-bit value representing the number of
705 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
706 */
707 double now;
708 GetSystemTimeAsFileTime( &ft );
709 now = ((double)ft.dwHighDateTime) * 4294967296.0;
710 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
711#ifdef SQLITE_TEST
712 if( sqlite3_current_time ){
713 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
714 }
715#endif
716 return 0;
717}
718
drhbf9a7e42004-06-15 00:29:03 +0000719/*
720** Find the time that the file was last modified. Write the
721** modification time and date as a Julian Day number into *prNow and
722** return SQLITE_OK. Return SQLITE_ERROR if the modification
723** time cannot be found.
724*/
725int sqlite3OsFileModTime(OsFile *id, double *prMTime){
726 int rc;
727 FILETIME ft;
728 /* FILETIME structure is a 64-bit value representing the number of
729 ** 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
730 */
731 if( GetFileTime(id->h, 0, 0, &ft) ){
732 double t;
733 t = ((double)ft.dwHighDateTime) * 4294967296.0;
734 *prMTime = (t + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
735 rc = SQLITE_OK;
736 }else{
737 rc = SQLITE_ERROR;
738 }
739 return rc;
740}
741
drhbbd42a62004-05-22 17:41:58 +0000742#endif /* OS_WIN */