亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? crypt.c

?? sqlite 3.3.8 支持加密的版本
?? C
字號:
#ifdef SQLITE_HAS_CODEC
  void sqlite3pager_free_codecarg(void *pArg);
#endif

#include "src/pager.c"

#ifndef SQLITE_OMIT_DISKIO
#ifdef SQLITE_HAS_CODEC

#include <windows.h>
#include <wincrypt.h>

// Extra padding before and after the cryptographic buffer
#define CRYPT_OFFSET 8

typedef struct _CRYPTBLOCK
{
  HCRYPTKEY hReadKey;     // Key used to read from the database and write to the journal
  HCRYPTKEY hWriteKey;    // Key used to write to the database
  DWORD     dwPageSize;   // Size of pages
  LPVOID    pvCrypt;      // A buffer for encrypting/decrypting (if necessary)
  DWORD     dwCryptSize;  // Equal to or greater than dwPageSize.  If larger, pvCrypt is valid and this is its size
} CRYPTBLOCK, *LPCRYPTBLOCK;

HCRYPTPROV g_hProvider = 0; // Global instance of the cryptographic provider

#define SQLITECRYPTERROR_PROVIDER "Cryptographic provider not available"

// Needed for re-keying
static void * sqlite3pager_get_codecarg(Pager *pPager)
{
  return (pPager->xCodec) ? pPager->pCodecArg: NULL;
}

void sqlite3_activate_see(const char *info)
{
}

// Create a cryptographic context.  Use the enhanced provider because it is available on
// most platforms
static BOOL InitializeProvider()
{
  if (g_hProvider) return TRUE;

  if (!CryptAcquireContext(&g_hProvider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  {
    return FALSE;
  }
  return TRUE;
}

// Create or update a cryptographic context for a pager.
// This function will automatically determine if the encryption algorithm requires
// extra padding, and if it does, will create a temp buffer big enough to provide
// space to hold it.
static LPCRYPTBLOCK CreateCryptBlock(HCRYPTKEY hKey, Pager *pager, LPCRYPTBLOCK pExisting)
{
  LPCRYPTBLOCK pBlock;

  if (!pExisting) // Creating a new cryptblock
  {
    pBlock = sqliteMalloc(sizeof(CRYPTBLOCK));
    ZeroMemory(pBlock, sizeof(CRYPTBLOCK));
    pBlock->hReadKey = hKey;
    pBlock->hWriteKey = hKey;
  }
  else // Updating an existing cryptblock
  {
    pBlock = pExisting;
  }

  pBlock->dwPageSize = (DWORD)pager->pageSize;
  pBlock->dwCryptSize = pBlock->dwPageSize;

  // Existing cryptblocks may have a buffer, if so, delete it
  if (pBlock->pvCrypt)
  {
    sqliteFree(pBlock->pvCrypt);
    pBlock->pvCrypt = NULL;
  }

  // Figure out how big to make our spare crypt block
  if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &pBlock->dwCryptSize, pBlock->dwCryptSize * 2))
  {
    pBlock->pvCrypt = sqliteMalloc(pBlock->dwCryptSize + (CRYPT_OFFSET * 2));
  }
  return pBlock;
}

// Destroy a cryptographic context and any buffers and keys allocated therein
static void DestroyCryptBlock(LPCRYPTBLOCK pBlock)
{
  // Destroy the read key if there is one
  if (pBlock->hReadKey)
  {
    CryptDestroyKey(pBlock->hReadKey);
  }

  // If there's a writekey and its not equal to the readkey, destroy it
  if (pBlock->hWriteKey && pBlock->hWriteKey != pBlock->hReadKey)
  {
    CryptDestroyKey(pBlock->hWriteKey);
  }

  // If there's extra buffer space allocated, free it as well
  if (pBlock->pvCrypt)
  {
    sqliteFree(pBlock->pvCrypt);
  }

  // All done with this cryptblock
  sqliteFree(pBlock);
}

// Encrypt/Decrypt functionality, called by pager.c
void * sqlite3Codec(void *pArg, void *data, Pgno nPageNum, int nMode)
{
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)pArg;
  DWORD dwPageSize;
  LPVOID pvTemp;

  if (!pBlock) return data;

  // Make sure the page size for the pager is still the same as the page size
  // for the cryptblock.  If the user changed it, we need to adjust!
  if (nMode != 2)
  {
    PgHdr *pageHeader;
    pageHeader = DATA_TO_PGHDR(data);
    if (pageHeader->pPager->pageSize != pBlock->dwPageSize)
    {
      // Update the cryptblock to reflect the new page size
      CreateCryptBlock(0, pageHeader->pPager, pBlock);
    }
  }

  switch(nMode)
  {
  case 0: // Undo a "case 7" journal file encryption
  case 2: // Reload a page
  case 3: // Load a page
    if (!pBlock->hReadKey) break;

    /* Block ciphers often need to write extra padding beyond the 
    data block.  We don't have that luxury for a given page of data so
    we must copy the page data to a buffer that IS large enough to hold
    the padding.  We then encrypt the block and write the buffer back to
    the page without the unnecessary padding.
    We only use the special block of memory if its absolutely necessary. */
    if (pBlock->dwCryptSize != pBlock->dwPageSize)
    {
      CopyMemory(((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, data, pBlock->dwPageSize);
      pvTemp = data;
      data = ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET;
    }


    dwPageSize = pBlock->dwCryptSize;
    CryptDecrypt(pBlock->hReadKey, 0, TRUE, 0, (LPBYTE)data, &dwPageSize);

    // If the encryption algorithm required extra padding and we were forced to encrypt or
    // decrypt a copy of the page data to a temp buffer, then write the contents of the temp
    // buffer back to the page data minus any padding applied.
    if (pBlock->dwCryptSize != pBlock->dwPageSize)
    {
      CopyMemory(pvTemp, data, pBlock->dwPageSize);
      data = pvTemp;
    }
    break;
  case 6: // Encrypt a page for the main database file
    if (!pBlock->hWriteKey) break;

    CopyMemory(((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, data, pBlock->dwPageSize);
    data = ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET;

    dwPageSize = pBlock->dwPageSize;
    CryptEncrypt(pBlock->hWriteKey, 0, TRUE, 0, ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, &dwPageSize, pBlock->dwCryptSize);
    break;
  case 7: // Encrypt a page for the journal file
    /* Under normal circumstances, the readkey is the same as the writekey.  However,
    when the database is being rekeyed, the readkey is not the same as the writekey.
    The rollback journal must be written using the original key for the
    database file because it is, by nature, a rollback journal.
    Therefore, for case 7, when the rollback is being written, always encrypt using
    the database's readkey, which is guaranteed to be the same key that was used to
    read the original data.
    */
    if (!pBlock->hReadKey) break;

    CopyMemory(((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, data, pBlock->dwPageSize);
    data = ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET;

    dwPageSize = pBlock->dwPageSize;
    CryptEncrypt(pBlock->hReadKey, 0, TRUE, 0, ((LPBYTE)pBlock->pvCrypt) + CRYPT_OFFSET, &dwPageSize, pBlock->dwCryptSize);
    break;
  }

  return data;
}

// Derive an encryption key from a user-supplied buffer
static HCRYPTKEY DeriveKey(const void *pKey, int nKeyLen)
{
  HCRYPTHASH hHash = 0;
  HCRYPTKEY  hKey;

  if (!pKey || !nKeyLen) return 0;

  if (!InitializeProvider())
  {
    return MAXDWORD;
  }

  if (CryptCreateHash(g_hProvider, CALG_SHA1, 0, 0, &hHash))
  {
    if (CryptHashData(hHash, (LPBYTE)pKey, nKeyLen, 0))
    {
      CryptDeriveKey(g_hProvider, CALG_RC4, hHash, 0, &hKey);
    }
    CryptDestroyHash(hHash);
  }  
  return hKey;
}

// Called by sqlite and sqlite3_key_interop to attach a key to a database.
int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen)
{
  int rc = SQLITE_ERROR;
  HCRYPTKEY hKey = 0;

  // No key specified, could mean either use the main db's encryption or no encryption
  if (!pKey || !nKeyLen)
  {
    if (!nDb)
    {
      return SQLITE_OK; // Main database, no key specified so not encrypted
    }
    else // Attached database, use the main database's key
    {
      // Get the encryption block for the main database and attempt to duplicate the key
      // for use by the attached database
      LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));

      if (!pBlock) return SQLITE_OK; // Main database is not encrypted so neither will be any attached database
      if (!pBlock->hReadKey) return SQLITE_OK; // Not encrypted

      if (!CryptDuplicateKey(pBlock->hReadKey, NULL, 0, &hKey))
        return rc; // Unable to duplicate the key
    }
  }
  else // User-supplied passphrase, so create a cryptographic key out of it
  {
    hKey = DeriveKey(pKey, nKeyLen);
    if (hKey == MAXDWORD)
    {
      sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
      return rc;
    }
  }

  // Create a new encryption block and assign the codec to the new attached database
  if (hKey)
  {
    LPCRYPTBLOCK pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db->aDb[nDb].pBt), NULL);
    sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Codec, pBlock);
    rc = SQLITE_OK;
  }
  return rc;
}

// Called by our code modification to pager.c to free the cryptblock associated with 
// a pager instance.
void sqlite3pager_free_codecarg(void *pArg)
{
  if (pArg)
    DestroyCryptBlock((LPCRYPTBLOCK)pArg);
}

// Once a password has been supplied and a key created, we don't keep the 
// original password for security purposes.  Therefore return NULL.
void sqlite3CodecGetKey(sqlite3 *db, int nDb, void **ppKey, int *pnKeyLen)
{
  *ppKey = NULL;
  *pnKeyLen = 0;
}

// We do not attach this key to the temp store, only the main database.
__declspec(dllexport) int WINAPI sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize)
{
  return sqlite3CodecAttach(db, 0, pKey, nKeySize);
}

// Changes the encryption key for an existing database.
__declspec(dllexport) int WINAPI sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize)
{
  Btree *pbt = db->aDb[0].pBt;
  Pager *p = sqlite3BtreePager(pbt);
  LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p);
  HCRYPTKEY hKey = DeriveKey(pKey, nKeySize);
  int rc = SQLITE_ERROR;

  if (hKey == MAXDWORD)
  {
    sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER);
    return rc;
  }

  if (!pBlock && !hKey) return SQLITE_OK; // Wasn't encrypted to begin with

  // To rekey a database, we change the writekey for the pager.  The readkey remains
  // the same
  if (!pBlock) // Encrypt an unencrypted database
  {
    pBlock = CreateCryptBlock(hKey, p, NULL);
    pBlock->hReadKey = 0; // Original database is not encrypted
    sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);
  }
  else // Change the writekey for an already-encrypted database
  {
    pBlock->hWriteKey = hKey;
  }

  // Start a transaction
  rc = sqlite3BtreeBeginTrans(pbt, 1);

  if (!rc)
  {
    // Rewrite all the pages in the database using the new encryption key
    Pgno nPage = sqlite3pager_pagecount(p);
    Pgno nSkip = PAGER_MJ_PGNO(p);
    void *pPage;
    Pgno n;

    for(n = 1; rc == SQLITE_OK && n <= nPage; n ++)
    {
      if (n == nSkip) continue;
      rc = sqlite3pager_get(p, n, &pPage);
      if(!rc)
      {
        rc = sqlite3pager_write(pPage);
        sqlite3pager_unref(pPage);
      }
    }
  }

  // If we succeeded, try and commit the transaction
  if (!rc)
  {
    rc = sqlite3BtreeCommit(pbt);
  }

  // If we failed, rollback
  if (rc)
  {
    sqlite3BtreeRollback(pbt);
  }

  // If we succeeded, destroy any previous read key this database used
  // and make the readkey equal to the writekey
  if (!rc)
  {
    if (pBlock->hReadKey)
    {
      CryptDestroyKey(pBlock->hReadKey);
    }
    pBlock->hReadKey = pBlock->hWriteKey;
  }
  // We failed.  Destroy the new writekey (if there was one) and revert it back to
  // the original readkey
  else
  {
    if (pBlock->hWriteKey)
    {
      CryptDestroyKey(pBlock->hWriteKey);
    }
    pBlock->hWriteKey = pBlock->hReadKey;
  }

  // If the readkey and writekey are both empty, there's no need for a codec on this
  // pager anymore.  Destroy the crypt block and remove the codec from the pager.
  if (!pBlock->hReadKey && !pBlock->hWriteKey)
  {
    sqlite3pager_set_codec(p, NULL, NULL);
    DestroyCryptBlock(pBlock);
  }

  return rc;
}

int sqlite3_key(sqlite3 *db, const void *pKey, int nKey)
{
  return sqlite3_key_interop(db, pKey, nKey);
}

int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)
{
  return sqlite3_rekey_interop(db, pKey, nKey);
}

#endif // SQLITE_HAS_CODEC

#endif // SQLITE_OMIT_DISKIO

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99在线精品免费| 日本一区二区久久| 日韩亚洲欧美中文三级| 欧美一卡二卡三卡四卡| 欧美一区二区成人6969| 在线观看欧美精品| 欧美日韩日本视频| 69精品人人人人| 国产欧美一区二区精品久导航| 中文字幕第一区第二区| 亚洲乱码国产乱码精品精的特点| 亚洲自拍另类综合| 三级久久三级久久久| 亚洲色图一区二区三区| 欧美成人官网二区| 国产精品欧美久久久久无广告| 亚洲婷婷在线视频| 三级亚洲高清视频| 精品中文av资源站在线观看| 成人a区在线观看| 在线欧美小视频| 欧美sm美女调教| 一区精品在线播放| 久久天天做天天爱综合色| 亚洲人123区| 午夜国产精品影院在线观看| 国产一区三区三区| av在线不卡电影| 538prom精品视频线放| 国产精品区一区二区三区| 亚洲不卡av一区二区三区| 精东粉嫩av免费一区二区三区| 99天天综合性| 欧美成人精品1314www| 亚洲视频一区二区在线| 天堂成人国产精品一区| 国产**成人网毛片九色| 日韩欧美激情四射| 亚洲欧洲制服丝袜| 久久91精品国产91久久小草| 91美女片黄在线观看91美女| 欧美大度的电影原声| 午夜精品久久久久久不卡8050| 国产传媒一区在线| 欧美丰满嫩嫩电影| 中文字幕一区二区三区四区| 亚洲一区二区三区不卡国产欧美| 国产91露脸合集magnet| 欧美一区二区三区视频免费播放 | 欧美激情一区二区三区全黄 | 成人妖精视频yjsp地址| 欧美日韩国产成人在线91| 久久蜜桃av一区二区天堂| 蜜臀国产一区二区三区在线播放| 91美女片黄在线观看| 国产欧美日韩久久| 久久精品免费观看| 欧美色倩网站大全免费| 亚洲精品乱码久久久久久久久| 国产真实乱对白精彩久久| 欧美绝品在线观看成人午夜影视| 成人欧美一区二区三区白人| 久久婷婷一区二区三区| 午夜精品福利在线| 欧洲日韩一区二区三区| 久久综合九色综合欧美就去吻| 亚洲.国产.中文慕字在线| av亚洲产国偷v产偷v自拍| 欧美一级理论性理论a| 亚洲亚洲精品在线观看| 国产不卡高清在线观看视频| 日韩精品一区二区三区在线播放| 亚洲成人动漫av| 色老汉一区二区三区| 亚洲精品在线一区二区| 久久99国产精品免费网站| 欧美人成免费网站| 亚洲成av人片在线观看无码| 色一情一伦一子一伦一区| 国产精品国产三级国产普通话三级 | 欧美日韩综合在线免费观看| 亚洲在线中文字幕| 欧美日韩中文字幕精品| 亚洲成人动漫一区| 欧美一区二区免费视频| 六月丁香婷婷色狠狠久久| 久久综合色综合88| 成人一区二区三区视频| 亚洲天堂免费看| 在线观看国产一区二区| 午夜精品一区二区三区免费视频 | 日韩有码一区二区三区| 日韩欧美一级特黄在线播放| 紧缚奴在线一区二区三区| 久久久久久综合| 成人av网址在线观看| 亚洲男女毛片无遮挡| 欧美久久高跟鞋激| 国模套图日韩精品一区二区| 中文字幕第一页久久| 色综合色综合色综合| 亚洲v精品v日韩v欧美v专区| 日韩免费高清电影| 国产精品一区专区| 亚洲精品国产一区二区三区四区在线| 欧美图区在线视频| 精品亚洲成a人在线观看| 国产精品色一区二区三区| 欧美做爰猛烈大尺度电影无法无天| 婷婷综合另类小说色区| 26uuu亚洲综合色| 一本久久a久久免费精品不卡| 日韩影院精彩在线| 中文字幕av一区二区三区免费看| 色噜噜狠狠色综合欧洲selulu| 日本欧洲一区二区| 中文天堂在线一区| 777xxx欧美| 欧美精品久久一区二区三区| 欧美精品黑人性xxxx| 国产一区二区调教| 一区二区视频免费在线观看| 日韩美女视频在线| 94-欧美-setu| 蜜桃av一区二区| 亚洲图片欧美激情| 精品国产乱码久久久久久免费| 一本色道亚洲精品aⅴ| 精品亚洲成a人| 夜夜嗨av一区二区三区| 久久新电视剧免费观看| 欧洲精品在线观看| 国产在线精品一区在线观看麻豆| 亚洲男人天堂av| 久久先锋资源网| 91精品欧美综合在线观看最新| 99热精品一区二区| 精品一区二区久久| 亚洲国产一区二区a毛片| 中文字幕欧美三区| 欧美一二三区在线| 欧美写真视频网站| 不卡高清视频专区| 国产在线国偷精品免费看| 亚洲第一会所有码转帖| 中文字幕亚洲在| 久久久蜜桃精品| 日韩一区二区精品葵司在线| 欧美三级日本三级少妇99| 99在线热播精品免费| 国产乱子伦视频一区二区三区| 午夜影院在线观看欧美| 亚洲天堂福利av| 中文字幕欧美区| 亚洲精品一区二区在线观看| 欧美浪妇xxxx高跟鞋交| 日本韩国一区二区三区视频| www.日韩精品| 粉嫩av一区二区三区| 国产一区久久久| 久久精品国产亚洲aⅴ| 视频一区中文字幕| 亚洲aⅴ怡春院| 亚洲香肠在线观看| 亚洲天堂精品视频| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 亚洲精品在线观| 日韩一区二区免费在线电影| 欧美日韩一区二区三区视频| 色综合久久综合| 99re这里只有精品6| 不卡视频一二三| 88在线观看91蜜桃国自产| 国产精品久久久久久久久久免费看| 2021中文字幕一区亚洲| 精品国精品自拍自在线| 日韩免费一区二区| 欧美一区二区三区爱爱| 日韩欧美一区二区三区在线| 日韩午夜激情av| 日韩亚洲欧美中文三级| 欧美一级理论片| 精品欧美一区二区三区精品久久| 欧美一级国产精品| 欧美大片免费久久精品三p| 欧美成人bangbros| 欧美精品一区二区三区蜜桃| 久久夜色精品国产噜噜av| 国产丝袜欧美中文另类| 国产亚洲精品aa| 亚洲国产精华液网站w| 国产精品久久毛片av大全日韩| 国产精品视频九色porn| 最新欧美精品一区二区三区| 亚洲六月丁香色婷婷综合久久 | 欧美裸体bbwbbwbbw| 欧美一区二区三区婷婷月色| 精品日本一线二线三线不卡| 久久久亚洲精华液精华液精华液| 中文一区二区完整视频在线观看|