Play-/Source/VolumeStream.cpp
2018-04-30 21:01:23 +01:00

108 lines
2.2 KiB
C++

#include <exception>
#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);
}