| 160 | |
| 161 | |
| 162 | BOOL CryptFileForward::Read(unsigned char *buf, DWORD buflen, LPDWORD pNread, LONGLONG offset) |
| 163 | { |
| 164 | |
| 165 | |
| 166 | if (m_real_file_size == (long long)-1) |
| 167 | return FALSE; |
| 168 | |
| 169 | if (!pNread || !buf) |
| 170 | return FALSE; |
| 171 | |
| 172 | *pNread = 0; |
| 173 | |
| 174 | if (buflen == 0) { |
| 175 | return TRUE; |
| 176 | } |
| 177 | |
| 178 | LONGLONG bytesleft = buflen; |
| 179 | |
| 180 | unsigned char *p = buf; |
| 181 | |
| 182 | shared_ptr<EVP_CIPHER_CTX> context; |
| 183 | GetKeys(); |
| 184 | if (!m_con->GetConfig()->m_AESSIV) { |
| 185 | context = get_crypt_context(BLOCK_IV_LEN, AES_MODE_GCM); |
| 186 | |
| 187 | if (!context) |
| 188 | return FALSE; |
| 189 | } |
| 190 | |
| 191 | BOOL bRet = TRUE; |
| 192 | |
| 193 | IoBuffer *iobuf = NULL; |
| 194 | BYTE *inputbuf = NULL; |
| 195 | int bytesinbuf = 0; |
| 196 | int inputbuflen = 0; |
| 197 | int inputbufpos = 0; |
| 198 | |
| 199 | int blocks_spanned = (int)(((offset + buflen - 1) / PLAIN_BS) - (offset / PLAIN_BS)) + 1; |
| 200 | |
| 201 | OVERLAPPED ov; |
| 202 | memset(&ov, 0, sizeof(ov)); |
| 203 | |
| 204 | try { |
| 205 | |
| 206 | if (blocks_spanned > 1 && m_con->m_bufferblocks > 1) { |
| 207 | inputbuflen = min(m_con->m_bufferblocks, blocks_spanned)*CIPHER_BS; |
| 208 | iobuf = IoBufferPool::getInstance().GetIoBuffer(inputbuflen, 0); |
| 209 | if (iobuf == NULL) { |
| 210 | SetLastError(ERROR_OUTOFMEMORY); |
| 211 | throw(-1); |
| 212 | } |
| 213 | inputbuf = iobuf->m_pBuf; |
| 214 | |
| 215 | long long blockoff = FILE_HEADER_LEN + (offset / PLAIN_BS)*CIPHER_BS; |
| 216 | |
| 217 | SetOverlapped(&ov, blockoff); |
| 218 | } |
| 219 |
no test coverage detected