blob: 2d2341a08974bfab92d43d09f7713f294ddf8e1e [file] [log] [blame]
drhbbd42a62004-05-22 17:41:58 +00001/*
2** 2004 May 22
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
13** This file contains code that is specific to windows.
14*/
drhbbd42a62004-05-22 17:41:58 +000015#include "sqliteInt.h"
drheb206252004-10-01 02:00:31 +000016#include "os.h"
17#if OS_WIN /* This file is used for windows only */
drhbbd42a62004-05-22 17:41:58 +000018
19#include <winbase.h>
20
drh09bf0e82005-03-21 00:36:08 +000021#ifdef __CYGWIN__
22# include <sys/cygwin.h>
23#endif
24
drhbbd42a62004-05-22 17:41:58 +000025/*
26** Macros used to determine whether or not to use threads.
27*/
28#if defined(THREADSAFE) && THREADSAFE
29# define SQLITE_W32_THREADS 1
30#endif
31
32/*
33** Include code that is common to all os_*.c files
34*/
35#include "os_common.h"
36
37/*
drhcc78fea2006-01-06 16:17:05 +000038** Determine if we are dealing with WindowsCE - which has a much
39** reduced API.
40*/
41#if defined(_WIN32_WCE)
42# define OS_WINCE 1
43#else
44# define OS_WINCE 0
45#endif
46
47/*
drh054889e2005-11-30 03:20:31 +000048** The winFile structure is a subclass of OsFile specific to the win32
49** portability layer.
drh9cbe6352005-11-29 03:13:21 +000050*/
drh054889e2005-11-30 03:20:31 +000051typedef struct winFile winFile;
52struct winFile {
53 IoMethod const *pMethod;/* Must be first */
drh9cbe6352005-11-29 03:13:21 +000054 HANDLE h; /* Handle for accessing the file */
55 unsigned char locktype; /* Type of lock currently held on this file */
56 short sharedLockByte; /* Randomly chosen byte used as a shared lock */
drhcc78fea2006-01-06 16:17:05 +000057#if OS_WINCE
drh9e9fe6f2006-01-06 21:09:01 +000058 WCHAR *zDeleteOnClose; /* Name of file to delete when closing */
drhcc78fea2006-01-06 16:17:05 +000059#endif
drh9cbe6352005-11-29 03:13:21 +000060};
61
62
drh9cbe6352005-11-29 03:13:21 +000063/*
drh0ccebe72005-06-07 22:22:50 +000064** Do not include any of the File I/O interface procedures if the
65** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
66** will be in-memory only)
67*/
68#ifndef SQLITE_OMIT_DISKIO
69
70/*
drhc0929982005-09-05 19:08:29 +000071** The following variable is (normally) set once and never changes
72** thereafter. It records whether the operating system is Win95
73** or WinNT.
74**
75** 0: Operating system unknown.
76** 1: Operating system is Win95.
77** 2: Operating system is WinNT.
78**
79** In order to facilitate testing on a WinNT system, the test fixture
80** can manually set this value to 1 to emulate Win98 behavior.
81*/
82int sqlite3_os_type = 0;
83
84/*
drhcc78fea2006-01-06 16:17:05 +000085** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
86** or WinCE. Return false (zero) for Win95, Win98, or WinME.
drhc0929982005-09-05 19:08:29 +000087**
88** Here is an interesting observation: Win95, Win98, and WinME lack
89** the LockFileEx() API. But we can still statically link against that
90** API as long as we don't call it win running Win95/98/ME. A call to
91** this routine is used to determine if the host is Win95/98/ME or
92** WinNT/2K/XP so that we will know whether or not we can safely call
93** the LockFileEx() API.
94*/
drhcc78fea2006-01-06 16:17:05 +000095#if OS_WINCE
96# define isNT() (1)
97#else
98 static int isNT(void){
99 if( sqlite3_os_type==0 ){
100 OSVERSIONINFO sInfo;
101 sInfo.dwOSVersionInfoSize = sizeof(sInfo);
102 GetVersionEx(&sInfo);
103 sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
104 }
105 return sqlite3_os_type==2;
drhc0929982005-09-05 19:08:29 +0000106 }
drhcc78fea2006-01-06 16:17:05 +0000107#endif /* OS_WINCE */
108
109#if OS_WINCE
110/*
111** WindowsCE does not have a localtime() function. So create a
112** substitute.
113*/
114#include <time.h>
115struct tm *__cdecl localtime(const time_t *t)
116{
117 static struct tm y;
118 FILETIME uTm, lTm;
119 SYSTEMTIME pTm;
120 i64 t64;
121 t64 = *t;
122 t64 = (t64 + 11644473600)*10000000;
123 uTm.dwLowDateTime = t64 & 0xFFFFFFFF;
124 uTm.dwHighDateTime= t64 >> 32;
125 FileTimeToLocalFileTime(&uTm,&lTm);
126 FileTimeToSystemTime(&lTm,&pTm);
127 y.tm_year = pTm.wYear - 1900;
128 y.tm_mon = pTm.wMonth - 1;
129 y.tm_wday = pTm.wDayOfWeek;
130 y.tm_mday = pTm.wDay;
131 y.tm_hour = pTm.wHour;
132 y.tm_min = pTm.wMinute;
133 y.tm_sec = pTm.wSecond;
134 return &y;
drhc0929982005-09-05 19:08:29 +0000135}
drhcc78fea2006-01-06 16:17:05 +0000136#endif
137
138/*
139** Compile with -DSQLITE_OMIT_WIN_LOCKS to disable file locking on
140** windows. If you do this and two or more connections attempt to
141** write the database at the same time, the database file will be
142** corrupted. But some versions of WindowsCE do not support locking,
143** in which case compiling with this option is required just to get
144** it to work at all.
145*/
146#ifdef SQLITE_OMIT_WIN_LOCKS
drhe2a926b2006-01-06 20:40:28 +0000147# define LockFile(a,b,c,d,e) (1)
drhcc78fea2006-01-06 16:17:05 +0000148# define LockFileEx(a,b,c,d,e,f) (1)
drhe2a926b2006-01-06 20:40:28 +0000149# define UnlockFile(a,b,c,d,e) (1)
drhcc78fea2006-01-06 16:17:05 +0000150# define UnlockFileEx(a,b,c,d,e) (1)
151#endif
drhc0929982005-09-05 19:08:29 +0000152
153/*
154** Convert a UTF-8 string to UTF-32. Space to hold the returned string
155** is obtained from sqliteMalloc.
156*/
157static WCHAR *utf8ToUnicode(const char *zFilename){
158 int nByte;
159 WCHAR *zWideFilename;
160
161 if( !isNT() ){
162 return 0;
163 }
164 nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
drhd81bd4e2005-09-05 20:06:49 +0000165 zWideFilename = sqliteMalloc( nByte*sizeof(zWideFilename[0]) );
drhc0929982005-09-05 19:08:29 +0000166 if( zWideFilename==0 ){
167 return 0;
168 }
169 nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
170 if( nByte==0 ){
171 sqliteFree(zWideFilename);
172 zWideFilename = 0;
173 }
174 return zWideFilename;
175}
176
177/*
178** Convert UTF-32 to UTF-8. Space to hold the returned string is
179** obtained from sqliteMalloc().
180*/
181static char *unicodeToUtf8(const WCHAR *zWideFilename){
182 int nByte;
183 char *zFilename;
184
185 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
186 zFilename = sqliteMalloc( nByte );
187 if( zFilename==0 ){
188 return 0;
189 }
190 nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
191 0, 0);
192 if( nByte == 0 ){
193 sqliteFree(zFilename);
194 zFilename = 0;
195 }
196 return zFilename;
197}
198
199
200/*
drhbbd42a62004-05-22 17:41:58 +0000201** Delete the named file
202*/
drh66560ad2006-01-06 14:32:19 +0000203int sqlite3WinDelete(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000204 WCHAR *zWide = utf8ToUnicode(zFilename);
205 if( zWide ){
206 DeleteFileW(zWide);
207 sqliteFree(zWide);
208 }else{
drhcc78fea2006-01-06 16:17:05 +0000209#if OS_WINCE
210 return SQLITE_NOMEM;
211#else
drhc0929982005-09-05 19:08:29 +0000212 DeleteFileA(zFilename);
drhcc78fea2006-01-06 16:17:05 +0000213#endif
drhc0929982005-09-05 19:08:29 +0000214 }
drh51c6d962004-06-06 00:42:25 +0000215 TRACE2("DELETE \"%s\"\n", zFilename);
drhbbd42a62004-05-22 17:41:58 +0000216 return SQLITE_OK;
217}
218
219/*
220** Return TRUE if the named file exists.
221*/
drh66560ad2006-01-06 14:32:19 +0000222int sqlite3WinFileExists(const char *zFilename){
drhc0929982005-09-05 19:08:29 +0000223 int exists = 0;
224 WCHAR *zWide = utf8ToUnicode(zFilename);
225 if( zWide ){
226 exists = GetFileAttributesW(zWide) != 0xffffffff;
227 sqliteFree(zWide);
228 }else{
drhcc78fea2006-01-06 16:17:05 +0000229#if OS_WINCE
230 return SQLITE_NOMEM;
231#else
drhc0929982005-09-05 19:08:29 +0000232 exists = GetFileAttributesA(zFilename) != 0xffffffff;
drhcc78fea2006-01-06 16:17:05 +0000233#endif
drhc0929982005-09-05 19:08:29 +0000234 }
235 return exists;
drhbbd42a62004-05-22 17:41:58 +0000236}
237
drh054889e2005-11-30 03:20:31 +0000238/* Forward declaration */
239int allocateWinFile(winFile *pInit, OsFile **pId);
drh9cbe6352005-11-29 03:13:21 +0000240
drhbbd42a62004-05-22 17:41:58 +0000241/*
242** Attempt to open a file for both reading and writing. If that
243** fails, try opening it read-only. If the file does not exist,
244** try to create it.
245**
246** On success, a handle for the open file is written to *id
247** and *pReadonly is set to 0 if the file was opened for reading and
248** writing or 1 if the file was opened read-only. The function returns
249** SQLITE_OK.
250**
251** On failure, the function returns SQLITE_CANTOPEN and leaves
252** *id and *pReadonly unchanged.
253*/
drh66560ad2006-01-06 14:32:19 +0000254int sqlite3WinOpenReadWrite(
drhbbd42a62004-05-22 17:41:58 +0000255 const char *zFilename,
drh9cbe6352005-11-29 03:13:21 +0000256 OsFile **pId,
drhbbd42a62004-05-22 17:41:58 +0000257 int *pReadonly
258){
drh054889e2005-11-30 03:20:31 +0000259 winFile f;
drhda71ce12004-06-21 18:14:45 +0000260 HANDLE h;
drhc0929982005-09-05 19:08:29 +0000261 WCHAR *zWide = utf8ToUnicode(zFilename);
drh9cbe6352005-11-29 03:13:21 +0000262 assert( *pId==0 );
drhc0929982005-09-05 19:08:29 +0000263 if( zWide ){
264 h = CreateFileW(zWide,
265 GENERIC_READ | GENERIC_WRITE,
266 FILE_SHARE_READ | FILE_SHARE_WRITE,
drhbbd42a62004-05-22 17:41:58 +0000267 NULL,
268 OPEN_ALWAYS,
269 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
270 NULL
271 );
272 if( h==INVALID_HANDLE_VALUE ){
drhc0929982005-09-05 19:08:29 +0000273 h = CreateFileW(zWide,
274 GENERIC_READ,
275 FILE_SHARE_READ,
276 NULL,
277 OPEN_ALWAYS,
278 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
279 NULL
280 );
281 if( h==INVALID_HANDLE_VALUE ){
282 sqliteFree(zWide);
283 return SQLITE_CANTOPEN;
284 }
285 *pReadonly = 1;
286 }else{
287 *pReadonly = 0;
drhbbd42a62004-05-22 17:41:58 +0000288 }
drhc0929982005-09-05 19:08:29 +0000289 sqliteFree(zWide);
drhbbd42a62004-05-22 17:41:58 +0000290 }else{
drhcc78fea2006-01-06 16:17:05 +0000291#if OS_WINCE
292 return SQLITE_NOMEM;
293#else
drhc0929982005-09-05 19:08:29 +0000294 h = CreateFileA(zFilename,
295 GENERIC_READ | GENERIC_WRITE,
296 FILE_SHARE_READ | FILE_SHARE_WRITE,
297 NULL,
298 OPEN_ALWAYS,
299 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
300 NULL
301 );
302 if( h==INVALID_HANDLE_VALUE ){
303 h = CreateFileA(zFilename,
304 GENERIC_READ,
305 FILE_SHARE_READ,
306 NULL,
307 OPEN_ALWAYS,
308 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
309 NULL
310 );
311 if( h==INVALID_HANDLE_VALUE ){
312 return SQLITE_CANTOPEN;
313 }
314 *pReadonly = 1;
315 }else{
316 *pReadonly = 0;
317 }
drhcc78fea2006-01-06 16:17:05 +0000318#endif /* OS_WINCE */
drhbbd42a62004-05-22 17:41:58 +0000319 }
drh9cbe6352005-11-29 03:13:21 +0000320 f.h = h;
321 f.locktype = NO_LOCK;
322 f.sharedLockByte = 0;
drh4bddfd22006-01-07 18:14:48 +0000323#if OS_WINCE
324 f.zDeleteOnClose = 0;
325#endif
drh51c6d962004-06-06 00:42:25 +0000326 TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000327 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000328}
329
330
331/*
332** Attempt to open a new file for exclusive access by this process.
333** The file will be opened for both reading and writing. To avoid
334** a potential security problem, we do not allow the file to have
335** previously existed. Nor do we allow the file to be a symbolic
336** link.
337**
338** If delFlag is true, then make arrangements to automatically delete
339** the file when it is closed.
340**
341** On success, write the file handle into *id and return SQLITE_OK.
342**
343** On failure, return SQLITE_CANTOPEN.
344*/
drh66560ad2006-01-06 14:32:19 +0000345int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
drh054889e2005-11-30 03:20:31 +0000346 winFile f;
drhbbd42a62004-05-22 17:41:58 +0000347 HANDLE h;
348 int fileflags;
drhc0929982005-09-05 19:08:29 +0000349 WCHAR *zWide = utf8ToUnicode(zFilename);
drh9cbe6352005-11-29 03:13:21 +0000350 assert( *pId == 0 );
drhcc78fea2006-01-06 16:17:05 +0000351 fileflags = FILE_FLAG_RANDOM_ACCESS;
352#if !OS_WINCE
drhbbd42a62004-05-22 17:41:58 +0000353 if( delFlag ){
drhcc78fea2006-01-06 16:17:05 +0000354 fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
drhbbd42a62004-05-22 17:41:58 +0000355 }
drhcc78fea2006-01-06 16:17:05 +0000356#endif
drhc0929982005-09-05 19:08:29 +0000357 if( zWide ){
358 h = CreateFileW(zWide,
359 GENERIC_READ | GENERIC_WRITE,
360 0,
361 NULL,
362 CREATE_ALWAYS,
363 fileflags,
364 NULL
365 );
366 sqliteFree(zWide);
367 }else{
drhcc78fea2006-01-06 16:17:05 +0000368#if OS_WINCE
369 return SQLITE_NOMEM;
370#else
drhc0929982005-09-05 19:08:29 +0000371 h = CreateFileA(zFilename,
372 GENERIC_READ | GENERIC_WRITE,
373 0,
374 NULL,
375 CREATE_ALWAYS,
376 fileflags,
377 NULL
378 );
drhcc78fea2006-01-06 16:17:05 +0000379#endif /* OS_WINCE */
drhc0929982005-09-05 19:08:29 +0000380 }
drhbbd42a62004-05-22 17:41:58 +0000381 if( h==INVALID_HANDLE_VALUE ){
382 return SQLITE_CANTOPEN;
383 }
drh9cbe6352005-11-29 03:13:21 +0000384 f.h = h;
385 f.locktype = NO_LOCK;
386 f.sharedLockByte = 0;
drhcc78fea2006-01-06 16:17:05 +0000387#if OS_WINCE
drh9e9fe6f2006-01-06 21:09:01 +0000388 f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0;
drhcc78fea2006-01-06 16:17:05 +0000389#endif
drh51c6d962004-06-06 00:42:25 +0000390 TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000391 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000392}
393
394/*
395** Attempt to open a new file for read-only access.
396**
397** On success, write the file handle into *id and return SQLITE_OK.
398**
399** On failure, return SQLITE_CANTOPEN.
400*/
drh66560ad2006-01-06 14:32:19 +0000401int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000402 winFile f;
drhda71ce12004-06-21 18:14:45 +0000403 HANDLE h;
drhc0929982005-09-05 19:08:29 +0000404 WCHAR *zWide = utf8ToUnicode(zFilename);
drh9cbe6352005-11-29 03:13:21 +0000405 assert( *pId==0 );
drhc0929982005-09-05 19:08:29 +0000406 if( zWide ){
407 h = CreateFileW(zWide,
408 GENERIC_READ,
409 0,
410 NULL,
411 OPEN_EXISTING,
412 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
413 NULL
414 );
415 sqliteFree(zWide);
416 }else{
drhcc78fea2006-01-06 16:17:05 +0000417#if OS_WINCE
418 return SQLITE_NOMEM;
419#else
drhc0929982005-09-05 19:08:29 +0000420 h = CreateFileA(zFilename,
421 GENERIC_READ,
422 0,
423 NULL,
424 OPEN_EXISTING,
425 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
426 NULL
427 );
drhcc78fea2006-01-06 16:17:05 +0000428#endif
drhc0929982005-09-05 19:08:29 +0000429 }
drhbbd42a62004-05-22 17:41:58 +0000430 if( h==INVALID_HANDLE_VALUE ){
431 return SQLITE_CANTOPEN;
432 }
drh9cbe6352005-11-29 03:13:21 +0000433 f.h = h;
434 f.locktype = NO_LOCK;
435 f.sharedLockByte = 0;
drh4bddfd22006-01-07 18:14:48 +0000436#if OS_WINCE
437 f.zDeleteOnClose = 0;
438#endif
drh51c6d962004-06-06 00:42:25 +0000439 TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
drh054889e2005-11-30 03:20:31 +0000440 return allocateWinFile(&f, pId);
drhbbd42a62004-05-22 17:41:58 +0000441}
442
443/*
444** Attempt to open a file descriptor for the directory that contains a
445** file. This file descriptor can be used to fsync() the directory
446** in order to make sure the creation of a new file is actually written
447** to disk.
448**
449** This routine is only meaningful for Unix. It is a no-op under
450** windows since windows does not support hard links.
451**
452** On success, a handle for a previously open file is at *id is
453** updated with the new directory file descriptor and SQLITE_OK is
454** returned.
455**
456** On failure, the function returns SQLITE_CANTOPEN and leaves
457** *id unchanged.
458*/
drh9c06c952005-11-26 00:25:00 +0000459static int winOpenDirectory(
drh054889e2005-11-30 03:20:31 +0000460 OsFile *id,
461 const char *zDirname
drhbbd42a62004-05-22 17:41:58 +0000462){
463 return SQLITE_OK;
464}
465
466/*
drh3d2efea2004-08-28 01:12:56 +0000467** If the following global variable points to a string which is the
468** name of a directory, then that directory will be used to store
469** temporary files.
470*/
tpoindex9a09a3c2004-12-20 19:01:32 +0000471char *sqlite3_temp_directory = 0;
drh3d2efea2004-08-28 01:12:56 +0000472
473/*
drhbbd42a62004-05-22 17:41:58 +0000474** Create a temporary file name in zBuf. zBuf must be big enough to
475** hold at least SQLITE_TEMPNAME_SIZE characters.
476*/
drh66560ad2006-01-06 14:32:19 +0000477int sqlite3WinTempFileName(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +0000478 static char zChars[] =
479 "abcdefghijklmnopqrstuvwxyz"
480 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
481 "0123456789";
482 int i, j;
483 char zTempPath[SQLITE_TEMPNAME_SIZE];
drheffd02b2004-08-29 23:42:13 +0000484 if( sqlite3_temp_directory ){
485 strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
drh3d2efea2004-08-28 01:12:56 +0000486 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
drhc0929982005-09-05 19:08:29 +0000487 }else if( isNT() ){
488 char *zMulti;
489 WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
490 GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
491 zMulti = unicodeToUtf8(zWidePath);
492 if( zMulti ){
drhd81bd4e2005-09-05 20:06:49 +0000493 strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
drhc0929982005-09-05 19:08:29 +0000494 zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
495 sqliteFree(zMulti);
496 }
drh3d2efea2004-08-28 01:12:56 +0000497 }else{
498 GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
499 }
drhbbd42a62004-05-22 17:41:58 +0000500 for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
501 zTempPath[i] = 0;
502 for(;;){
503 sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
504 j = strlen(zBuf);
505 sqlite3Randomness(15, &zBuf[j]);
506 for(i=0; i<15; i++, j++){
507 zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
508 }
509 zBuf[j] = 0;
drh66560ad2006-01-06 14:32:19 +0000510 if( !sqlite3OsFileExists(zBuf) ) break;
drhbbd42a62004-05-22 17:41:58 +0000511 }
drh51c6d962004-06-06 00:42:25 +0000512 TRACE2("TEMP FILENAME: %s\n", zBuf);
drhbbd42a62004-05-22 17:41:58 +0000513 return SQLITE_OK;
514}
515
516/*
517** Close a file.
518*/
drh9cbe6352005-11-29 03:13:21 +0000519static int winClose(OsFile **pId){
drh054889e2005-11-30 03:20:31 +0000520 winFile *pFile;
521 if( pId && (pFile = (winFile*)*pId)!=0 ){
522 TRACE2("CLOSE %d\n", pFile->h);
523 CloseHandle(pFile->h);
drhcc78fea2006-01-06 16:17:05 +0000524#if OS_WINCE
525 if( pFile->zDeleteOnClose ){
drh9e9fe6f2006-01-06 21:09:01 +0000526 DeleteFileW(pFile->zDeleteOnClose);
drhcc78fea2006-01-06 16:17:05 +0000527 sqliteFree(pFile->zDeleteOnClose);
528 }
529#endif
drhda71ce12004-06-21 18:14:45 +0000530 OpenCounter(-1);
drh054889e2005-11-30 03:20:31 +0000531 sqliteFree(pFile);
drh9cbe6352005-11-29 03:13:21 +0000532 *pId = 0;
drhda71ce12004-06-21 18:14:45 +0000533 }
drhbbd42a62004-05-22 17:41:58 +0000534 return SQLITE_OK;
535}
536
537/*
538** Read data from a file into a buffer. Return SQLITE_OK if all
539** bytes were read successfully and SQLITE_IOERR if anything goes
540** wrong.
541*/
drh9c06c952005-11-26 00:25:00 +0000542static int winRead(OsFile *id, void *pBuf, int amt){
drhbbd42a62004-05-22 17:41:58 +0000543 DWORD got;
drh9cbe6352005-11-29 03:13:21 +0000544 assert( id!=0 );
drhbbd42a62004-05-22 17:41:58 +0000545 SimulateIOError(SQLITE_IOERR);
drh054889e2005-11-30 03:20:31 +0000546 TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
547 if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
drhbbd42a62004-05-22 17:41:58 +0000548 got = 0;
549 }
550 if( got==(DWORD)amt ){
551 return SQLITE_OK;
552 }else{
553 return SQLITE_IOERR;
554 }
555}
556
557/*
558** Write data from a buffer into a file. Return SQLITE_OK on success
559** or some other error code on failure.
560*/
drh9c06c952005-11-26 00:25:00 +0000561static int winWrite(OsFile *id, const void *pBuf, int amt){
drh4c7f9412005-02-03 00:29:47 +0000562 int rc = 0;
drhbbd42a62004-05-22 17:41:58 +0000563 DWORD wrote;
drh9cbe6352005-11-29 03:13:21 +0000564 assert( id!=0 );
drhbbd42a62004-05-22 17:41:58 +0000565 SimulateIOError(SQLITE_IOERR);
dougcurrie0924bba2004-10-01 18:21:43 +0000566 SimulateDiskfullError;
drh054889e2005-11-30 03:20:31 +0000567 TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
drh4c7f9412005-02-03 00:29:47 +0000568 assert( amt>0 );
drh054889e2005-11-30 03:20:31 +0000569 while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
570 && wrote>0 ){
drhbbd42a62004-05-22 17:41:58 +0000571 amt -= wrote;
572 pBuf = &((char*)pBuf)[wrote];
573 }
574 if( !rc || amt>(int)wrote ){
575 return SQLITE_FULL;
576 }
577 return SQLITE_OK;
578}
579
580/*
drhbbdc2b92005-09-19 12:53:18 +0000581** Some microsoft compilers lack this definition.
582*/
583#ifndef INVALID_SET_FILE_POINTER
584# define INVALID_SET_FILE_POINTER ((DWORD)-1)
585#endif
586
587/*
drhbbd42a62004-05-22 17:41:58 +0000588** Move the read/write pointer in a file.
589*/
drh9c06c952005-11-26 00:25:00 +0000590static int winSeek(OsFile *id, i64 offset){
drhbbd42a62004-05-22 17:41:58 +0000591 LONG upperBits = offset>>32;
592 LONG lowerBits = offset & 0xffffffff;
593 DWORD rc;
drh9cbe6352005-11-29 03:13:21 +0000594 assert( id!=0 );
drhb4746b92005-09-09 01:32:06 +0000595#ifdef SQLITE_TEST
596 if( offset ) SimulateDiskfullError
597#endif
drhbbd42a62004-05-22 17:41:58 +0000598 SEEK(offset/1024 + 1);
drh054889e2005-11-30 03:20:31 +0000599 rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
600 TRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
drhe08b8142005-09-09 10:17:33 +0000601 if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
602 return SQLITE_FULL;
603 }
drhbbd42a62004-05-22 17:41:58 +0000604 return SQLITE_OK;
605}
606
607/*
608** Make sure all writes to a particular file are committed to disk.
609*/
drh9c06c952005-11-26 00:25:00 +0000610static int winSync(OsFile *id, int dataOnly){
drh9cbe6352005-11-29 03:13:21 +0000611 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +0000612 TRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
613 if( FlushFileBuffers(((winFile*)id)->h) ){
drhbbd42a62004-05-22 17:41:58 +0000614 return SQLITE_OK;
615 }else{
616 return SQLITE_IOERR;
617 }
618}
619
620/*
danielk1977962398d2004-06-14 09:35:16 +0000621** Sync the directory zDirname. This is a no-op on operating systems other
622** than UNIX.
623*/
drh66560ad2006-01-06 14:32:19 +0000624int sqlite3WinSyncDirectory(const char *zDirname){
danielk1977369f27e2004-06-15 11:40:04 +0000625 SimulateIOError(SQLITE_IOERR);
danielk1977962398d2004-06-14 09:35:16 +0000626 return SQLITE_OK;
627}
628
629/*
drhbbd42a62004-05-22 17:41:58 +0000630** Truncate an open file to a specified size
631*/
drh9c06c952005-11-26 00:25:00 +0000632static int winTruncate(OsFile *id, i64 nByte){
drhbbd42a62004-05-22 17:41:58 +0000633 LONG upperBits = nByte>>32;
drh9cbe6352005-11-29 03:13:21 +0000634 assert( id!=0 );
drh054889e2005-11-30 03:20:31 +0000635 TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
drhbbd42a62004-05-22 17:41:58 +0000636 SimulateIOError(SQLITE_IOERR);
drh054889e2005-11-30 03:20:31 +0000637 SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
638 SetEndOfFile(((winFile*)id)->h);
drhbbd42a62004-05-22 17:41:58 +0000639 return SQLITE_OK;
640}
641
642/*
643** Determine the current size of a file in bytes
644*/
drh9c06c952005-11-26 00:25:00 +0000645static int winFileSize(OsFile *id, i64 *pSize){
drhbbd42a62004-05-22 17:41:58 +0000646 DWORD upperBits, lowerBits;
drh9cbe6352005-11-29 03:13:21 +0000647 assert( id!=0 );
drhbbd42a62004-05-22 17:41:58 +0000648 SimulateIOError(SQLITE_IOERR);
drh054889e2005-11-30 03:20:31 +0000649 lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
drheb206252004-10-01 02:00:31 +0000650 *pSize = (((i64)upperBits)<<32) + lowerBits;
drhbbd42a62004-05-22 17:41:58 +0000651 return SQLITE_OK;
652}
653
654/*
drh602bbd32006-01-06 20:22:29 +0000655** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
656*/
657#ifndef LOCKFILE_FAIL_IMMEDIATELY
658# define LOCKFILE_FAIL_IMMEDIATELY 1
659#endif
660
661/*
drh9c105bb2004-10-02 20:38:28 +0000662** Acquire a reader lock.
drh51c6d962004-06-06 00:42:25 +0000663** Different API routines are called depending on whether or not this
664** is Win95 or WinNT.
665*/
drh054889e2005-11-30 03:20:31 +0000666static int getReadLock(winFile *id){
drh51c6d962004-06-06 00:42:25 +0000667 int res;
668 if( isNT() ){
669 OVERLAPPED ovlp;
drh9c105bb2004-10-02 20:38:28 +0000670 ovlp.Offset = SHARED_FIRST;
drh51c6d962004-06-06 00:42:25 +0000671 ovlp.OffsetHigh = 0;
672 ovlp.hEvent = 0;
drh9c105bb2004-10-02 20:38:28 +0000673 res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
drhbbd42a62004-05-22 17:41:58 +0000674 }else{
drh9c105bb2004-10-02 20:38:28 +0000675 int lk;
676 sqlite3Randomness(sizeof(lk), &lk);
677 id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
678 res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000679 }
680 return res;
681}
682
683/*
684** Undo a readlock
685*/
drh054889e2005-11-30 03:20:31 +0000686static int unlockReadLock(winFile *pFile){
drh51c6d962004-06-06 00:42:25 +0000687 int res;
688 if( isNT() ){
drh054889e2005-11-30 03:20:31 +0000689 res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drh51c6d962004-06-06 00:42:25 +0000690 }else{
drh054889e2005-11-30 03:20:31 +0000691 res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000692 }
693 return res;
694}
695
drh268283b2005-01-08 15:44:25 +0000696#ifndef SQLITE_OMIT_PAGER_PRAGMAS
drh51c6d962004-06-06 00:42:25 +0000697/*
tpoindex9a09a3c2004-12-20 19:01:32 +0000698** Check that a given pathname is a directory and is writable
699**
700*/
drh66560ad2006-01-06 14:32:19 +0000701int sqlite3WinIsDirWritable(char *zDirname){
tpoindex9a09a3c2004-12-20 19:01:32 +0000702 int fileAttr;
drhc0929982005-09-05 19:08:29 +0000703 WCHAR *zWide;
704 if( zDirname==0 ) return 0;
705 if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
706 zWide = utf8ToUnicode(zDirname);
707 if( zWide ){
708 fileAttr = GetFileAttributesW(zWide);
709 sqliteFree(zWide);
710 }else{
drhcc78fea2006-01-06 16:17:05 +0000711#if OS_WINCE
712 return 0;
713#else
drhc0929982005-09-05 19:08:29 +0000714 fileAttr = GetFileAttributesA(zDirname);
drhcc78fea2006-01-06 16:17:05 +0000715#endif
drhc0929982005-09-05 19:08:29 +0000716 }
tpoindex9a09a3c2004-12-20 19:01:32 +0000717 if( fileAttr == 0xffffffff ) return 0;
drh268283b2005-01-08 15:44:25 +0000718 if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
719 return 0;
720 }
tpoindex9a09a3c2004-12-20 19:01:32 +0000721 return 1;
722}
drh268283b2005-01-08 15:44:25 +0000723#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
tpoindex9a09a3c2004-12-20 19:01:32 +0000724
725/*
drhb3e04342004-06-08 00:47:47 +0000726** Lock the file with the lock specified by parameter locktype - one
727** of the following:
728**
729** (1) SHARED_LOCK
730** (2) RESERVED_LOCK
731** (3) PENDING_LOCK
732** (4) EXCLUSIVE_LOCK
733**
734** Sometimes when requesting one lock state, additional lock states
735** are inserted in between. The locking might fail on one of the later
736** transitions leaving the lock state different from what it started but
737** still short of its goal. The following chart shows the allowed
738** transitions and the inserted intermediate states:
739**
740** UNLOCKED -> SHARED
741** SHARED -> RESERVED
742** SHARED -> (PENDING) -> EXCLUSIVE
743** RESERVED -> (PENDING) -> EXCLUSIVE
744** PENDING -> EXCLUSIVE
745**
drh9c06c952005-11-26 00:25:00 +0000746** This routine will only increase a lock. The winUnlock() routine
drhb3e04342004-06-08 00:47:47 +0000747** erases all locks at once and returns us immediately to locking level 0.
748** It is not possible to lower the locking level one step at a time. You
749** must go straight to locking level 0.
drh51c6d962004-06-06 00:42:25 +0000750*/
drh9c06c952005-11-26 00:25:00 +0000751static int winLock(OsFile *id, int locktype){
drh51c6d962004-06-06 00:42:25 +0000752 int rc = SQLITE_OK; /* Return code from subroutines */
753 int res = 1; /* Result of a windows lock call */
drhe54ca3f2004-06-07 01:52:14 +0000754 int newLocktype; /* Set id->locktype to this value before exiting */
755 int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
drh054889e2005-11-30 03:20:31 +0000756 winFile *pFile = (winFile*)id;
drh51c6d962004-06-06 00:42:25 +0000757
drh054889e2005-11-30 03:20:31 +0000758 assert( pFile!=0 );
drhe54ca3f2004-06-07 01:52:14 +0000759 TRACE5("LOCK %d %d was %d(%d)\n",
drh054889e2005-11-30 03:20:31 +0000760 pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);
drh51c6d962004-06-06 00:42:25 +0000761
762 /* If there is already a lock of this type or more restrictive on the
763 ** OsFile, do nothing. Don't use the end_lock: exit path, as
764 ** sqlite3OsEnterMutex() hasn't been called yet.
765 */
drh054889e2005-11-30 03:20:31 +0000766 if( pFile->locktype>=locktype ){
drh51c6d962004-06-06 00:42:25 +0000767 return SQLITE_OK;
768 }
769
drhb3e04342004-06-08 00:47:47 +0000770 /* Make sure the locking sequence is correct
771 */
drh054889e2005-11-30 03:20:31 +0000772 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000773 assert( locktype!=PENDING_LOCK );
drh054889e2005-11-30 03:20:31 +0000774 assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
drhb3e04342004-06-08 00:47:47 +0000775
drh51c6d962004-06-06 00:42:25 +0000776 /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
777 ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
778 ** the PENDING_LOCK byte is temporary.
779 */
drh054889e2005-11-30 03:20:31 +0000780 newLocktype = pFile->locktype;
781 if( pFile->locktype==NO_LOCK
782 || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)
drhe54ca3f2004-06-07 01:52:14 +0000783 ){
drhb3e04342004-06-08 00:47:47 +0000784 int cnt = 3;
drh054889e2005-11-30 03:20:31 +0000785 while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){
drhb3e04342004-06-08 00:47:47 +0000786 /* Try 3 times to get the pending lock. The pending lock might be
drh51c6d962004-06-06 00:42:25 +0000787 ** held by another reader process who will release it momentarily.
788 */
drhe54ca3f2004-06-07 01:52:14 +0000789 TRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
drhbbd42a62004-05-22 17:41:58 +0000790 Sleep(1);
791 }
drhe54ca3f2004-06-07 01:52:14 +0000792 gotPendingLock = res;
drh51c6d962004-06-06 00:42:25 +0000793 }
794
795 /* Acquire a shared lock
796 */
drhb3e04342004-06-08 00:47:47 +0000797 if( locktype==SHARED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000798 assert( pFile->locktype==NO_LOCK );
799 res = getReadLock(pFile);
drhe54ca3f2004-06-07 01:52:14 +0000800 if( res ){
801 newLocktype = SHARED_LOCK;
drh51c6d962004-06-06 00:42:25 +0000802 }
803 }
804
805 /* Acquire a RESERVED lock
806 */
drhb3e04342004-06-08 00:47:47 +0000807 if( locktype==RESERVED_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000808 assert( pFile->locktype==SHARED_LOCK );
809 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhe54ca3f2004-06-07 01:52:14 +0000810 if( res ){
811 newLocktype = RESERVED_LOCK;
812 }
813 }
814
815 /* Acquire a PENDING lock
816 */
drhb3e04342004-06-08 00:47:47 +0000817 if( locktype==EXCLUSIVE_LOCK && res ){
drhe54ca3f2004-06-07 01:52:14 +0000818 newLocktype = PENDING_LOCK;
819 gotPendingLock = 0;
drh51c6d962004-06-06 00:42:25 +0000820 }
821
822 /* Acquire an EXCLUSIVE lock
823 */
drhe54ca3f2004-06-07 01:52:14 +0000824 if( locktype==EXCLUSIVE_LOCK && res ){
drh054889e2005-11-30 03:20:31 +0000825 assert( pFile->locktype>=SHARED_LOCK );
826 res = unlockReadLock(pFile);
drhb3e04342004-06-08 00:47:47 +0000827 TRACE2("unreadlock = %d\n", res);
drh054889e2005-11-30 03:20:31 +0000828 res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
drhe54ca3f2004-06-07 01:52:14 +0000829 if( res ){
830 newLocktype = EXCLUSIVE_LOCK;
831 }else{
832 TRACE2("error-code = %d\n", GetLastError());
833 }
834 }
835
836 /* If we are holding a PENDING lock that ought to be released, then
837 ** release it now.
838 */
drhb3e04342004-06-08 00:47:47 +0000839 if( gotPendingLock && locktype==SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000840 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000841 }
842
843 /* Update the state of the lock has held in the file descriptor then
844 ** return the appropriate result code.
845 */
846 if( res ){
drh51c6d962004-06-06 00:42:25 +0000847 rc = SQLITE_OK;
848 }else{
drh054889e2005-11-30 03:20:31 +0000849 TRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,
drhe54ca3f2004-06-07 01:52:14 +0000850 locktype, newLocktype);
drh51c6d962004-06-06 00:42:25 +0000851 rc = SQLITE_BUSY;
drhbbd42a62004-05-22 17:41:58 +0000852 }
drh054889e2005-11-30 03:20:31 +0000853 pFile->locktype = newLocktype;
drhbbd42a62004-05-22 17:41:58 +0000854 return rc;
855}
856
857/*
drh51c6d962004-06-06 00:42:25 +0000858** This routine checks if there is a RESERVED lock held on the specified
859** file by this or any other process. If such a lock is held, return
860** non-zero, otherwise zero.
drhbbd42a62004-05-22 17:41:58 +0000861*/
drh9c06c952005-11-26 00:25:00 +0000862static int winCheckReservedLock(OsFile *id){
drhbbd42a62004-05-22 17:41:58 +0000863 int rc;
drh054889e2005-11-30 03:20:31 +0000864 winFile *pFile = (winFile*)id;
865 assert( pFile!=0 );
866 if( pFile->locktype>=RESERVED_LOCK ){
drh51c6d962004-06-06 00:42:25 +0000867 rc = 1;
drh054889e2005-11-30 03:20:31 +0000868 TRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000869 }else{
drh054889e2005-11-30 03:20:31 +0000870 rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000871 if( rc ){
drh054889e2005-11-30 03:20:31 +0000872 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drhbbd42a62004-05-22 17:41:58 +0000873 }
drh2ac3ee92004-06-07 16:27:46 +0000874 rc = !rc;
drh054889e2005-11-30 03:20:31 +0000875 TRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
drhbbd42a62004-05-22 17:41:58 +0000876 }
drh2ac3ee92004-06-07 16:27:46 +0000877 return rc;
drhbbd42a62004-05-22 17:41:58 +0000878}
879
880/*
drha6abd042004-06-09 17:37:22 +0000881** Lower the locking level on file descriptor id to locktype. locktype
882** must be either NO_LOCK or SHARED_LOCK.
883**
884** If the locking level of the file descriptor is already at or below
885** the requested locking level, this routine is a no-op.
886**
drh9c105bb2004-10-02 20:38:28 +0000887** It is not possible for this routine to fail if the second argument
888** is NO_LOCK. If the second argument is SHARED_LOCK then this routine
889** might return SQLITE_IOERR;
drhbbd42a62004-05-22 17:41:58 +0000890*/
drh9c06c952005-11-26 00:25:00 +0000891static int winUnlock(OsFile *id, int locktype){
drh9c105bb2004-10-02 20:38:28 +0000892 int type;
893 int rc = SQLITE_OK;
drh054889e2005-11-30 03:20:31 +0000894 winFile *pFile = (winFile*)id;
895 assert( pFile!=0 );
drha6abd042004-06-09 17:37:22 +0000896 assert( locktype<=SHARED_LOCK );
drh054889e2005-11-30 03:20:31 +0000897 TRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
898 pFile->locktype, pFile->sharedLockByte);
899 type = pFile->locktype;
drhe54ca3f2004-06-07 01:52:14 +0000900 if( type>=EXCLUSIVE_LOCK ){
drh054889e2005-11-30 03:20:31 +0000901 UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
902 if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
drh9c105bb2004-10-02 20:38:28 +0000903 /* This should never happen. We should always be able to
904 ** reacquire the read lock */
905 rc = SQLITE_IOERR;
906 }
drhbbd42a62004-05-22 17:41:58 +0000907 }
drhe54ca3f2004-06-07 01:52:14 +0000908 if( type>=RESERVED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000909 UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
drh51c6d962004-06-06 00:42:25 +0000910 }
drh9c105bb2004-10-02 20:38:28 +0000911 if( locktype==NO_LOCK && type>=SHARED_LOCK ){
drh054889e2005-11-30 03:20:31 +0000912 unlockReadLock(pFile);
drh51c6d962004-06-06 00:42:25 +0000913 }
drhb3e04342004-06-08 00:47:47 +0000914 if( type>=PENDING_LOCK ){
drh054889e2005-11-30 03:20:31 +0000915 UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
drhb3e04342004-06-08 00:47:47 +0000916 }
drh054889e2005-11-30 03:20:31 +0000917 pFile->locktype = locktype;
drh9c105bb2004-10-02 20:38:28 +0000918 return rc;
drhbbd42a62004-05-22 17:41:58 +0000919}
920
921/*
drh0ccebe72005-06-07 22:22:50 +0000922** Turn a relative pathname into a full pathname. Return a pointer
923** to the full pathname stored in space obtained from sqliteMalloc().
924** The calling function is responsible for freeing this space once it
925** is no longer needed.
926*/
drh66560ad2006-01-06 14:32:19 +0000927char *sqlite3WinFullPathname(const char *zRelative){
drh0ccebe72005-06-07 22:22:50 +0000928 char *zFull;
drhcc78fea2006-01-06 16:17:05 +0000929#if defined(__CYGWIN__)
drh0ccebe72005-06-07 22:22:50 +0000930 int nByte;
drh0ccebe72005-06-07 22:22:50 +0000931 nByte = strlen(zRelative) + MAX_PATH + 1001;
932 zFull = sqliteMalloc( nByte );
933 if( zFull==0 ) return 0;
934 if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
drhcc78fea2006-01-06 16:17:05 +0000935#elif OS_WINCE
936 /* WinCE has no concept of a relative pathname, or so I am told. */
danielk1977e7259292006-01-13 06:33:23 +0000937 zFull = sqliteStrDup(zRelative);
drh0ccebe72005-06-07 22:22:50 +0000938#else
drhcc78fea2006-01-06 16:17:05 +0000939 char *zNotUsed;
940 WCHAR *zWide;
941 int nByte;
drhc0929982005-09-05 19:08:29 +0000942 zWide = utf8ToUnicode(zRelative);
943 if( zWide ){
944 WCHAR *zTemp, *zNotUsedW;
945 nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
946 zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
947 if( zTemp==0 ) return 0;
948 GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
949 sqliteFree(zWide);
950 zFull = unicodeToUtf8(zTemp);
951 sqliteFree(zTemp);
952 }else{
953 nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
954 zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
955 if( zFull==0 ) return 0;
956 GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
957 }
drh0ccebe72005-06-07 22:22:50 +0000958#endif
959 return zFull;
960}
961
drh9c06c952005-11-26 00:25:00 +0000962/*
drh9cbe6352005-11-29 03:13:21 +0000963** The fullSync option is meaningless on windows. This is a no-op.
drh18839212005-11-26 03:43:23 +0000964*/
drh9cbe6352005-11-29 03:13:21 +0000965static void winSetFullSync(OsFile *id, int v){
966 return;
967}
968
969/*
970** Return the underlying file handle for an OsFile
971*/
972static int winFileHandle(OsFile *id){
drh054889e2005-11-30 03:20:31 +0000973 return (int)((winFile*)id)->h;
drh9cbe6352005-11-29 03:13:21 +0000974}
975
976/*
977** Return an integer that indices the type of lock currently held
978** by this handle. (Used for testing and analysis only.)
979*/
980static int winLockState(OsFile *id){
drh054889e2005-11-30 03:20:31 +0000981 return ((winFile*)id)->locktype;
drh18839212005-11-26 03:43:23 +0000982}
983
drh18839212005-11-26 03:43:23 +0000984/*
drh054889e2005-11-30 03:20:31 +0000985** This vector defines all the methods that can operate on an OsFile
986** for win32.
drh9c06c952005-11-26 00:25:00 +0000987*/
drh054889e2005-11-30 03:20:31 +0000988static const IoMethod sqlite3WinIoMethod = {
drh9c06c952005-11-26 00:25:00 +0000989 winClose,
drh054889e2005-11-30 03:20:31 +0000990 winOpenDirectory,
drh9c06c952005-11-26 00:25:00 +0000991 winRead,
992 winWrite,
993 winSeek,
drh9c06c952005-11-26 00:25:00 +0000994 winTruncate,
drh054889e2005-11-30 03:20:31 +0000995 winSync,
drh9cbe6352005-11-29 03:13:21 +0000996 winSetFullSync,
997 winFileHandle,
drh054889e2005-11-30 03:20:31 +0000998 winFileSize,
999 winLock,
1000 winUnlock,
drh9cbe6352005-11-29 03:13:21 +00001001 winLockState,
drh054889e2005-11-30 03:20:31 +00001002 winCheckReservedLock,
drh9c06c952005-11-26 00:25:00 +00001003};
1004
drh054889e2005-11-30 03:20:31 +00001005/*
1006** Allocate memory for an OsFile. Initialize the new OsFile
1007** to the value given in pInit and return a pointer to the new
1008** OsFile. If we run out of memory, close the file and return NULL.
1009*/
1010int allocateWinFile(winFile *pInit, OsFile **pId){
1011 winFile *pNew;
1012 pNew = sqliteMalloc( sizeof(*pNew) );
1013 if( pNew==0 ){
1014 CloseHandle(pInit->h);
drhcc78fea2006-01-06 16:17:05 +00001015#if OS_WINCE
1016 sqliteFree(pInit->zDeleteOnClose);
1017#endif
drh054889e2005-11-30 03:20:31 +00001018 *pId = 0;
1019 return SQLITE_NOMEM;
1020 }else{
1021 *pNew = *pInit;
1022 pNew->pMethod = &sqlite3WinIoMethod;
drh66560ad2006-01-06 14:32:19 +00001023 *pId = (OsFile*)pNew;
drh054889e2005-11-30 03:20:31 +00001024 return SQLITE_OK;
1025 }
1026}
1027
1028
drh0ccebe72005-06-07 22:22:50 +00001029#endif /* SQLITE_OMIT_DISKIO */
1030/***************************************************************************
1031** Everything above deals with file I/O. Everything that follows deals
1032** with other miscellanous aspects of the operating system interface
1033****************************************************************************/
1034
1035/*
drhbbd42a62004-05-22 17:41:58 +00001036** Get information to seed the random number generator. The seed
1037** is written into the buffer zBuf[256]. The calling function must
1038** supply a sufficiently large buffer.
1039*/
drh66560ad2006-01-06 14:32:19 +00001040int sqlite3WinRandomSeed(char *zBuf){
drhbbd42a62004-05-22 17:41:58 +00001041 /* We have to initialize zBuf to prevent valgrind from reporting
1042 ** errors. The reports issued by valgrind are incorrect - we would
1043 ** prefer that the randomness be increased by making use of the
1044 ** uninitialized space in zBuf - but valgrind errors tend to worry
1045 ** some users. Rather than argue, it seems easier just to initialize
1046 ** the whole array and silence valgrind, even if that means less randomness
1047 ** in the random seed.
1048 **
1049 ** When testing, initializing zBuf[] to zero is all we do. That means
1050 ** that we always use the same random number sequence.* This makes the
1051 ** tests repeatable.
1052 */
1053 memset(zBuf, 0, 256);
1054 GetSystemTime((LPSYSTEMTIME)zBuf);
1055 return SQLITE_OK;
1056}
1057
1058/*
1059** Sleep for a little while. Return the amount of time slept.
1060*/
drh66560ad2006-01-06 14:32:19 +00001061int sqlite3WinSleep(int ms){
drhbbd42a62004-05-22 17:41:58 +00001062 Sleep(ms);
1063 return ms;
1064}
1065
1066/*
1067** Static variables used for thread synchronization
1068*/
1069static int inMutex = 0;
1070#ifdef SQLITE_W32_THREADS
drh332b1fe2006-01-18 14:20:17 +00001071 static HANDLE mutexOwner;
drhbbd42a62004-05-22 17:41:58 +00001072 static CRITICAL_SECTION cs;
1073#endif
1074
1075/*
1076** The following pair of routine implement mutual exclusion for
1077** multi-threaded processes. Only a single thread is allowed to
1078** executed code that is surrounded by EnterMutex() and LeaveMutex().
1079**
1080** SQLite uses only a single Mutex. There is not much critical
1081** code and what little there is executes quickly and without blocking.
1082*/
drh66560ad2006-01-06 14:32:19 +00001083void sqlite3WinEnterMutex(){
drhbbd42a62004-05-22 17:41:58 +00001084#ifdef SQLITE_W32_THREADS
1085 static int isInit = 0;
1086 while( !isInit ){
1087 static long lock = 0;
1088 if( InterlockedIncrement(&lock)==1 ){
1089 InitializeCriticalSection(&cs);
1090 isInit = 1;
1091 }else{
1092 Sleep(1);
1093 }
1094 }
1095 EnterCriticalSection(&cs);
drh332b1fe2006-01-18 14:20:17 +00001096 mutexOwner = GetCurrentThread();
drhbbd42a62004-05-22 17:41:58 +00001097#endif
drh332b1fe2006-01-18 14:20:17 +00001098 inMutex++;
drhbbd42a62004-05-22 17:41:58 +00001099}
drh66560ad2006-01-06 14:32:19 +00001100void sqlite3WinLeaveMutex(){
drhbbd42a62004-05-22 17:41:58 +00001101 assert( inMutex );
drh332b1fe2006-01-18 14:20:17 +00001102 inMutex--;
drhbbd42a62004-05-22 17:41:58 +00001103#ifdef SQLITE_W32_THREADS
1104 LeaveCriticalSection(&cs);
1105#endif
1106}
1107
1108/*
drh88f474a2006-01-02 20:00:12 +00001109** Return TRUE if we are currently within the mutex and FALSE if not.
drh88f474a2006-01-02 20:00:12 +00001110*/
drh66560ad2006-01-06 14:32:19 +00001111int sqlite3WinInMutex(){
drh332b1fe2006-01-18 14:20:17 +00001112#ifdef SQLITE_W32_THREADS
1113 return inMutex && mutexOwner==GetCurrentThread();
1114#else
drh88f474a2006-01-02 20:00:12 +00001115 return inMutex;
drh332b1fe2006-01-18 14:20:17 +00001116#endif
drh88f474a2006-01-02 20:00:12 +00001117}
1118
1119
1120/*
drhbbd42a62004-05-22 17:41:58 +00001121** The following variable, if set to a non-zero value, becomes the result
1122** returned from sqlite3OsCurrentTime(). This is used for testing.
1123*/
1124#ifdef SQLITE_TEST
1125int sqlite3_current_time = 0;
1126#endif
1127
1128/*
1129** Find the current time (in Universal Coordinated Time). Write the
1130** current time and date as a Julian Day number into *prNow and
1131** return 0. Return 1 if the time and date cannot be found.
1132*/
drh66560ad2006-01-06 14:32:19 +00001133int sqlite3WinCurrentTime(double *prNow){
drhbbd42a62004-05-22 17:41:58 +00001134 FILETIME ft;
1135 /* FILETIME structure is a 64-bit value representing the number of
1136 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
1137 */
1138 double now;
drhcc78fea2006-01-06 16:17:05 +00001139#if OS_WINCE
1140 SYSTEMTIME time;
1141 GetSystemTime(&time);
1142 SystemTimeToFileTime(&time,&ft);
1143#else
drhbbd42a62004-05-22 17:41:58 +00001144 GetSystemTimeAsFileTime( &ft );
drhcc78fea2006-01-06 16:17:05 +00001145#endif
drhbbd42a62004-05-22 17:41:58 +00001146 now = ((double)ft.dwHighDateTime) * 4294967296.0;
1147 *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
1148#ifdef SQLITE_TEST
1149 if( sqlite3_current_time ){
1150 *prNow = sqlite3_current_time/86400.0 + 2440587.5;
1151 }
1152#endif
1153 return 0;
1154}
1155
drh6f7adc82006-01-11 21:41:20 +00001156/*
drhb4bc7052006-01-11 23:40:33 +00001157** Remember the number of thread-specific-data blocks allocated.
1158** Use this to verify that we are not leaking thread-specific-data.
1159** Ticket #1601
1160*/
1161#ifdef SQLITE_TEST
1162int sqlite3_tsd_count = 0;
1163# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
1164# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
1165#else
1166# define TSD_COUNTER_INCR /* no-op */
1167# define TSD_COUNTER_DECR /* no-op */
1168#endif
1169
1170
1171
1172/*
drh70ff98a2006-01-12 01:25:18 +00001173** If called with allocateFlag>1, then return a pointer to thread
drh6f7adc82006-01-11 21:41:20 +00001174** specific data for the current thread. Allocate and zero the
1175** thread-specific data if it does not already exist necessary.
drh3fbb0b12006-01-06 00:36:00 +00001176**
drh6f7adc82006-01-11 21:41:20 +00001177** If called with allocateFlag==0, then check the current thread
drh70ff98a2006-01-12 01:25:18 +00001178** specific data. Return it if it exists. If it does not exist,
1179** then return NULL.
1180**
1181** If called with allocateFlag<0, check to see if the thread specific
1182** data is allocated and is all zero. If it is then deallocate it.
drh6f7adc82006-01-11 21:41:20 +00001183** Return a pointer to the thread specific data or NULL if it is
drh70ff98a2006-01-12 01:25:18 +00001184** unallocated or gets deallocated.
danielk197713a68c32005-12-15 10:11:30 +00001185*/
drhb4bc7052006-01-11 23:40:33 +00001186ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
drh3fbb0b12006-01-06 00:36:00 +00001187 static int key;
1188 static int keyInit = 0;
drh6f7adc82006-01-11 21:41:20 +00001189 static const ThreadData zeroData;
drhb4bc7052006-01-11 23:40:33 +00001190 ThreadData *pTsd;
drh3fbb0b12006-01-06 00:36:00 +00001191
1192 if( !keyInit ){
drh66560ad2006-01-06 14:32:19 +00001193 sqlite3OsEnterMutex();
drh3fbb0b12006-01-06 00:36:00 +00001194 if( !keyInit ){
1195 key = TlsAlloc();
1196 if( key==0xffffffff ){
drh66560ad2006-01-06 14:32:19 +00001197 sqlite3OsLeaveMutex();
drh3fbb0b12006-01-06 00:36:00 +00001198 return 0;
1199 }
1200 keyInit = 1;
1201 }
drh66560ad2006-01-06 14:32:19 +00001202 sqlite3OsLeaveMutex();
danielk197713a68c32005-12-15 10:11:30 +00001203 }
drh3fbb0b12006-01-06 00:36:00 +00001204 pTsd = TlsGetValue(key);
drh70ff98a2006-01-12 01:25:18 +00001205 if( allocateFlag>0 ){
drh6f7adc82006-01-11 21:41:20 +00001206 if( !pTsd ){
drhb4bc7052006-01-11 23:40:33 +00001207 pTsd = sqlite3OsMalloc( sizeof(zeroData) );
drh6f7adc82006-01-11 21:41:20 +00001208 if( pTsd ){
1209 *pTsd = zeroData;
1210 TlsSetValue(key, pTsd);
drhb4bc7052006-01-11 23:40:33 +00001211 TSD_COUNTER_INCR;
drh6f7adc82006-01-11 21:41:20 +00001212 }
drh3fbb0b12006-01-06 00:36:00 +00001213 }
drh70ff98a2006-01-12 01:25:18 +00001214 }else if( pTsd!=0 && allocateFlag<0
danielk1977cbb84962006-01-17 16:10:13 +00001215 && memcmp(pTsd, &zeroData, THREADDATASIZE)==0 ){
drh6f7adc82006-01-11 21:41:20 +00001216 sqlite3OsFree(pTsd);
1217 TlsSetValue(key, 0);
drhb4bc7052006-01-11 23:40:33 +00001218 TSD_COUNTER_DECR;
drh6f7adc82006-01-11 21:41:20 +00001219 pTsd = 0;
drh3fbb0b12006-01-06 00:36:00 +00001220 }
1221 return pTsd;
danielk197713a68c32005-12-15 10:11:30 +00001222}
drhbbd42a62004-05-22 17:41:58 +00001223#endif /* OS_WIN */