mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
107 lines
2.1 KiB
C++
107 lines
2.1 KiB
C++
![]() |
#include "VolumeStream.h"
|
||
|
|
||
|
using namespace Framework;
|
||
|
using namespace Framework::Win32;
|
||
|
|
||
|
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 "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 "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);
|
||
|
}
|