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

📄 os_win.c

📁 1.编译色情sqlite源代码为dll;2.运用sqlite3数据库存储二进制数据到数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* 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 *//******************************************************************************* The next group of routines implement the I/O methods specified** by the sqlite3_io_methods object.******************************************************************************//*** Close a file.**** It is reported that an attempt to close a handle might sometimes** fail.  This is a very unreasonable result, but windows is notorious** for being unreasonable so I do not doubt that it might happen.  If** the close fails, we pause for 100 milliseconds and try again.  As** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before** giving up and returning an error.*/#define MX_CLOSE_ATTEMPT 3static int winClose(sqlite3_file *id){  int rc, cnt = 0;  winFile *pFile = (winFile*)id;  OSTRACE2("CLOSE %d\n", pFile->h);  do{    rc = CloseHandle(pFile->h);  }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );#if OS_WINCE  winceDestroyLock(pFile);  if( pFile->zDeleteOnClose ){    DeleteFileW(pFile->zDeleteOnClose);    free(pFile->zDeleteOnClose);  }#endif  OpenCounter(-1);  return rc ? SQLITE_OK : SQLITE_IOERR;}/*** Some microsoft compilers lack this definition.*/#ifndef INVALID_SET_FILE_POINTER# define INVALID_SET_FILE_POINTER ((DWORD)-1)#endif/*** Read data from a file into a buffer.  Return SQLITE_OK if all** bytes were read successfully and SQLITE_IOERR if anything goes** wrong.*/static int winRead(  sqlite3_file *id,          /* File to read from */  void *pBuf,                /* Write content into this buffer */  int amt,                   /* Number of bytes to read */  sqlite3_int64 offset       /* Begin reading at this offset */){  LONG upperBits = (offset>>32) & 0x7fffffff;  LONG lowerBits = offset & 0xffffffff;  DWORD rc;  DWORD got;  winFile *pFile = (winFile*)id;  assert( id!=0 );  SimulateIOError(return SQLITE_IOERR_READ);  OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);  if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){    return SQLITE_FULL;  }  if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){    return SQLITE_IOERR_READ;  }  if( got==(DWORD)amt ){    return SQLITE_OK;  }else{    memset(&((char*)pBuf)[got], 0, amt-got);    return SQLITE_IOERR_SHORT_READ;  }}/*** Write data from a buffer into a file.  Return SQLITE_OK on success** or some other error code on failure.*/static int winWrite(  sqlite3_file *id,         /* File to write into */  const void *pBuf,         /* The bytes to be written */  int amt,                  /* Number of bytes to write */  sqlite3_int64 offset      /* Offset into the file to begin writing at */){  LONG upperBits = (offset>>32) & 0x7fffffff;  LONG lowerBits = offset & 0xffffffff;  DWORD rc;  DWORD wrote;  winFile *pFile = (winFile*)id;  assert( id!=0 );  SimulateIOError(return SQLITE_IOERR_WRITE);  SimulateDiskfullError(return SQLITE_FULL);  OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);  if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){    return SQLITE_FULL;  }  assert( amt>0 );  while(     amt>0     && (rc = WriteFile(pFile->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;}/*** Truncate an open file to a specified size*/static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){  LONG upperBits = (nByte>>32) & 0x7fffffff;  LONG lowerBits = nByte & 0xffffffff;  winFile *pFile = (winFile*)id;  OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);  SimulateIOError(return SQLITE_IOERR_TRUNCATE);  SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);  SetEndOfFile(pFile->h);  return SQLITE_OK;}#ifdef SQLITE_TEST/*** Count the number of fullsyncs and normal syncs.  This is used to test** that syncs and fullsyncs are occuring at the right times.*/int sqlite3_sync_count = 0;int sqlite3_fullsync_count = 0;#endif/*** Make sure all writes to a particular file are committed to disk.*/static int winSync(sqlite3_file *id, int flags){  winFile *pFile = (winFile*)id;  OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);#ifdef SQLITE_TEST  if( flags & SQLITE_SYNC_FULL ){    sqlite3_fullsync_count++;  }  sqlite3_sync_count++;#endif  if( FlushFileBuffers(pFile->h) ){    return SQLITE_OK;  }else{    return SQLITE_IOERR;  }}/*** Determine the current size of a file in bytes*/static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){  winFile *pFile = (winFile*)id;  DWORD upperBits, lowerBits;  SimulateIOError(return SQLITE_IOERR_FSTAT);  lowerBits = GetFileSize(pFile->h, &upperBits);  *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;  return SQLITE_OK;}/*** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.*/#ifndef LOCKFILE_FAIL_IMMEDIATELY# define LOCKFILE_FAIL_IMMEDIATELY 1#endif/*** Acquire a reader lock.** Different API routines are called depending on whether or not this** is Win95 or WinNT.*/static int getReadLock(winFile *pFile){  int res;  if( isNT() ){    OVERLAPPED ovlp;    ovlp.Offset = SHARED_FIRST;    ovlp.OffsetHigh = 0;    ovlp.hEvent = 0;    res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,                     0, SHARED_SIZE, 0, &ovlp);  }else{    int lk;    sqlite3Randomness(sizeof(lk), &lk);    pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);    res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);  }  return res;}/*** Undo a readlock*/static int unlockReadLock(winFile *pFile){  int res;  if( isNT() ){    res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);  }else{    res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0);  }  return res;}/*** Lock the file with the lock specified by parameter locktype - one** of the following:****     (1) SHARED_LOCK**     (2) RESERVED_LOCK**     (3) PENDING_LOCK**     (4) EXCLUSIVE_LOCK**** Sometimes when requesting one lock state, additional lock states** are inserted in between.  The locking might fail on one of the later** transitions leaving the lock state different from what it started but** still short of its goal.  The following chart shows the allowed** transitions and the inserted intermediate states:****    UNLOCKED -> SHARED**    SHARED -> RESERVED**    SHARED -> (PENDING) -> EXCLUSIVE**    RESERVED -> (PENDING) -> EXCLUSIVE**    PENDING -> EXCLUSIVE**** This routine will only increase a lock.  The winUnlock() routine** erases all locks at once and returns us immediately to locking level 0.** It is not possible to lower the locking level one step at a time.  You** must go straight to locking level 0.*/static int winLock(sqlite3_file *id, int locktype){  int rc = SQLITE_OK;    /* Return code from subroutines */  int res = 1;           /* Result of a windows lock call */  int newLocktype;       /* Set pFile->locktype to this value before exiting */  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */  winFile *pFile = (winFile*)id;  assert( pFile!=0 );  OSTRACE5("LOCK %d %d was %d(%d)\n",          pFile->h, locktype, pFile->locktype, pFile->sharedLockByte);  /* If there is already a lock of this type or more restrictive on the  ** OsFile, do nothing. Don't use the end_lock: exit path, as  ** sqlite3OsEnterMutex() hasn't been called yet.  */  if( pFile->locktype>=locktype ){    return SQLITE_OK;  }  /* Make sure the locking sequence is correct  */  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );  assert( locktype!=PENDING_LOCK );  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of  ** the PENDING_LOCK byte is temporary.  */  newLocktype = pFile->locktype;  if( pFile->locktype==NO_LOCK   || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK)  ){    int cnt = 3;    while( cnt-->0 && (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){      /* Try 3 times to get the pending lock.  The pending lock might be      ** held by another reader process who will release it momentarily.      */      OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);      Sleep(1);    }    gotPendingLock = res;  }  /* Acquire a shared lock  */  if( locktype==SHARED_LOCK && res ){    assert( pFile->locktype==NO_LOCK );    res = getReadLock(pFile);    if( res ){      newLocktype = SHARED_LOCK;    }  }  /* Acquire a RESERVED lock  */  if( locktype==RESERVED_LOCK && res ){    assert( pFile->locktype==SHARED_LOCK );    res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);    if( res ){      newLocktype = RESERVED_LOCK;    }  }  /* Acquire a PENDING lock  */  if( locktype==EXCLUSIVE_LOCK && res ){    newLocktype = PENDING_LOCK;    gotPendingLock = 0;  }  /* Acquire an EXCLUSIVE lock  */  if( locktype==EXCLUSIVE_LOCK && res ){    assert( pFile->locktype>=SHARED_LOCK );    res = unlockReadLock(pFile);    OSTRACE2("unreadlock = %d\n", res);    res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);    if( res ){      newLocktype = EXCLUSIVE_LOCK;    }else{      OSTRACE2("error-code = %d\n", GetLastError());      getReadLock(pFile);    }  }  /* If we are holding a PENDING lock that ought to be released, then  ** release it now.  */  if( gotPendingLock && locktype==SHARED_LOCK ){    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);  }  /* Update the state of the lock has held in the file descriptor then  ** return the appropriate result code.  */  if( res ){    rc = SQLITE_OK;  }else{    OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", pFile->h,           locktype, newLocktype);    rc = SQLITE_BUSY;  }  pFile->locktype = newLocktype;  return rc;}/*** This routine checks if there is a RESERVED lock held on the specified** file by this or any other process. If such a lock is held, return** non-zero, otherwise zero.*/static int winCheckReservedLock(sqlite3_file *id){  int rc;  winFile *pFile = (winFile*)id;  assert( pFile!=0 );  if( pFile->locktype>=RESERVED_LOCK ){    rc = 1;    OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);  }else{    rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);    if( rc ){      UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);    }    rc = !rc;    OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);  }  return rc;}/*** Lower the locking level on file descriptor id to locktype.  locktype** must be either NO_LOCK or SHARED_LOCK.**** If the locking level of the file descriptor is already at or below** the requested locking level, this routine is a no-op.**** It is not possible for this routine to fail if the second argument** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine** might return SQLITE_IOERR;*/static int winUnlock(sqlite3_file *id, int locktype){  int type;  winFile *pFile = (winFile*)id;  int rc = SQLITE_OK;  assert( pFile!=0 );  assert( locktype<=SHARED_LOCK );  OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,          pFile->locktype, pFile->sharedLockByte);  type = pFile->locktype;  if( type>=EXCLUSIVE_LOCK ){    UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);    if( locktype==SHARED_LOCK && !getReadLock(pFile) ){      /* This should never happen.  We should always be able to      ** reacquire the read lock */      rc = SQLITE_IOERR_UNLOCK;    }  }  if( type>=RESERVED_LOCK ){    UnlockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);  }  if( locktype==NO_LOCK && type>=SHARED_LOCK ){    unlockReadLock(pFile);  }  if( type>=PENDING_LOCK ){    UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);  }  pFile->locktype = locktype;  return rc;}/*** Control and query of the open file handle.*/static int winFileControl(sqlite3_file *id, int op, void *pArg){  switch( op ){    case SQLITE_FCNTL_LOCKSTATE: {      *(int*)pArg = ((winFile*)id)->locktype;      return SQLITE_OK;    }  }  return SQLITE_ERROR;}/*** Return the sector size in bytes of the underlying block device for** the specified file. This is almost always 512 bytes, but may be** larger for some devices.**** SQLite code assumes this function cannot fail. It also assumes that** if two files are created in the same file-system directory (i.e.** a database and its journal file) that the sector size will be the** same for both.*/static int winSectorSize(sqlite3_file *id){  return SQLITE_DEFAULT_SECTOR_SIZE;}/*** Return a vector of device characteristics.*/static int winDeviceCharacteristics(sqlite3_file *id){  return 0;}/*** This vector defines all the methods that can operate on an** sqlite3_file for win32.*/static const sqlite3_io_methods winIoMethod = {  1,                        /* iVersion */  winClose,  winRead,  winWrite,  winTruncate,  winSync,  winFileSize,  winLock,  winUnlock,  winCheckReservedLock,

⌨️ 快捷键说明

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