// Copyright (C) 2003-2008 Dolphin Project. // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 2.0. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License 2.0 for more details. // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ #include "stdafx.h" #include "DriveBlob.h" namespace DiscIO { DriveReader::DriveReader(const char *drive) { #ifdef _WIN32 char path[MAX_PATH]; strncpy(path, drive, 3); path[2] = 0; sprintf(path, "\\\\.\\%s", drive); hDisc = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); if (hDisc == INVALID_HANDLE_VALUE) { PanicAlert("Load from DVD backup failed"); } else { SectorReader::SetSectorSize(2048); #ifdef _LOCKDRIVE // Lock the compact disc in the CD-ROM drive to prevent accidental // removal while reading from it. pmrLockCDROM.PreventMediaRemoval = TRUE; DeviceIoControl (hDisc, IOCTL_CDROM_MEDIA_REMOVAL, &pmrLockCDROM, sizeof(pmrLockCDROM), NULL, 0, &dwNotUsed, NULL); #endif } #else file_ = fopen(drive, "rb"); if (!file_) PanicAlert("Load from DVD backup failed"); else SetSectorSize(2048); #endif } // DriveReader::DriveReader DriveReader::~DriveReader() { #ifdef _WIN32 #ifdef _LOCKDRIVE // Do we want to lock the drive? // Unlock the disc in the CD-ROM drive. pmrLockCDROM.PreventMediaRemoval = FALSE; DeviceIoControl (hDisc, IOCTL_CDROM_MEDIA_REMOVAL, &pmrLockCDROM, sizeof(pmrLockCDROM), NULL, 0, &dwNotUsed, NULL); #endif CloseHandle(hDisc); #else fclose(file_); #endif } DriveReader * DriveReader::Create(const char *drive) { return new DriveReader(drive); } void DriveReader::GetBlock(u64 block_num, u8 *out_ptr) { u32 NotUsed; u8 * lpSector = new u8[m_blocksize]; #ifdef _WIN32 u64 offset = m_blocksize * block_num; LONG off_low = (LONG)offset & 0xFFFFFFFF; LONG off_high = (LONG)(offset >> 32); SetFilePointer(hDisc, off_low, &off_high, FILE_BEGIN); if (!ReadFile(hDisc, lpSector, m_blocksize, (LPDWORD)&NotUsed, NULL)) PanicAlert("DRE"); #else fseek(file_, m_blocksize*block_num, SEEK_SET); fread(lpSector, 1, m_blocksize, file_); #endif memcpy(out_ptr, lpSector, m_blocksize); delete lpSector; } bool DriveReader::ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8 *out_ptr) { u32 NotUsed; #ifdef _WIN32 u64 offset = m_blocksize * block_num; LONG off_low = (LONG)offset & 0xFFFFFFFF; LONG off_high = (LONG)(offset >> 32); SetFilePointer(hDisc, off_low, &off_high, FILE_BEGIN); if (!ReadFile(hDisc, out_ptr, (DWORD)(m_blocksize * num_blocks), (LPDWORD)&NotUsed, NULL)) PanicAlert("DRE"); #else fseek(file_, m_blocksize*block_num, SEEK_SET); fread(out_ptr, 1, m_blocksize * num_blocks, file_); #endif return true; } } // namespace