pureikyubu/SRC/DVD/GCM.cpp
2020-08-09 12:46:30 +03:00

114 lines
2.5 KiB
C++

// simple GCM image reading.
#include "pch.h"
// local data
// ---------------------------------------------------------------------------
bool GCMMountFile(const wchar_t*file)
{
FILE* gcm_file;
dvd.gcm_filename[0] = 0;
dvd.mountedImage = false;
if (file == nullptr)
{
return true;
}
// open GCM file
gcm_file = fopen(Util::WstringToString(file).c_str(), "rb");
if(!gcm_file) return false;
// get file size
fseek(gcm_file, 0, SEEK_END);
dvd.gcm_size = ftell(gcm_file);
fseek(gcm_file, 0, SEEK_SET);
fclose(gcm_file);
// protect from damaged GCMs
if(dvd.gcm_size < DVD_APPLDR_OFFSET)
{
return false;
}
// reset position
dvd.seekval = 0;
wcscpy(dvd.gcm_filename, file);
dvd.mountedImage = true;
return true;
}
void GCMSeek(int position)
{
dvd.seekval = position;
}
bool GCMRead(uint8_t*buf, size_t length)
{
FILE* gcm_file;
if (dvd.gcm_filename[0] == 0)
{
memset(buf, 0, length); // fill by zeroes
return true;
}
gcm_file = fopen ( Util::WstringToString(dvd.gcm_filename).c_str(), "rb");
if(gcm_file)
{
// out of DVD
if(dvd.seekval >= DVD_SIZE)
{
memset(buf, 0, length); // fill by zeroes
dvd.seekval += (int)length;
fclose(gcm_file);
return false;
}
// GCM files can be less than 1.4 GB,
// so just return zeroes, when seek is out of file
if(dvd.seekval >= dvd.gcm_size)
{
memset(buf, 0, length); // fill by zeroes
dvd.seekval += (int)length;
fclose(gcm_file);
return true;
}
// wrap, if seek is near to out of DVD
if( (dvd.seekval + length) >= DVD_SIZE)
{
length = DVD_SIZE - dvd.seekval;
}
// wrap, if seek is near to out of file
if( (dvd.seekval + length) >= dvd.gcm_size)
{
length = dvd.gcm_size - dvd.seekval;
}
// read data
if(length)
{
fseek(gcm_file, dvd.seekval, SEEK_SET);
// https://stackoverflow.com/questions/295994/what-is-the-rationale-for-fread-fwrite-taking-size-and-count-as-arguments
size_t bytesRead = fread(buf, 1, length, gcm_file);
fclose(gcm_file);
dvd.seekval += (int)length;
return (bytesRead == length);
}
}
else
{
memset(buf, 0, length); // fill by zeroes
return false;
}
return true;
}