⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_win.c

📁 pda上的数据库,速度快,体积小,做朋友的福音
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 2004 May 22**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.************************************************************************************ This file contains code that is specific to windows.*/#include "sqliteInt.h"#include "os.h"#if OS_WIN               /* This file is used for windows only */#include <winbase.h>#ifdef __CYGWIN__# include <sys/cygwin.h>#endif/*** Macros used to determine whether or not to use threads.*/#if defined(THREADSAFE) && THREADSAFE# define SQLITE_W32_THREADS 1#endif/*** Include code that is common to all os_*.c files*/#include "os_common.h"/*** Do not include any of the File I/O interface procedures if the** SQLITE_OMIT_DISKIO macro is defined (indicating that there database** will be in-memory only)*/#ifndef SQLITE_OMIT_DISKIO/*** The following variable is (normally) set once and never changes** thereafter.  It records whether the operating system is Win95** or WinNT.**** 0:   Operating system unknown.** 1:   Operating system is Win95.** 2:   Operating system is WinNT.**** In order to facilitate testing on a WinNT system, the test fixture** can manually set this value to 1 to emulate Win98 behavior.*/int sqlite3_os_type = 0;/*** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.** Return false (zero) for Win95, Win98, or WinME.**** Here is an interesting observation:  Win95, Win98, and WinME lack** the LockFileEx() API.  But we can still statically link against that** API as long as we don't call it win running Win95/98/ME.  A call to** this routine is used to determine if the host is Win95/98/ME or** WinNT/2K/XP so that we will know whether or not we can safely call** the LockFileEx() API.*/static int isNT(void){  if( sqlite3_os_type==0 ){    OSVERSIONINFO sInfo;    sInfo.dwOSVersionInfoSize = sizeof(sInfo);    GetVersionEx(&sInfo);    sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;  }  return sqlite3_os_type==2;}/*** Convert a UTF-8 string to UTF-32.  Space to hold the returned string** is obtained from sqliteMalloc.*/static WCHAR *utf8ToUnicode(const char *zFilename){  int nByte;  WCHAR *zWideFilename;  if( !isNT() ){    return 0;  }  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);  zWideFilename = sqliteMalloc( nByte*sizeof(zWideFilename[0]) );  if( zWideFilename==0 ){    return 0;  }  nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);  if( nByte==0 ){    sqliteFree(zWideFilename);    zWideFilename = 0;  }  return zWideFilename;}/*** Convert UTF-32 to UTF-8.  Space to hold the returned string is** obtained from sqliteMalloc().*/static char *unicodeToUtf8(const WCHAR *zWideFilename){  int nByte;  char *zFilename;  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);  zFilename = sqliteMalloc( nByte );  if( zFilename==0 ){    return 0;  }  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,                              0, 0);  if( nByte == 0 ){    sqliteFree(zFilename);    zFilename = 0;  }  return zFilename;}/*** Delete the named file*/int sqlite3OsDelete(const char *zFilename){  WCHAR *zWide = utf8ToUnicode(zFilename);  if( zWide ){    DeleteFileW(zWide);    sqliteFree(zWide);  }else{    DeleteFileA(zFilename);  }  TRACE2("DELETE \"%s\"\n", zFilename);  return SQLITE_OK;}/*** Return TRUE if the named file exists.*/int sqlite3OsFileExists(const char *zFilename){  int exists = 0;  WCHAR *zWide = utf8ToUnicode(zFilename);  if( zWide ){    exists = GetFileAttributesW(zWide) != 0xffffffff;    sqliteFree(zWide);  }else{    exists = GetFileAttributesA(zFilename) != 0xffffffff;  }  return exists;}/*** Attempt to open a file for both reading and writing.  If that** fails, try opening it read-only.  If the file does not exist,** try to create it.**** On success, a handle for the open file is written to *id** and *pReadonly is set to 0 if the file was opened for reading and** writing or 1 if the file was opened read-only.  The function returns** SQLITE_OK.**** On failure, the function returns SQLITE_CANTOPEN and leaves** *id and *pReadonly unchanged.*/int sqlite3OsOpenReadWrite(  const char *zFilename,  OsFile *id,  int *pReadonly){  HANDLE h;  WCHAR *zWide = utf8ToUnicode(zFilename);  assert( !id->isOpen );  if( zWide ){    h = CreateFileW(zWide,       GENERIC_READ | GENERIC_WRITE,       FILE_SHARE_READ | FILE_SHARE_WRITE,       NULL,       OPEN_ALWAYS,       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,       NULL    );    if( h==INVALID_HANDLE_VALUE ){      h = CreateFileW(zWide,         GENERIC_READ,         FILE_SHARE_READ,         NULL,         OPEN_ALWAYS,         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,         NULL      );      if( h==INVALID_HANDLE_VALUE ){        sqliteFree(zWide);        return SQLITE_CANTOPEN;      }      *pReadonly = 1;    }else{      *pReadonly = 0;    }    sqliteFree(zWide);  }else{    h = CreateFileA(zFilename,       GENERIC_READ | GENERIC_WRITE,       FILE_SHARE_READ | FILE_SHARE_WRITE,       NULL,       OPEN_ALWAYS,       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,       NULL    );    if( h==INVALID_HANDLE_VALUE ){      h = CreateFileA(zFilename,         GENERIC_READ,         FILE_SHARE_READ,         NULL,         OPEN_ALWAYS,         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,         NULL      );      if( h==INVALID_HANDLE_VALUE ){        return SQLITE_CANTOPEN;      }      *pReadonly = 1;    }else{      *pReadonly = 0;    }  }  id->h = h;  id->locktype = NO_LOCK;  id->sharedLockByte = 0;  id->isOpen = 1;  OpenCounter(+1);  TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);  return SQLITE_OK;}/*** Attempt to open a new file for exclusive access by this process.** The file will be opened for both reading and writing.  To avoid** a potential security problem, we do not allow the file to have** previously existed.  Nor do we allow the file to be a symbolic** link.**** If delFlag is true, then make arrangements to automatically delete** the file when it is closed.**** On success, write the file handle into *id and return SQLITE_OK.**** On failure, return SQLITE_CANTOPEN.*/int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){  HANDLE h;  int fileflags;  WCHAR *zWide = utf8ToUnicode(zFilename);  assert( !id->isOpen );  if( delFlag ){    fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS                      | FILE_FLAG_DELETE_ON_CLOSE;  }else{    fileflags = FILE_FLAG_RANDOM_ACCESS;  }  if( zWide ){    h = CreateFileW(zWide,       GENERIC_READ | GENERIC_WRITE,       0,       NULL,       CREATE_ALWAYS,       fileflags,       NULL    );    sqliteFree(zWide);  }else{    h = CreateFileA(zFilename,       GENERIC_READ | GENERIC_WRITE,       0,       NULL,       CREATE_ALWAYS,       fileflags,       NULL    );  }  if( h==INVALID_HANDLE_VALUE ){    return SQLITE_CANTOPEN;  }  id->h = h;  id->locktype = NO_LOCK;  id->sharedLockByte = 0;  id->isOpen = 1;  OpenCounter(+1);  TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);  return SQLITE_OK;}/*** Attempt to open a new file for read-only access.**** On success, write the file handle into *id and return SQLITE_OK.**** On failure, return SQLITE_CANTOPEN.*/int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){  HANDLE h;  WCHAR *zWide = utf8ToUnicode(zFilename);  assert( !id->isOpen );  if( zWide ){    h = CreateFileW(zWide,       GENERIC_READ,       0,       NULL,       OPEN_EXISTING,       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,       NULL    );    sqliteFree(zWide);  }else{    h = CreateFileA(zFilename,       GENERIC_READ,       0,       NULL,       OPEN_EXISTING,       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,       NULL    );  }  if( h==INVALID_HANDLE_VALUE ){    return SQLITE_CANTOPEN;  }  id->h = h;  id->locktype = NO_LOCK;  id->sharedLockByte = 0;  id->isOpen = 1;  OpenCounter(+1);  TRACE3("OPEN RO %d \"%s\"\n", h, zFilename);  return SQLITE_OK;}/*** Attempt to open a file descriptor for the directory that contains a** file.  This file descriptor can be used to fsync() the directory** in order to make sure the creation of a new file is actually written** to disk.**** This routine is only meaningful for Unix.  It is a no-op under** windows since windows does not support hard links.**** On success, a handle for a previously open file is at *id is** updated with the new directory file descriptor and SQLITE_OK is** returned.**** On failure, the function returns SQLITE_CANTOPEN and leaves** *id unchanged.*/int sqlite3OsOpenDirectory(  const char *zDirname,  OsFile *id){  return SQLITE_OK;}/*** If the following global variable points to a string which is the** name of a directory, then that directory will be used to store** temporary files.*/char *sqlite3_temp_directory = 0;/*** Create a temporary file name in zBuf.  zBuf must be big enough to** hold at least SQLITE_TEMPNAME_SIZE characters.*/int sqlite3OsTempFileName(char *zBuf){  static char zChars[] =    "abcdefghijklmnopqrstuvwxyz"    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"    "0123456789";  int i, j;  char zTempPath[SQLITE_TEMPNAME_SIZE];  if( sqlite3_temp_directory ){    strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);    zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;  }else if( isNT() ){    char *zMulti;    WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];    GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);    zMulti = unicodeToUtf8(zWidePath);    if( zMulti ){      strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;      sqliteFree(zMulti);    }  }else{    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);  }  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}  zTempPath[i] = 0;  for(;;){    sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);    j = strlen(zBuf);    sqlite3Randomness(15, &zBuf[j]);    for(i=0; i<15; i++, j++){      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];    }    zBuf[j] = 0;    if( !sqlite3OsFileExists(zBuf) ) break;  }  TRACE2("TEMP FILENAME: %s\n", zBuf);  return SQLITE_OK; }/*** Close a file.*/int sqlite3OsClose(OsFile *id){  if( id->isOpen ){    TRACE2("CLOSE %d\n", id->h);    CloseHandle(id->h);    OpenCounter(-1);    id->isOpen = 0;  }  return SQLITE_OK;}/*** Read data from a file into a buffer.  Return SQLITE_OK if all** bytes were read successfully and SQLITE_IOERR if anything goes** wrong.*/int sqlite3OsRead(OsFile *id, void *pBuf, int amt){  DWORD got;  assert( id->isOpen );  SimulateIOError(SQLITE_IOERR);  TRACE3("READ %d lock=%d\n", id->h, id->locktype);  if( !ReadFile(id->h, pBuf, amt, &got, 0) ){    got = 0;  }  if( got==(DWORD)amt ){    return SQLITE_OK;  }else{    return SQLITE_IOERR;  }}/*** Write data from a buffer into a file.  Return SQLITE_OK on success** or some other error code on failure.*/int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){  int rc = 0;  DWORD wrote;  assert( id->isOpen );  SimulateIOError(SQLITE_IOERR);  SimulateDiskfullError;  TRACE3("WRITE %d lock=%d\n", id->h, id->locktype);  assert( amt>0 );  while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){    amt -= wrote;    pBuf = &((char*)pBuf)[wrote];  }  if( !rc || amt>(int)wrote ){    return SQLITE_FULL;  }  return SQLITE_OK;}/*** Some microsoft compilers lack this definition.*/#ifndef INVALID_SET_FILE_POINTER

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -