Here is the changed version a made for it: http://baiy.cn/tmp/sqlite.zip .

Search "by BaiYang - add piRealAmt" to go through all changes I have made.

With these simple changes, I could for example, write a simple VFS shim that 
implement data encryption by only adding decrypt algorithm for xRead, adding 
encrypt algorithm for xWrite, and forward ALL other methods to the underlayer 
VFS.

On the other hand, without the piRealAmt argument, we need to re-implement a 
complete VFS to add the encryption functionality.

--
  Best Regards
  BaiYang
  baiy...@263.net.cn
  http://baiy.cn
**** < END OF EMAIL > ****

发件人: BaiYang
发送时间: 2012-04-27 05:54
收件人: sqlite-users
主题: the xRead method in sqlite3_io_methods
We should add a new output argument for xRead method which is in 
sqlite3_io_methods structure like this:

int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst, int* 
piRealAmt);

The new 'piRealAmt' could be used to report the actual read data, this argument 
will greatly boost the ability of VFS Shims. For example, with this argument, 
we can write a encryption shim easily.

It's very simple. Basically, you only need adding just one line code per xRead 
driver like this:

  }else{
    pFile->lastErrno = 0; /* not a system error */
    /* Unread parts of the buffer must be zero-filled */
    memset(&((char*)pBuf)[got], 0, amt-got);
    if (piRealAmt) *piRealAmt = (int)got; // <----
    return SQLITE_IOERR_SHORT_READ;
  }

By using this simple extension, we can write code like this:

//! shim xRead driver for encryption
BAIY_LOCAL int
ReadMethod(
    IN OUT       sqlite3_file* piFile, 
    OUT          void*         pbBuf, 
    IN           int           nAmt, 
    IN           sqlite_int64  nnOfst,
    OPTIONAL OUT int*          piRealAmt)
{
    // =========================================================================
    // = Init, Guard
    ENCVFS_FILE* piOriFile = reinterpret_cast<ENCVFS_FILE*>(piFile);
    if (piOriFile->btUnder.empty() || !piOriFile->thCipher.IsValid())
    {
        return SQLITE_IOERR_READ;
    }
    
    sqlite3_file* const piUnder = reinterpret_cast<sqlite3_file*>(
        piOriFile->btUnder.ref()
        );

    // =========================================================================
    // = Read
    int nReadLen;
    piOriFile->btBuf.reserve(nAmt);
    
    const int r = piUnder->pMethods->xRead(
        piUnder, piOriFile->btBuf.ref(), nAmt, nnOfst, &nReadLen
        );
    
    switch (r)
    {
    case SQLITE_OK:
        nReadLen = nAmt;
        break;
    case SQLITE_IOERR_SHORT_READ:
        break;
    default:
        return r; // <----
    }
    
    // =========================================================================
    // = Decrypt
    try
    {
        piOriFile->thCipher->SeekDecryptor(nnOfst);
        piOriFile->thCipher->IterDecrypt(
            bySBn((BYTE*)pbBuf, nReadLen), piOriFile->btBuf
        );
    
        if (SQLITE_IOERR_SHORT_READ == r)
        {
            memset(((BYTE*)pbBuf)+nReadLen, 0, nAmt-nReadLen);
            if (piRealAmt)
            {
                *piRealAmt = nReadLen;
            }
            return SQLITE_IOERR_SHORT_READ;
        }
        else
        {
            return SQLITE_OK;
        }
    }
    catch (...)
    {
        LogError(byT("ReadMethod"));
        return SQLITE_IOERR_READ;
    }
}

--
  Best Regards
  BaiYang
  baiy...@263.net.cn
  http://baiy.cn
**** < END OF EMAIL > ****
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to