blob: f675fb1a77e13d3022831c7231e40cf25010e775 [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/*
drh0ccebe72005-06-07 22:22:50 +000038** Do not include any of the File I/O interface procedures if the
39** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
40** will be in-memory only)
41*/
42#ifndef SQLITE_OMIT_DISKIO
43
44/*
drhc0929982005-09-05 19:08:29 +000045** The following variable is (normally) set once and never changes
46** thereafter. It records whether the operating system is Win95
47** or WinNT.
48**
49** 0: Operating system unknown.
50** 1: Operating system is Win95.
51** 2: Operating system is WinNT.
52**
53** In order to facilitate testing on a WinNT system, the test fixture
54** can manually set this value to 1 to emulate Win98 behavior.
55*/
56int sqlite3_os_type = 0;
57
58/*
59** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
60** Return false (zero) for Win95, Win98, or WinME.
61**
62** Here is an interesting observation: Win95, Win98, and WinME lack
63** the LockFileEx() API. But we can still statically link against that
64** API as long as we don't call it win running Win95/98/ME. A call to
65** this routine is used to determine if the host is Win95/98/ME or
66** WinNT/2K/XP so that we will know whether or not we can safely call
67** the LockFileEx() API.
68*/
69static int isNT(void){
70 if( sqlite3_os_type==0 ){
71 OSVERSIONINFO sInfo;
72 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
73 GetVersionEx(&sInfo);
74 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
75 }
76 return sqlite3_os_type==2;
77}
78
79/*
80** Convert a UTF-8 string to UTF-32. Space to hold the returned string
81** is obtained from sqliteMalloc.
82*/
83static WCHAR *utf8ToUnicode(const char *zFilename){
84 int nByte;
85 WCHAR *zWideFilename;
86
87 if( !isNT() ){
88 return 0;
89 }
90 nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
drhd81bd4e2005-09-05 20:06:49 +000091 zWideFilename = sqliteMalloc( nByte*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +000092 if( zWideFilename==0 ){
93 return 0;
94 }
95 nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
96 if( nByte==0 ){
97 sqliteFree(zWideFilename);
98 zWideFilename = 0;
99 }
100 return zWideFilename;
101}
102
103/*
104** Convert UTF-32 to UTF-8. Space to hold the returned string is
105** obtained from sqliteMalloc().
106*/
107static char *unicodeToUtf8(const WCHAR *zWideFilename){
108 int nByte;
109 char *zFilename;
110
111 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
112 zFilename = sqliteMalloc( nByte );
113 if( zFilename==0 ){
114 return 0;
115 }
116 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
117 0, 0);
118 if( nByte == 0 ){
119 sqliteFree(zFilename);
120 zFilename = 0;
121 }
122 return zFilename;
123}
124
125
126/*
drhbbd42a62004-05-22 17:41:58 +0000127** Delete the named file
128*/
129int sqlite3OsDelete(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000130 WCHAR *zWide = utf8ToUnicode(zFilename);
131 if( zWide ){
132 DeleteFileW(zWide);
133 sqliteFree(zWide);
134 }else{
135 DeleteFileA(zFilename);
136 }
drh51c6d962004-06-06 00:42:25 +0000137 TRACE2("DELETE \"%s\"\n", zFilename);
drhbbd42a62004-05-22 17:41:58 +0000138 return SQLITE_OK;
139}
140
141/*
142** Return TRUE if the named file exists.
143*/
144int sqlite3OsFileExists(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000145 int exists = 0;
146 WCHAR *zWide = utf8ToUnicode(zFilename);
147 if( zWide ){
148 exists = GetFileAttributesW(zWide) != 0xffffffff;
149 sqliteFree(zWide);
150 }else{
151 exists = GetFileAttributesA(zFilename) != 0xffffffff;
152 }
153 return exists;
drhbbd42a62004-05-22 17:41:58 +0000154}
155
156/*
157** Attempt to open a file for both reading and writing. If that
158** fails, try opening it read-only. If the file does not exist,
159** try to create it.
160**
161** On success, a handle for the open file is written to *id
162** and *pReadonly is set to 0 if the file was opened for reading and
163** writing or 1 if the file was opened read-only. The function returns
164** SQLITE_OK.
165**
166** On failure, the function returns SQLITE_CANTOPEN and leaves
167** *id and *pReadonly unchanged.
168*/
169int sqlite3OsOpenReadWrite(
170 const char *zFilename,
171 OsFile *id,
172 int *pReadonly
173){
drhda71ce12004-06-21 18:14:45 +0000174 HANDLE h;
drhc0929982005-09-05 19:08:29 +0000175 WCHAR *zWide = utf8ToUnicode(zFilename);
drhda71ce12004-06-21 18:14:45 +0000176 assert( !id->isOpen );
drhc0929982005-09-05 19:08:29 +0000177 if( zWide ){
178 h = CreateFileW(zWide,
179 GENERIC_READ | GENERIC_WRITE,
180 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhbbd42a62004-05-22 17:41:58 +0000181 NULL,
182 OPEN_ALWAYS,
183 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
184 NULL
185 );
186 if( h==INVALID_HANDLE_VALUE ){
drhc0929982005-09-05 19:08:29 +0000187 h = CreateFileW(zWide,
188 GENERIC_READ,
189 FILE_SHARE_READ,
190 NULL,
191 OPEN_ALWAYS,
192 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
193 NULL
194 );
195 if( h==INVALID_HANDLE_VALUE ){
196 sqliteFree(zWide);
197 return SQLITE_CANTOPEN;
198 }
199 *pReadonly = 1;
200 }else{
201 *pReadonly = 0;
drhbbd42a62004-05-22 17:41:58 +0000202 }
drhc0929982005-09-05 19:08:29 +0000203 sqliteFree(zWide);
drhbbd42a62004-05-22 17:41:58 +0000204 }else{
drhc0929982005-09-05 19:08:29 +0000205 h = CreateFileA(zFilename,
206 GENERIC_READ | GENERIC_WRITE,
207 FILE_SHARE_READ | FILE_SHARE_WRITE,
208 NULL,
209 OPEN_ALWAYS,
210 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
211 NULL
212 );
213 if( h==INVALID_HANDLE_VALUE ){
214 h = CreateFileA(zFilename,
215 GENERIC_READ,
216 FILE_SHARE_READ,
217 NULL,
218 OPEN_ALWAYS,
219 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
220 NULL
221 );
222 if( h==INVALID_HANDLE_VALUE ){
223 return SQLITE_CANTOPEN;
224 }
225 *pReadonly = 1;
226 }else{
227 *pReadonly = 0;
228 }
drhbbd42a62004-05-22 17:41:58 +0000229 }
230 id->h = h;
drh51c6d962004-06-06 00:42:25 +0000231 id->locktype = NO_LOCK;
drhe54ca3f2004-06-07 01:52:14 +0000232 id->sharedLockByte = 0;
drhda71ce12004-06-21 18:14:45 +0000233 id->isOpen = 1;
drhbbd42a62004-05-22 17:41:58 +0000234 OpenCounter(+1);
drh51c6d962004-06-06 00:42:25 +0000235 TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
drhbbd42a62004-05-22 17:41:58 +0000236 return SQLITE_OK;
237}
238
239
240/*
241** Attempt to open a new file for exclusive access by this process.
242** The file will be opened for both reading and writing. To avoid
243** a potential security problem, we do not allow the file to have
244** previously existed. Nor do we allow the file to be a symbolic
245** link.
246**
247** If delFlag is true, then make arrangements to automatically delete
248** the file when it is closed.
249**
250** On success, write the file handle into *id and return SQLITE_OK.
251**
252** On failure, return SQLITE_CANTOPEN.
253*/
254int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
255 HANDLE h;
256 int fileflags;
drhc0929982005-09-05 19:08:29 +0000257 WCHAR *zWide = utf8ToUnicode(zFilename);
drhda71ce12004-06-21 18:14:45 +0000258 assert( !id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000259 if( delFlag ){
260 fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
261 | FILE_FLAG_DELETE_ON_CLOSE;
262 }else{
263 fileflags = FILE_FLAG_RANDOM_ACCESS;
264 }
drhc0929982005-09-05 19:08:29 +0000265 if( zWide ){
266 h = CreateFileW(zWide,
267 GENERIC_READ | GENERIC_WRITE,
268 0,
269 NULL,
270 CREATE_ALWAYS,
271 fileflags,
272 NULL
273 );
274 sqliteFree(zWide);
275 }else{
276 h = CreateFileA(zFilename,
277 GENERIC_READ | GENERIC_WRITE,
278 0,
279 NULL,
280 CREATE_ALWAYS,
281 fileflags,
282 NULL
283 );
284 }
drhbbd42a62004-05-22 17:41:58 +0000285 if( h==INVALID_HANDLE_VALUE ){
286 return SQLITE_CANTOPEN;
287 }
288 id->h = h;
drh51c6d962004-06-06 00:42:25 +0000289 id->locktype = NO_LOCK;
drhe54ca3f2004-06-07 01:52:14 +0000290 id->sharedLockByte = 0;
drhda71ce12004-06-21 18:14:45 +0000291 id->isOpen = 1;
drhbbd42a62004-05-22 17:41:58 +0000292 OpenCounter(+1);
drh51c6d962004-06-06 00:42:25 +0000293 TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
drhbbd42a62004-05-22 17:41:58 +0000294 return SQLITE_OK;
295}
296
297/*
298** Attempt to open a new file for read-only access.
299**
300** On success, write the file handle into *id and return SQLITE_OK.
301**
302** On failure, return SQLITE_CANTOPEN.
303*/
304int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
drhda71ce12004-06-21 18:14:45 +0000305 HANDLE h;
drhc0929982005-09-05 19:08:29 +0000306 WCHAR *zWide = utf8ToUnicode(zFilename);
drhda71ce12004-06-21 18:14:45 +0000307 assert( !id->isOpen );
drhc0929982005-09-05 19:08:29 +0000308 if( zWide ){
309 h = CreateFileW(zWide,
310 GENERIC_READ,
311 0,
312 NULL,
313 OPEN_EXISTING,
314 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
315 NULL
316 );
317 sqliteFree(zWide);
318 }else{
319 h = CreateFileA(zFilename,
320 GENERIC_READ,
321 0,
322 NULL,
323 OPEN_EXISTING,
324 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
325 NULL
326 );
327 }
drhbbd42a62004-05-22 17:41:58 +0000328 if( h==INVALID_HANDLE_VALUE ){
329 return SQLITE_CANTOPEN;
330 }
331 id->h = h;
drh51c6d962004-06-06 00:42:25 +0000332 id->locktype = NO_LOCK;
drhe54ca3f2004-06-07 01:52:14 +0000333 id->sharedLockByte = 0;
drhda71ce12004-06-21 18:14:45 +0000334 id->isOpen = 1;
drhbbd42a62004-05-22 17:41:58 +0000335 OpenCounter(+1);
drh51c6d962004-06-06 00:42:25 +0000336 TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
drhbbd42a62004-05-22 17:41:58 +0000337 return SQLITE_OK;
338}
339
340/*
341** Attempt to open a file descriptor for the directory that contains a
342** file. This file descriptor can be used to fsync() the directory
343** in order to make sure the creation of a new file is actually written
344** to disk.
345**
346** This routine is only meaningful for Unix. It is a no-op under
347** windows since windows does not support hard links.
348**
349** On success, a handle for a previously open file is at *id is
350** updated with the new directory file descriptor and SQLITE_OK is
351** returned.
352**
353** On failure, the function returns SQLITE_CANTOPEN and leaves
354** *id unchanged.
355*/
356int sqlite3OsOpenDirectory(
357 const char *zDirname,
358 OsFile *id
359){
360 return SQLITE_OK;
361}
362
363/*
drh3d2efea2004-08-28 01:12:56 +0000364** If the following global variable points to a string which is the
365** name of a directory, then that directory will be used to store
366** temporary files.
367*/
tpoindex9a09a3c2004-12-20 19:01:32 +0000368char *sqlite3_temp_directory = 0;
drh3d2efea2004-08-28 01:12:56 +0000369
370/*
drhbbd42a62004-05-22 17:41:58 +0000371** Create a temporary file name in zBuf. zBuf must be big enough to
372** hold at least SQLITE_TEMPNAME_SIZE characters.
373*/
374int sqlite3OsTempFileName(char *zBuf){
375 static char zChars[] =
376 "abcdefghijklmnopqrstuvwxyz"
377 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
378 "0123456789";
379 int i, j;
380 char zTempPath[SQLITE_TEMPNAME_SIZE];
drheffd02b2004-08-29 23:42:13 +0000381 if( sqlite3_temp_directory ){
382 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
drh3d2efea2004-08-28 01:12:56 +0000383 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
drhc0929982005-09-05 19:08:29 +0000384 }else if( isNT() ){
385 char *zMulti;
386 WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
387 GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
388 zMulti = unicodeToUtf8(zWidePath);
389 if( zMulti ){
drhd81bd4e2005-09-05 20:06:49 +0000390 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
drhc0929982005-09-05 19:08:29 +0000391 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
392 sqliteFree(zMulti);
393 }
drh3d2efea2004-08-28 01:12:56 +0000394 }else{
395 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
396 }
drhbbd42a62004-05-22 17:41:58 +0000397 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
398 zTempPath[i] = 0;
399 for(;;){
400 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
401 j = strlen(zBuf);
402 sqlite3Randomness(15, &zBuf[j]);
403 for(i=0; i<15; i++, j++){
404 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
405 }
406 zBuf[j] = 0;
407 if( !sqlite3OsFileExists(zBuf) ) break;
408 }
drh51c6d962004-06-06 00:42:25 +0000409 TRACE2("TEMP FILENAME: %s\n", zBuf);
drhbbd42a62004-05-22 17:41:58 +0000410 return SQLITE_OK;
411}
412
413/*
414** Close a file.
415*/
416int sqlite3OsClose(OsFile *id){
drhda71ce12004-06-21 18:14:45 +0000417 if( id->isOpen ){
418 TRACE2("CLOSE %d\n", id->h);
419 CloseHandle(id->h);
420 OpenCounter(-1);
421 id->isOpen = 0;
422 }
drhbbd42a62004-05-22 17:41:58 +0000423 return SQLITE_OK;
424}
425
426/*
427** Read data from a file into a buffer. Return SQLITE_OK if all
428** bytes were read successfully and SQLITE_IOERR if anything goes
429** wrong.
430*/
431int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
432 DWORD got;
drhda71ce12004-06-21 18:14:45 +0000433 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000434 SimulateIOError(SQLITE_IOERR);
drhe54ca3f2004-06-07 01:52:14 +0000435 TRACE3("READ %d lock=%d\n", id->h, id->locktype);
drhbbd42a62004-05-22 17:41:58 +0000436 if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
437 got = 0;
438 }
439 if( got==(DWORD)amt ){
440 return SQLITE_OK;
441 }else{
442 return SQLITE_IOERR;
443 }
444}
445
446/*
447** Write data from a buffer into a file. Return SQLITE_OK on success
448** or some other error code on failure.
449*/
450int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
drh4c7f9412005-02-03 00:29:47 +0000451 int rc = 0;
drhbbd42a62004-05-22 17:41:58 +0000452 DWORD wrote;
drhda71ce12004-06-21 18:14:45 +0000453 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000454 SimulateIOError(SQLITE_IOERR);
dougcurrie0924bba2004-10-01 18:21:43 +0000455 SimulateDiskfullError;
drhe54ca3f2004-06-07 01:52:14 +0000456 TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);
drh4c7f9412005-02-03 00:29:47 +0000457 assert( amt>0 );
drhbbd42a62004-05-22 17:41:58 +0000458 while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
459 amt -= wrote;
460 pBuf = &((char*)pBuf)[wrote];
461 }
462 if( !rc || amt>(int)wrote ){
463 return SQLITE_FULL;
464 }
465 return SQLITE_OK;
466}
467
468/*
469** Move the read/write pointer in a file.
470*/
drheb206252004-10-01 02:00:31 +0000471int sqlite3OsSeek(OsFile *id, i64 offset){
drhbbd42a62004-05-22 17:41:58 +0000472 LONG upperBits = offset>>32;
473 LONG lowerBits = offset & 0xffffffff;
474 DWORD rc;
drhda71ce12004-06-21 18:14:45 +0000475 assert( id->isOpen );
drhb4746b92005-09-09 01:32:06 +0000476#ifdef SQLITE_TEST
477 if( offset ) SimulateDiskfullError
478#endif
drhbbd42a62004-05-22 17:41:58 +0000479 SEEK(offset/1024 + 1);
480 rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
drh51c6d962004-06-06 00:42:25 +0000481 TRACE3("SEEK %d %lld\n", id->h, offset);
drhe08b8142005-09-09 10:17:33 +0000482 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
483 return SQLITE_FULL;
484 }
drhbbd42a62004-05-22 17:41:58 +0000485 return SQLITE_OK;
486}
487
488/*
489** Make sure all writes to a particular file are committed to disk.
490*/
drheb796a72005-09-08 12:38:41 +0000491int sqlite3OsSync(OsFile *id, int dataOnly){
drhda71ce12004-06-21 18:14:45 +0000492 assert( id->isOpen );
drhe54ca3f2004-06-07 01:52:14 +0000493 TRACE3("SYNC %d lock=%d\n", id->h, id->locktype);
drhbbd42a62004-05-22 17:41:58 +0000494 if( FlushFileBuffers(id->h) ){
495 return SQLITE_OK;
496 }else{
497 return SQLITE_IOERR;
498 }
499}
500
501/*
danielk1977962398d2004-06-14 09:35:16 +0000502** Sync the directory zDirname. This is a no-op on operating systems other
503** than UNIX.
504*/
505int sqlite3OsSyncDirectory(const char *zDirname){
danielk1977369f27e2004-06-15 11:40:04 +0000506 SimulateIOError(SQLITE_IOERR);
danielk1977962398d2004-06-14 09:35:16 +0000507 return SQLITE_OK;
508}
509
510/*
drhbbd42a62004-05-22 17:41:58 +0000511** Truncate an open file to a specified size
512*/
drheb206252004-10-01 02:00:31 +0000513int sqlite3OsTruncate(OsFile *id, i64 nByte){
drhbbd42a62004-05-22 17:41:58 +0000514 LONG upperBits = nByte>>32;
drhda71ce12004-06-21 18:14:45 +0000515 assert( id->isOpen );
drh51c6d962004-06-06 00:42:25 +0000516 TRACE3("TRUNCATE %d %lld\n", id->h, nByte);
drhbbd42a62004-05-22 17:41:58 +0000517 SimulateIOError(SQLITE_IOERR);
518 SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
519 SetEndOfFile(id->h);
520 return SQLITE_OK;
521}
522
523/*
524** Determine the current size of a file in bytes
525*/
drheb206252004-10-01 02:00:31 +0000526int sqlite3OsFileSize(OsFile *id, i64 *pSize){
drhbbd42a62004-05-22 17:41:58 +0000527 DWORD upperBits, lowerBits;
drhda71ce12004-06-21 18:14:45 +0000528 assert( id->isOpen );
drhbbd42a62004-05-22 17:41:58 +0000529 SimulateIOError(SQLITE_IOERR);
530 lowerBits = GetFileSize(id->h, &upperBits);
drheb206252004-10-01 02:00:31 +0000531 *pSize = (((i64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000532 return SQLITE_OK;
533}
534
535/*
drh9c105bb2004-10-02 20:38:28 +0000536** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000537** Different API routines are called depending on whether or not this
538** is Win95 or WinNT.
539*/
drh9c105bb2004-10-02 20:38:28 +0000540static int getReadLock(OsFile *id){
drh51c6d962004-06-06 00:42:25 +0000541 int res;
542 if( isNT() ){
543 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000544 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000545 ovlp.OffsetHigh = 0;
546 ovlp.hEvent = 0;
drh9c105bb2004-10-02 20:38:28 +0000547 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
drhbbd42a62004-05-22 17:41:58 +0000548 }else{
drh9c105bb2004-10-02 20:38:28 +0000549 int lk;
550 sqlite3Randomness(sizeof(lk), &lk);
551 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
552 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000553 }
554 return res;
555}
556
557/*
558** Undo a readlock
559*/
560static int unlockReadLock(OsFile *id){
561 int res;
562 if( isNT() ){
563 res = UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
564 }else{
565 res = UnlockFile(id->h, SHARED_FIRST + id->sharedLockByte, 0, 1, 0);
566 }
567 return res;
568}
569
drh268283b2005-01-08 15:44:25 +0000570#ifndef SQLITE_OMIT_PAGER_PRAGMAS
drh51c6d962004-06-06 00:42:25 +0000571/*
tpoindex9a09a3c2004-12-20 19:01:32 +0000572** Check that a given pathname is a directory and is writable
573**
574*/
drhc0929982005-09-05 19:08:29 +0000575int sqlite3OsIsDirWritable(char *zDirname){
tpoindex9a09a3c2004-12-20 19:01:32 +0000576 int fileAttr;
drhc0929982005-09-05 19:08:29 +0000577 WCHAR *zWide;
578 if( zDirname==0 ) return 0;
579 if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
580 zWide = utf8ToUnicode(zDirname);
581 if( zWide ){
582 fileAttr = GetFileAttributesW(zWide);
583 sqliteFree(zWide);
584 }else{
585 fileAttr = GetFileAttributesA(zDirname);
586 }
tpoindex9a09a3c2004-12-20 19:01:32 +0000587 if( fileAttr == 0xffffffff ) return 0;
drh268283b2005-01-08 15:44:25 +0000588 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
589 return 0;
590 }
tpoindex9a09a3c2004-12-20 19:01:32 +0000591 return 1;
592}
drh268283b2005-01-08 15:44:25 +0000593#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
tpoindex9a09a3c2004-12-20 19:01:32 +0000594
595/*
drhb3e04342004-06-08 00:47:47 +0000596** Lock the file with the lock specified by parameter locktype - one
597** of the following:
598**
599** (1) SHARED_LOCK
600** (2) RESERVED_LOCK
601** (3) PENDING_LOCK
602** (4) EXCLUSIVE_LOCK
603**
604** Sometimes when requesting one lock state, additional lock states
605** are inserted in between. The locking might fail on one of the later
606** transitions leaving the lock state different from what it started but
607** still short of its goal. The following chart shows the allowed
608** transitions and the inserted intermediate states:
609**
610** UNLOCKED -> SHARED
611** SHARED -> RESERVED
612** SHARED -> (PENDING) -> EXCLUSIVE
613** RESERVED -> (PENDING) -> EXCLUSIVE
614** PENDING -> EXCLUSIVE
615**
616** This routine will only increase a lock. The sqlite3OsUnlock() routine
617** erases all locks at once and returns us immediately to locking level 0.
618** It is not possible to lower the locking level one step at a time. You
619** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000620*/
621int sqlite3OsLock(OsFile *id, int locktype){
622 int rc = SQLITE_OK; /* Return code from subroutines */
623 int res = 1; /* Result of a windows lock call */
drhe54ca3f2004-06-07 01:52:14 +0000624 int newLocktype; /* Set id->locktype to this value before exiting */
625 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh51c6d962004-06-06 00:42:25 +0000626
drhda71ce12004-06-21 18:14:45 +0000627 assert( id->isOpen );
drhe54ca3f2004-06-07 01:52:14 +0000628 TRACE5("LOCK %d %d was %d(%d)\n",
629 id->h, locktype, id->locktype, id->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000630
631 /* If there is already a lock of this type or more restrictive on the
632 ** OsFile, do nothing. Don't use the end_lock: exit path, as
633 ** sqlite3OsEnterMutex() hasn't been called yet.
634 */
635 if( id->locktype>=locktype ){
636 return SQLITE_OK;
637 }
638
drhb3e04342004-06-08 00:47:47 +0000639 /* Make sure the locking sequence is correct
640 */
641 assert( id->locktype!=NO_LOCK || locktype==SHARED_LOCK );
642 assert( locktype!=PENDING_LOCK );
643 assert( locktype!=RESERVED_LOCK || id->locktype==SHARED_LOCK );
644
drh51c6d962004-06-06 00:42:25 +0000645 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
646 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
647 ** the PENDING_LOCK byte is temporary.
648 */
drh3cde3bb2004-06-12 02:17:14 +0000649 newLocktype = id->locktype;
drhe54ca3f2004-06-07 01:52:14 +0000650 if( id->locktype==NO_LOCK
drhb3e04342004-06-08 00:47:47 +0000651 || (locktype==EXCLUSIVE_LOCK && id->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +0000652 ){
drhb3e04342004-06-08 00:47:47 +0000653 int cnt = 3;
drh51c6d962004-06-06 00:42:25 +0000654 while( cnt-->0 && (res = LockFile(id->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000655 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000656 ** held by another reader process who will release it momentarily.
657 */
drhe54ca3f2004-06-07 01:52:14 +0000658 TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000659 Sleep(1);
660 }
drhe54ca3f2004-06-07 01:52:14 +0000661 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +0000662 }
663
664 /* Acquire a shared lock
665 */
drhb3e04342004-06-08 00:47:47 +0000666 if( locktype==SHARED_LOCK && res ){
667 assert( id->locktype==NO_LOCK );
drh9c105bb2004-10-02 20:38:28 +0000668 res = getReadLock(id);
drhe54ca3f2004-06-07 01:52:14 +0000669 if( res ){
670 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +0000671 }
672 }
673
674 /* Acquire a RESERVED lock
675 */
drhb3e04342004-06-08 00:47:47 +0000676 if( locktype==RESERVED_LOCK && res ){
677 assert( id->locktype==SHARED_LOCK );
drhe54ca3f2004-06-07 01:52:14 +0000678 res = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
679 if( res ){
680 newLocktype = RESERVED_LOCK;
681 }
682 }
683
684 /* Acquire a PENDING lock
685 */
drhb3e04342004-06-08 00:47:47 +0000686 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000687 newLocktype = PENDING_LOCK;
688 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000689 }
690
691 /* Acquire an EXCLUSIVE lock
692 */
drhe54ca3f2004-06-07 01:52:14 +0000693 if( locktype==EXCLUSIVE_LOCK && res ){
drhb3e04342004-06-08 00:47:47 +0000694 assert( id->locktype>=SHARED_LOCK );
695 res = unlockReadLock(id);
696 TRACE2("unreadlock = %d\n", res);
697 res = LockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +0000698 if( res ){
699 newLocktype = EXCLUSIVE_LOCK;
700 }else{
701 TRACE2("error-code = %d\n", GetLastError());
702 }
703 }
704
705 /* If we are holding a PENDING lock that ought to be released, then
706 ** release it now.
707 */
drhb3e04342004-06-08 00:47:47 +0000708 if( gotPendingLock && locktype==SHARED_LOCK ){
drhe54ca3f2004-06-07 01:52:14 +0000709 UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000710 }
711
712 /* Update the state of the lock has held in the file descriptor then
713 ** return the appropriate result code.
714 */
715 if( res ){
drh51c6d962004-06-06 00:42:25 +0000716 rc = SQLITE_OK;
717 }else{
drhe54ca3f2004-06-07 01:52:14 +0000718 TRACE4("LOCK FAILED %d trying for %d but got %d\n", id->h,
719 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +0000720 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +0000721 }
drhe54ca3f2004-06-07 01:52:14 +0000722 id->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +0000723 return rc;
724}
725
726/*
drh51c6d962004-06-06 00:42:25 +0000727** This routine checks if there is a RESERVED lock held on the specified
728** file by this or any other process. If such a lock is held, return
729** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +0000730*/
drha6abd042004-06-09 17:37:22 +0000731int sqlite3OsCheckReservedLock(OsFile *id){
drhbbd42a62004-05-22 17:41:58 +0000732 int rc;
drhda71ce12004-06-21 18:14:45 +0000733 assert( id->isOpen );
drh51c6d962004-06-06 00:42:25 +0000734 if( id->locktype>=RESERVED_LOCK ){
735 rc = 1;
drh2ac3ee92004-06-07 16:27:46 +0000736 TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000737 }else{
drhe54ca3f2004-06-07 01:52:14 +0000738 rc = LockFile(id->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000739 if( rc ){
740 UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000741 }
drh2ac3ee92004-06-07 16:27:46 +0000742 rc = !rc;
743 TRACE3("TEST WR-LOCK %d %d (remote)\n", id->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000744 }
drh2ac3ee92004-06-07 16:27:46 +0000745 return rc;
drhbbd42a62004-05-22 17:41:58 +0000746}
747
748/*
drha6abd042004-06-09 17:37:22 +0000749** Lower the locking level on file descriptor id to locktype. locktype
750** must be either NO_LOCK or SHARED_LOCK.
751**
752** If the locking level of the file descriptor is already at or below
753** the requested locking level, this routine is a no-op.
754**
drh9c105bb2004-10-02 20:38:28 +0000755** It is not possible for this routine to fail if the second argument
756** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
757** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000758*/
drha6abd042004-06-09 17:37:22 +0000759int sqlite3OsUnlock(OsFile *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +0000760 int type;
761 int rc = SQLITE_OK;
drhda71ce12004-06-21 18:14:45 +0000762 assert( id->isOpen );
drha6abd042004-06-09 17:37:22 +0000763 assert( locktype<=SHARED_LOCK );
drh3cde3bb2004-06-12 02:17:14 +0000764 TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype,
drha6abd042004-06-09 17:37:22 +0000765 id->locktype, id->sharedLockByte);
drhe54ca3f2004-06-07 01:52:14 +0000766 type = id->locktype;
767 if( type>=EXCLUSIVE_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000768 UnlockFile(id->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drh9c105bb2004-10-02 20:38:28 +0000769 if( locktype==SHARED_LOCK && !getReadLock(id) ){
770 /* This should never happen. We should always be able to
771 ** reacquire the read lock */
772 rc = SQLITE_IOERR;
773 }
drhbbd42a62004-05-22 17:41:58 +0000774 }
drhe54ca3f2004-06-07 01:52:14 +0000775 if( type>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000776 UnlockFile(id->h, RESERVED_BYTE, 0, 1, 0);
777 }
drh9c105bb2004-10-02 20:38:28 +0000778 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000779 unlockReadLock(id);
780 }
drhb3e04342004-06-08 00:47:47 +0000781 if( type>=PENDING_LOCK ){
782 UnlockFile(id->h, PENDING_BYTE, 0, 1, 0);
783 }
drha6abd042004-06-09 17:37:22 +0000784 id->locktype = locktype;
drh9c105bb2004-10-02 20:38:28 +0000785 return rc;
drhbbd42a62004-05-22 17:41:58 +0000786}
787
788/*
drh0ccebe72005-06-07 22:22:50 +0000789** Turn a relative pathname into a full pathname. Return a pointer
790** to the full pathname stored in space obtained from sqliteMalloc().
791** The calling function is responsible for freeing this space once it
792** is no longer needed.
793*/
794char *sqlite3OsFullPathname(const char *zRelative){
795 char *zNotUsed;
796 char *zFull;
drhc0929982005-09-05 19:08:29 +0000797 WCHAR *zWide;
drh0ccebe72005-06-07 22:22:50 +0000798 int nByte;
799#ifdef __CYGWIN__
800 nByte = strlen(zRelative) + MAX_PATH + 1001;
801 zFull = sqliteMalloc( nByte );
802 if( zFull==0 ) return 0;
803 if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
804#else
drhc0929982005-09-05 19:08:29 +0000805 zWide = utf8ToUnicode(zRelative);
806 if( zWide ){
807 WCHAR *zTemp, *zNotUsedW;
808 nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
809 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
810 if( zTemp==0 ) return 0;
811 GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
812 sqliteFree(zWide);
813 zFull = unicodeToUtf8(zTemp);
814 sqliteFree(zTemp);
815 }else{
816 nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
817 zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
818 if( zFull==0 ) return 0;
819 GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
820 }
drh0ccebe72005-06-07 22:22:50 +0000821#endif
822 return zFull;
823}
824
825#endif /* SQLITE_OMIT_DISKIO */
826/***************************************************************************
827** Everything above deals with file I/O. Everything that follows deals
828** with other miscellanous aspects of the operating system interface
829****************************************************************************/
830
831/*
drhbbd42a62004-05-22 17:41:58 +0000832** Get information to seed the random number generator. The seed
833** is written into the buffer zBuf[256]. The calling function must
834** supply a sufficiently large buffer.
835*/
836int sqlite3OsRandomSeed(char *zBuf){
837 /* We have to initialize zBuf to prevent valgrind from reporting
838 ** errors. The reports issued by valgrind are incorrect - we would
839 ** prefer that the randomness be increased by making use of the
840 ** uninitialized space in zBuf - but valgrind errors tend to worry
841 ** some users. Rather than argue, it seems easier just to initialize
842 ** the whole array and silence valgrind, even if that means less randomness
843 ** in the random seed.
844 **
845 ** When testing, initializing zBuf[] to zero is all we do. That means
846 ** that we always use the same random number sequence.* This makes the
847 ** tests repeatable.
848 */
849 memset(zBuf, 0, 256);
850 GetSystemTime((LPSYSTEMTIME)zBuf);
851 return SQLITE_OK;
852}
853
854/*
855** Sleep for a little while. Return the amount of time slept.
856*/
857int sqlite3OsSleep(int ms){
858 Sleep(ms);
859 return ms;
860}
861
862/*
863** Static variables used for thread synchronization
864*/
865static int inMutex = 0;
866#ifdef SQLITE_W32_THREADS
867 static CRITICAL_SECTION cs;
868#endif
869
870/*
871** The following pair of routine implement mutual exclusion for
872** multi-threaded processes. Only a single thread is allowed to
873** executed code that is surrounded by EnterMutex() and LeaveMutex().
874**
875** SQLite uses only a single Mutex. There is not much critical
876** code and what little there is executes quickly and without blocking.
877*/
878void sqlite3OsEnterMutex(){
879#ifdef SQLITE_W32_THREADS
880 static int isInit = 0;
881 while( !isInit ){
882 static long lock = 0;
883 if( InterlockedIncrement(&lock)==1 ){
884 InitializeCriticalSection(&cs);
885 isInit = 1;
886 }else{
887 Sleep(1);
888 }
889 }
890 EnterCriticalSection(&cs);
891#endif
892 assert( !inMutex );
893 inMutex = 1;
894}
895void sqlite3OsLeaveMutex(){
896 assert( inMutex );
897 inMutex = 0;
898#ifdef SQLITE_W32_THREADS
899 LeaveCriticalSection(&cs);
900#endif
901}
902
903/*
drhbbd42a62004-05-22 17:41:58 +0000904** The following variable, if set to a non-zero value, becomes the result
905** returned from sqlite3OsCurrentTime(). This is used for testing.
906*/
907#ifdef SQLITE_TEST
908int sqlite3_current_time = 0;
909#endif
910
911/*
912** Find the current time (in Universal Coordinated Time). Write the
913** current time and date as a Julian Day number into *prNow and
914** return 0. Return 1 if the time and date cannot be found.
915*/
916int sqlite3OsCurrentTime(double *prNow){
917 FILETIME ft;
918 /* FILETIME structure is a 64-bit value representing the number of
919 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
920 */
921 double now;
922 GetSystemTimeAsFileTime( &ft );
923 now = ((double)ft.dwHighDateTime) * 4294967296.0;
924 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
925#ifdef SQLITE_TEST
926 if( sqlite3_current_time ){
927 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
928 }
929#endif
930 return 0;
931}
932
drhbbd42a62004-05-22 17:41:58 +0000933#endif /* OS_WIN */