📄 os_win.c
字号:
isTemp = 1; }else{ dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; isTemp = 0; } /* Reports from the internet are that performance is always ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; if( isNT() ){ h = CreateFileW((WCHAR*)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL ); }else{ h = CreateFileA((char*)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL ); } if( h==INVALID_HANDLE_VALUE ){ free(zConverted); if( flags & SQLITE_OPEN_READWRITE ){ return winOpen(0, zName, id, ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); }else{ return SQLITE_CANTOPEN; } } if( pOutFlags ){ if( flags & SQLITE_OPEN_READWRITE ){ *pOutFlags = SQLITE_OPEN_READWRITE; }else{ *pOutFlags = SQLITE_OPEN_READONLY; } } memset(pFile, 0, sizeof(*pFile)); pFile->pMethod = &winIoMethod; pFile->h = h;#if SQLITE_OS_WINCE if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) && !winceCreateLock(zName, pFile) ){ CloseHandle(h); free(zConverted); return SQLITE_CANTOPEN; } if( isTemp ){ pFile->zDeleteOnClose = zConverted; }else#endif { free(zConverted); } OpenCounter(+1); return SQLITE_OK;}/*** Delete the named file.**** Note that windows does not allow a file to be deleted if some other** process has it open. Sometimes a virus scanner or indexing program** will open a journal file shortly after it is created in order to do** whatever it does. While this other process is holding the** file open, we will be unable to delete it. To work around this** problem, we delay 100 milliseconds and try to delete again. Up** to MX_DELETION_ATTEMPTs deletion attempts are run before giving** up and returning an error.*/#define MX_DELETION_ATTEMPTS 5static int winDelete( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */){ int cnt = 0; int rc; DWORD error; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } SimulateIOError(return SQLITE_IOERR_DELETE); if( isNT() ){ do{ DeleteFileW(zConverted); }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES) || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) && (cnt++ < MX_DELETION_ATTEMPTS) && (Sleep(100), 1) ); }else{ do{ DeleteFileA(zConverted); }while( ( ((rc = GetFileAttributesA(zConverted)) != INVALID_FILE_ATTRIBUTES) || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) && (cnt++ < MX_DELETION_ATTEMPTS) && (Sleep(100), 1) ); } free(zConverted); OSTRACE2("DELETE \"%s\"\n", zFilename); return ( (rc==INVALID_FILE_ATTRIBUTES) && (error == ERROR_FILE_NOT_FOUND)) ? SQLITE_OK : SQLITE_IOERR_DELETE;}/*** Check the existance and status of a file.*/static int winAccess( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */){ DWORD attr; int rc; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ attr = GetFileAttributesW((WCHAR*)zConverted); }else{ attr = GetFileAttributesA((char*)zConverted); } free(zConverted); switch( flags ){ case SQLITE_ACCESS_READ: case SQLITE_ACCESS_EXISTS: rc = attr!=INVALID_FILE_ATTRIBUTES; break; case SQLITE_ACCESS_READWRITE: rc = (attr & FILE_ATTRIBUTE_READONLY)==0; break; default: assert(!"Invalid flags argument"); } *pResOut = rc; return SQLITE_OK;}/*** Turn a relative pathname into a full pathname. Write the full** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname** bytes in size.*/static int winFullPathname( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */){#if defined(__CYGWIN__) cygwin_conv_to_full_win32_path(zRelative, zFull); return SQLITE_OK;#endif#if SQLITE_OS_WINCE /* WinCE has no concept of a relative pathname, or so I am told. */ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); return SQLITE_OK;#endif#if !SQLITE_OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; zConverted = convertUtf8Filename(zRelative); if( isNT() ){ WCHAR *zTemp; nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ free(zConverted); return SQLITE_NOMEM; } GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); free(zConverted); zOut = unicodeToUtf8(zTemp); free(zTemp); }else{ char *zTemp; nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; zTemp = malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ free(zConverted); return SQLITE_NOMEM; } GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); free(zConverted); zOut = mbcsToUtf8(zTemp); free(zTemp); } if( zOut ){ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zOut); free(zOut); return SQLITE_OK; }else{ return SQLITE_NOMEM; }#endif}#ifndef SQLITE_OMIT_LOAD_EXTENSION/*** Interfaces for opening a shared library, finding entry points** within the shared library, and closing the shared library.*//*** Interfaces for opening a shared library, finding entry points** within the shared library, and closing the shared library.*/static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ HANDLE h; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return 0; } if( isNT() ){ h = LoadLibraryW((WCHAR*)zConverted); }else{ h = LoadLibraryA((char*)zConverted); } free(zConverted); return (void*)h;}static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ getLastErrorMsg(nBuf, zBufOut);}void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){#if SQLITE_OS_WINCE /* The GetProcAddressA() routine is only available on wince. */ return GetProcAddressA((HANDLE)pHandle, zSymbol);#else /* All other windows platforms expect GetProcAddress() to take ** an Ansi string regardless of the _UNICODE setting */ return GetProcAddress((HANDLE)pHandle, zSymbol);#endif}void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ FreeLibrary((HANDLE)pHandle);}#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ #define winDlOpen 0 #define winDlError 0 #define winDlSym 0 #define winDlClose 0#endif/*** Write up to nBuf bytes of randomness into zBuf.*/static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ int n = 0; if( sizeof(SYSTEMTIME)<=nBuf-n ){ SYSTEMTIME x; GetSystemTime(&x); memcpy(&zBuf[n], &x, sizeof(x)); n += sizeof(x); } if( sizeof(DWORD)<=nBuf-n ){ DWORD pid = GetCurrentProcessId(); memcpy(&zBuf[n], &pid, sizeof(pid)); n += sizeof(pid); } if( sizeof(DWORD)<=nBuf-n ){ DWORD cnt = GetTickCount(); memcpy(&zBuf[n], &cnt, sizeof(cnt)); n += sizeof(cnt); } if( sizeof(LARGE_INTEGER)<=nBuf-n ){ LARGE_INTEGER i; QueryPerformanceCounter(&i); memcpy(&zBuf[n], &i, sizeof(i)); n += sizeof(i); } return n;}/*** Sleep for a little while. Return the amount of time slept.*/static int winSleep(sqlite3_vfs *pVfs, int microsec){ Sleep((microsec+999)/1000); return ((microsec+999)/1000)*1000;}/*** The following variable, if set to a non-zero value, becomes the result** returned from sqlite3OsCurrentTime(). This is used for testing.*/#ifdef SQLITE_TESTint sqlite3_current_time = 0;#endif/*** Find the current time (in Universal Coordinated Time). Write the** current time and date as a Julian Day number into *prNow and** return 0. Return 1 if the time and date cannot be found.*/int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ FILETIME ft; /* FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ double now;#if SQLITE_OS_WINCE SYSTEMTIME time; GetSystemTime(&time); /* if SystemTimeToFileTime() fails, it returns zero. */ if (!SystemTimeToFileTime(&time,&ft)){ return 1; }#else GetSystemTimeAsFileTime( &ft );#endif now = ((double)ft.dwHighDateTime) * 4294967296.0; *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;#ifdef SQLITE_TEST if( sqlite3_current_time ){ *prNow = sqlite3_current_time/86400.0 + 2440587.5; }#endif return 0;}/*** The idea is that this function works like a combination of** GetLastError() and FormatMessage() on windows (or errno and** strerror_r() on unix). After an error is returned by an OS** function, SQLite calls this function with zBuf pointing to** a buffer of nBuf bytes. The OS layer should populate the** buffer with a nul-terminated UTF-8 encoded error message** describing the last IO error to have occured within the calling** thread.**** If the error message is too large for the supplied buffer,** it should be truncated. The return value of xGetLastError** is zero if the error message fits in the buffer, or non-zero** otherwise (if the message was truncated). If non-zero is returned,** then it is not necessary to include the nul-terminator character** in the output buffer.**** Not supplying an error message will have no adverse effect** on SQLite. It is fine to have an implementation that never** returns an error message:**** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){** assert(zBuf[0]=='\0');** return 0;** }**** However if an error message is supplied, it will be incorporated** by sqlite into the error message available to the user using** sqlite3_errmsg(), possibly making IO errors easier to debug.*/static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ return getLastErrorMsg(nBuf, zBuf);}/*** Initialize and deinitialize the operating system interface.*/int sqlite3_os_init(void){ static sqlite3_vfs winVfs = { 1, /* iVersion */ sizeof(winFile), /* szOsFile */ MAX_PATH, /* mxPathname */ 0, /* pNext */ "win32", /* zName */ 0, /* pAppData */ winOpen, /* xOpen */ winDelete, /* xDelete */ winAccess, /* xAccess */ winFullPathname, /* xFullPathname */ winDlOpen, /* xDlOpen */ winDlError, /* xDlError */ winDlSym, /* xDlSym */ winDlClose, /* xDlClose */ winRandomness, /* xRandomness */ winSleep, /* xSleep */ winCurrentTime, /* xCurrentTime */ winGetLastError /* xGetLastError */ }; sqlite3_vfs_register(&winVfs, 1); return SQLITE_OK; }int sqlite3_os_end(void){ return SQLITE_OK;}#endif /* SQLITE_OS_WIN */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -