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

📄 os_win.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*** 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.**** $Id: os_win.c,v 1.132 2008/07/31 01:34:34 shane Exp $*/#include "sqliteInt.h"#if SQLITE_OS_WIN               /* This file is used for windows only *//*** A Note About Memory Allocation:**** This driver uses malloc()/free() directly rather than going through** the SQLite-wrappers sqlite3_malloc()/sqlite3_free().  Those wrappers** are designed for use on embedded systems where memory is scarce and** malloc failures happen frequently.  Win32 does not typically run on** embedded systems, and when it does the developers normally have bigger** problems to worry about than running out of memory.  So there is not** a compelling need to use the wrappers.**** But there is a good reason to not use the wrappers.  If we use the** wrappers then we will get simulated malloc() failures within this** driver.  And that causes all kinds of problems for our tests.  We** could enhance SQLite to deal with simulated malloc failures within** the OS driver, but the code to deal with those failure would not** be exercised on Linux (which does not need to malloc() in the driver)** and so we would have difficulty writing coverage tests for that** code.  Better to leave the code out, we think.**** The point of this discussion is as follows:  When creating a new** OS layer for an embedded system, if you use this file as an example,** avoid the use of malloc()/free().  Those routines work ok on windows** desktops but not so well in embedded systems.*/#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(SQLITE_OS_WINCE)# define AreFileApisANSI() 1#endif/*** WinCE lacks native support for file locking so we have to fake it** with some code of our own.*/#if SQLITE_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 sqlite3_file* specific to the win32** portability layer.*/typedef struct winFile winFile;struct winFile {  const sqlite3_io_methods *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 SQLITE_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};/*** 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.*/#ifdef SQLITE_TESTint sqlite3_os_type = 0;#elsestatic int sqlite3_os_type = 0;#endif/*** 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 SQLITE_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 /* SQLITE_OS_WINCE *//*** Convert a UTF-8 string to microsoft unicode (UTF-16?). **** Space to hold the returned string is obtained from malloc.*/static WCHAR *utf8ToUnicode(const char *zFilename){  int nChar;  WCHAR *zWideFilename;  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);  zWideFilename = malloc( nChar*sizeof(zWideFilename[0]) );  if( zWideFilename==0 ){    return 0;  }  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);  if( nChar==0 ){    free(zWideFilename);    zWideFilename = 0;  }  return zWideFilename;}/*** Convert microsoft unicode to UTF-8.  Space to hold the returned string is** obtained from malloc().*/static char *unicodeToUtf8(const WCHAR *zWideFilename){  int nByte;  char *zFilename;  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);  zFilename = malloc( nByte );  if( zFilename==0 ){    return 0;  }  nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,                              0, 0);  if( nByte == 0 ){    free(zFilename);    zFilename = 0;  }  return zFilename;}/*** Convert an ansi string to microsoft unicode, based on the** current codepage settings for file apis.** ** Space to hold the returned string is obtained** from malloc.*/static WCHAR *mbcsToUnicode(const char *zFilename){  int nByte;  WCHAR *zMbcsFilename;  int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;  nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);  zMbcsFilename = malloc( nByte*sizeof(zMbcsFilename[0]) );  if( zMbcsFilename==0 ){    return 0;  }  nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);  if( nByte==0 ){    free(zMbcsFilename);    zMbcsFilename = 0;  }  return zMbcsFilename;}/*** Convert microsoft unicode to multibyte character string, based on the** user's Ansi codepage.**** Space to hold the returned string is obtained from** malloc().*/static char *unicodeToMbcs(const WCHAR *zWideFilename){  int nByte;  char *zFilename;  int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;  nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);  zFilename = malloc( nByte );  if( zFilename==0 ){    return 0;  }  nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,                              0, 0);  if( nByte == 0 ){    free(zFilename);    zFilename = 0;  }  return zFilename;}/*** Convert multibyte character string to UTF-8.  Space to hold the** returned string is obtained from malloc().*/static char *mbcsToUtf8(const char *zFilename){  char *zFilenameUtf8;  WCHAR *zTmpWide;  zTmpWide = mbcsToUnicode(zFilename);  if( zTmpWide==0 ){    return 0;  }  zFilenameUtf8 = unicodeToUtf8(zTmpWide);  free(zTmpWide);  return zFilenameUtf8;}/*** Convert UTF-8 to multibyte character string.  Space to hold the ** returned string is obtained from malloc().*/static char *utf8ToMbcs(const char *zFilename){  char *zFilenameMbcs;  WCHAR *zTmpWide;  zTmpWide = utf8ToUnicode(zFilename);  if( zTmpWide==0 ){    return 0;  }  zFilenameMbcs = unicodeToMbcs(zTmpWide);  free(zTmpWide);  return zFilenameMbcs;}#if SQLITE_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;  sqlite3_int64 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){    free(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;  }  free(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;}/*

⌨️ 快捷键说明

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