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