#include #include "VolumeStream.h" using namespace Framework; using namespace Framework::Win32; using namespace std; CVolumeStream::CVolumeStream(char nDriveLetter) { char sPath[7] = { '\\', '\\', '.', '\\', nDriveLetter, ':', '\0' }; m_nVolume = CreateFileA(sPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); m_nPosition = 0; m_nSectorSize = 0x800; m_nCacheSector = m_nSectorSize - 1; m_pCache = VirtualAlloc(NULL, (SIZE_T)m_nSectorSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); } CVolumeStream::~CVolumeStream() { VirtualFree(m_pCache, 0, MEM_RELEASE); CloseHandle(m_nVolume); } void CVolumeStream::Seek(int64 nDistance, STREAM_SEEK_DIRECTION nFrom) { switch(nFrom) { case STREAM_SEEK_SET: m_nPosition = nDistance; break; case STREAM_SEEK_CUR: m_nPosition += nDistance; break; case STREAM_SEEK_END: throw exception("Operation not supported."); break; } } uint64 CVolumeStream::Tell() { return m_nPosition; } uint64 CVolumeStream::Read(void* pBuffer, uint64 nSize) { uint8* pDst; uint8* pSrc; uint64 nRetSize; pSrc = (uint8*)m_pCache; pDst = (uint8*)pBuffer; nRetSize = nSize; while(nSize != 0) { size_t nSectorRemain, nSectorOffset, nCopy; SyncCache(); nSectorOffset = (size_t)(m_nPosition & (m_nSectorSize - 1)); nSectorRemain = (size_t)(m_nSectorSize - nSectorOffset); nCopy = min((size_t)nSize, nSectorRemain); memcpy(pDst, pSrc + nSectorOffset, nCopy); m_nPosition += nCopy; nSize -= nCopy; pDst += nCopy; } return nRetSize; } uint64 CVolumeStream::Write(const void* pBuffer, uint64 nSize) { throw exception("Operation not-supported."); } bool CVolumeStream::IsEOF() { return false; } void CVolumeStream::SyncCache() { uint64 nSectorPosition; DWORD nRead; nSectorPosition = m_nPosition & ~(m_nSectorSize - 1); if(nSectorPosition == m_nCacheSector) return; m_nCacheSector = nSectorPosition; SetFilePointer(m_nVolume, (uint32)nSectorPosition, (PLONG)((uint32*)&nSectorPosition) + 1, FILE_BEGIN); ReadFile(m_nVolume, m_pCache, (DWORD)m_nSectorSize, &nRead, NULL); }