mirror of
https://github.com/libretro/Play-.git
synced 2024-11-27 18:50:28 +00:00
108 lines
2.2 KiB
C++
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);
|
|
}
|