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

📄 os_win.c

📁 sqlite嵌入式数据库源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** 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"/*** Determine if we are dealing with WindowsCE - which has a much** reduced API.*/#if defined(_WIN32_WCE)# define OS_WINCE 1#else# define OS_WINCE 0#endif/*** WinCE lacks native support for file locking so we have to fake it** with some code of our own.*/#if OS_WINCEtypedef struct winceLock {  int nReaders;       /* Number of reader locks obtained */  BOOL bPending;      /* Indicates a pending lock has been obtained */  BOOL bReserved;     /* Indicates a reserved lock has been obtained */  BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */} winceLock;#endif/*** The winFile structure is a subclass of OsFile specific to the win32** portability layer.*/typedef struct winFile winFile;struct winFile {  IoMethod const *pMethod;/* Must be first */  HANDLE h;               /* Handle for accessing the file */  unsigned char locktype; /* Type of lock currently held on this file */  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */#if OS_WINCE  WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */  HANDLE hMutex;          /* Mutex used to control access to shared lock */    HANDLE hShared;         /* Shared memory segment used for locking */  winceLock local;        /* Locks obtained by this instance of winFile */  winceLock *shared;      /* Global shared lock memory for the file  */#endif};/*** 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, WinXP,** or WinCE.  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.*/#if OS_WINCE# define isNT()  (1)#else  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;  }#endif /* OS_WINCE *//*** 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 nChar;  WCHAR *zWideFilename;  if( !isNT() ){    return 0;  }  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);  zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );  if( zWideFilename==0 ){    return 0;  }  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);  if( nChar==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;}#if OS_WINCE/*************************************************************************** This section contains code for WinCE only.*//*** WindowsCE does not have a localtime() function.  So create a** substitute.*/#include <time.h>struct tm *__cdecl localtime(const time_t *t){  static struct tm y;  FILETIME uTm, lTm;  SYSTEMTIME pTm;  i64 t64;  t64 = *t;  t64 = (t64 + 11644473600)*10000000;  uTm.dwLowDateTime = t64 & 0xFFFFFFFF;  uTm.dwHighDateTime= t64 >> 32;  FileTimeToLocalFileTime(&uTm,&lTm);  FileTimeToSystemTime(&lTm,&pTm);  y.tm_year = pTm.wYear - 1900;  y.tm_mon = pTm.wMonth - 1;  y.tm_wday = pTm.wDayOfWeek;  y.tm_mday = pTm.wDay;  y.tm_hour = pTm.wHour;  y.tm_min = pTm.wMinute;  y.tm_sec = pTm.wSecond;  return &y;}/* This will never be called, but defined to make the code compile */#define GetTempPathA(a,b)#define LockFile(a,b,c,d,e)       winceLockFile(&a, b, c, d, e)#define UnlockFile(a,b,c,d,e)     winceUnlockFile(&a, b, c, d, e)#define LockFileEx(a,b,c,d,e,f)   winceLockFileEx(&a, b, c, d, e, f)#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)]/*** Acquire a lock on the handle h*/static void winceMutexAcquire(HANDLE h){   DWORD dwErr;   do {     dwErr = WaitForSingleObject(h, INFINITE);   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);}/*** Release a lock acquired by winceMutexAcquire()*/#define winceMutexRelease(h) ReleaseMutex(h)/*** Create the mutex and shared memory used for locking in the file** descriptor pFile*/static BOOL winceCreateLock(const char *zFilename, winFile *pFile){  WCHAR *zTok;  WCHAR *zName = utf8ToUnicode(zFilename);  BOOL bInit = TRUE;  /* Initialize the local lockdata */  ZeroMemory(&pFile->local, sizeof(pFile->local));  /* Replace the backslashes from the filename and lowercase it  ** to derive a mutex name. */  zTok = CharLowerW(zName);  for (;*zTok;zTok++){    if (*zTok == '\\') *zTok = '_';  }  /* Create/open the named mutex */  pFile->hMutex = CreateMutexW(NULL, FALSE, zName);  if (!pFile->hMutex){    sqliteFree(zName);    return FALSE;  }  /* Acquire the mutex before continuing */  winceMutexAcquire(pFile->hMutex);    /* Since the names of named mutexes, semaphores, file mappings etc are   ** case-sensitive, take advantage of that by uppercasing the mutex name  ** and using that as the shared filemapping name.  */  CharUpperW(zName);  pFile->hShared = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,                                       PAGE_READWRITE, 0, sizeof(winceLock),                                       zName);    /* Set a flag that indicates we're the first to create the memory so it   ** must be zero-initialized */  if (GetLastError() == ERROR_ALREADY_EXISTS){    bInit = FALSE;  }  sqliteFree(zName);  /* If we succeeded in making the shared memory handle, map it. */  if (pFile->hShared){    pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared,              FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));    /* If mapping failed, close the shared memory handle and erase it */    if (!pFile->shared){      CloseHandle(pFile->hShared);      pFile->hShared = NULL;    }  }  /* If shared memory could not be created, then close the mutex and fail */  if (pFile->hShared == NULL){    winceMutexRelease(pFile->hMutex);    CloseHandle(pFile->hMutex);    pFile->hMutex = NULL;    return FALSE;  }    /* Initialize the shared memory if we're supposed to */  if (bInit) {    ZeroMemory(pFile->shared, sizeof(winceLock));  }  winceMutexRelease(pFile->hMutex);  return TRUE;}/*** Destroy the part of winFile that deals with wince locks*/static void winceDestroyLock(winFile *pFile){  if (pFile->hMutex){    /* Acquire the mutex */    winceMutexAcquire(pFile->hMutex);    /* The following blocks should probably assert in debug mode, but they       are to cleanup in case any locks remained open */    if (pFile->local.nReaders){      pFile->shared->nReaders --;    }    if (pFile->local.bReserved){      pFile->shared->bReserved = FALSE;    }    if (pFile->local.bPending){      pFile->shared->bPending = FALSE;    }    if (pFile->local.bExclusive){      pFile->shared->bExclusive = FALSE;    }    /* De-reference and close our copy of the shared memory handle */    UnmapViewOfFile(pFile->shared);    CloseHandle(pFile->hShared);    /* Done with the mutex */    winceMutexRelease(pFile->hMutex);        CloseHandle(pFile->hMutex);    pFile->hMutex = NULL;  }}/* ** An implementation of the LockFile() API of windows for wince*/static BOOL winceLockFile(  HANDLE *phFile,  DWORD dwFileOffsetLow,  DWORD dwFileOffsetHigh,  DWORD nNumberOfBytesToLockLow,  DWORD nNumberOfBytesToLockHigh){  winFile *pFile = HANDLE_TO_WINFILE(phFile);  BOOL bReturn = FALSE;  if (!pFile->hMutex) return TRUE;  winceMutexAcquire(pFile->hMutex);  /* Wanting an exclusive lock? */  if (dwFileOffsetLow == SHARED_FIRST       && nNumberOfBytesToLockLow == SHARED_SIZE){    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){       pFile->shared->bExclusive = TRUE;       pFile->local.bExclusive = TRUE;       bReturn = TRUE;    }  }  /* Want a read-only lock? */  else if ((dwFileOffsetLow >= SHARED_FIRST &&            dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) &&            nNumberOfBytesToLockLow == 1){    if (pFile->shared->bExclusive == 0){      pFile->local.nReaders ++;      if (pFile->local.nReaders == 1){        pFile->shared->nReaders ++;      }      bReturn = TRUE;    }  }  /* Want a pending lock? */  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){    /* If no pending lock has been acquired, then acquire it */    if (pFile->shared->bPending == 0) {      pFile->shared->bPending = TRUE;      pFile->local.bPending = TRUE;      bReturn = TRUE;    }  }  /* Want a reserved lock? */  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){    if (pFile->shared->bReserved == 0) {      pFile->shared->bReserved = TRUE;      pFile->local.bReserved = TRUE;      bReturn = TRUE;    }  }  winceMutexRelease(pFile->hMutex);  return bReturn;}/*** An implementation of the UnlockFile API of windows for wince*/static BOOL winceUnlockFile(  HANDLE *phFile,  DWORD dwFileOffsetLow,  DWORD dwFileOffsetHigh,  DWORD nNumberOfBytesToUnlockLow,  DWORD nNumberOfBytesToUnlockHigh){  winFile *pFile = HANDLE_TO_WINFILE(phFile);  BOOL bReturn = FALSE;  if (!pFile->hMutex) return TRUE;  winceMutexAcquire(pFile->hMutex);  /* Releasing a reader lock or an exclusive lock */  if (dwFileOffsetLow >= SHARED_FIRST &&       dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){    /* Did we have an exclusive lock? */    if (pFile->local.bExclusive){      pFile->local.bExclusive = FALSE;      pFile->shared->bExclusive = FALSE;      bReturn = TRUE;    }    /* Did we just have a reader lock? */    else if (pFile->local.nReaders){      pFile->local.nReaders --;      if (pFile->local.nReaders == 0)      {        pFile->shared->nReaders --;      }      bReturn = TRUE;    }  }  /* Releasing a pending lock */  else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){    if (pFile->local.bPending){      pFile->local.bPending = FALSE;      pFile->shared->bPending = FALSE;      bReturn = TRUE;    }  }  /* Releasing a reserved lock */  else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){    if (pFile->local.bReserved) {      pFile->local.bReserved = FALSE;      pFile->shared->bReserved = FALSE;      bReturn = TRUE;    }  }  winceMutexRelease(pFile->hMutex);  return bReturn;}/*** An implementation of the LockFileEx() API of windows for wince*/static BOOL winceLockFileEx(  HANDLE *phFile,  DWORD dwFlags,  DWORD dwReserved,  DWORD nNumberOfBytesToLockLow,  DWORD nNumberOfBytesToLockHigh,  LPOVERLAPPED lpOverlapped){  /* If the caller wants a shared read lock, forward this call  ** to winceLockFile */  if (lpOverlapped->Offset == SHARED_FIRST &&      dwFlags == 1 &&      nNumberOfBytesToLockLow == SHARED_SIZE){    return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0);  }  return FALSE;}/*** End of the special code for wince*****************************************************************************/#endif /* OS_WINCE *//*** 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 is 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 3int sqlite3WinDelete(const char *zFilename){  WCHAR *zWide = utf8ToUnicode(zFilename);  int cnt = 0;  int rc;  if( zWide ){    do{      rc = DeleteFileW(zWide);    }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );    sqliteFree(zWide);  }else{#if OS_WINCE    return SQLITE_NOMEM;#else    do{      rc = DeleteFileA(zFilename);    }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );#endif  }  TRACE2("DELETE \"%s\"\n", zFilename);  return rc==0 ? SQLITE_OK : SQLITE_IOERR;}/*** Return TRUE if the named file exists.*/int sqlite3WinFileExists(const char *zFilename){  int exists = 0;  WCHAR *zWide = utf8ToUnicode(zFilename);  if( zWide ){

⌨️ 快捷键说明

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