| 
									
										
										
										
											2013-04-17 23:09:55 -04:00
										 |  |  | // Copyright 2013 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include <cstdio>
 | 
					
						
							|  |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-07 20:06:58 -05:00
										 |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #include "Common/FileUtil.h"
 | 
					
						
							|  |  |  | #include "DiscIO/Blob.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-17 05:18:15 -05:00
										 |  |  | #include "DiscIO/DriveBlob.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-21 01:47:53 +01:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | #include "Common/StringUtil.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | namespace DiscIO | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | DriveReader::DriveReader(const std::string& drive) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	SectorReader::SetSectorSize(2048); | 
					
						
							| 
									
										
										
										
											2013-02-27 20:04:07 -06:00
										 |  |  | 	auto const path = UTF8ToTStr(std::string("\\\\.\\") + drive); | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	m_disc_handle = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, | 
					
						
							|  |  |  | 	                           nullptr, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, nullptr); | 
					
						
							|  |  |  | 	if (m_disc_handle != INVALID_HANDLE_VALUE) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		// Do a test read to make sure everything is OK, since it seems you can get
 | 
					
						
							|  |  |  | 		// handles to empty drives.
 | 
					
						
							|  |  |  | 		DWORD not_used; | 
					
						
							|  |  |  | 		u8 *buffer = new u8[m_blocksize]; | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		if (!ReadFile(m_disc_handle, buffer, m_blocksize, (LPDWORD)¬_used, nullptr)) | 
					
						
							| 
									
										
										
										
											2009-02-24 07:30:10 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 			delete [] buffer; | 
					
						
							|  |  |  | 			// OK, something is wrong.
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 			CloseHandle(m_disc_handle); | 
					
						
							|  |  |  | 			m_disc_handle = INVALID_HANDLE_VALUE; | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2009-02-24 07:30:10 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 		delete [] buffer; | 
					
						
							| 
									
										
										
										
											2013-10-29 01:23:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	#ifdef _LOCKDRIVE // Do we want to lock the drive?
 | 
					
						
							|  |  |  | 		// Lock the compact disc in the CD-ROM drive to prevent accidental
 | 
					
						
							|  |  |  | 		// removal while reading from it.
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		m_lock_cdrom.PreventMediaRemoval = TRUE; | 
					
						
							|  |  |  | 		DeviceIoControl(m_disc_handle, IOCTL_CDROM_MEDIA_REMOVAL, | 
					
						
							|  |  |  | 		                &m_lock_cdrom, sizeof(m_lock_cdrom), nullptr, | 
					
						
							|  |  |  | 		                0, &dwNotUsed, nullptr); | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	#endif
 | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2010-03-17 01:54:40 +00:00
										 |  |  | 	SectorReader::SetSectorSize(2048); | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	m_file.Open(drive, "rb"); | 
					
						
							|  |  |  | 	if (m_file) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-02-22 16:48:54 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		NOTICE_LOG(DISCIO, "Load from DVD backup failed or no disc in drive %s", drive.c_str()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | DriveReader::~DriveReader() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | #ifdef _LOCKDRIVE // Do we want to lock the drive?
 | 
					
						
							|  |  |  | 	// Unlock the disc in the CD-ROM drive.
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	m_lock_cdrom.PreventMediaRemoval = FALSE; | 
					
						
							|  |  |  | 	DeviceIoControl (m_disc_handle, IOCTL_CDROM_MEDIA_REMOVAL, | 
					
						
							|  |  |  | 		&m_lock_cdrom, sizeof(m_lock_cdrom), nullptr, | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 		0, &dwNotUsed, nullptr); | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	if (m_disc_handle != INVALID_HANDLE_VALUE) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 		CloseHandle(m_disc_handle); | 
					
						
							|  |  |  | 		m_disc_handle = INVALID_HANDLE_VALUE; | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	m_file.Close(); | 
					
						
							| 
									
										
										
										
											2013-10-18 03:32:56 -04:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | DriveReader* DriveReader::Create(const std::string& drive) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 	DriveReader* reader = new DriveReader(drive); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	if (!reader->IsOK()) | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 		delete reader; | 
					
						
							| 
									
										
										
										
											2014-03-09 21:14:26 +01:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	return reader; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | void DriveReader::GetBlock(u64 block_num, u8* out_ptr) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-11 10:21:46 +00:00
										 |  |  | 	u8* const lpSector = new u8[m_blocksize]; | 
					
						
							| 
									
										
										
										
											2009-02-22 16:48:54 +00:00
										 |  |  | #ifdef _WIN32
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	u32 NotUsed; | 
					
						
							|  |  |  | 	u64 offset = m_blocksize * block_num; | 
					
						
							|  |  |  | 	LONG off_low = (LONG)offset & 0xFFFFFFFF; | 
					
						
							|  |  |  | 	LONG off_high = (LONG)(offset >> 32); | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	SetFilePointer(m_disc_handle, off_low, &off_high, FILE_BEGIN); | 
					
						
							|  |  |  | 	if (!ReadFile(m_disc_handle, lpSector, m_blocksize, (LPDWORD)&NotUsed, nullptr)) | 
					
						
							| 
									
										
										
										
											2011-01-13 02:05:58 +00:00
										 |  |  | 		PanicAlertT("Disc Read Error"); | 
					
						
							| 
									
										
										
										
											2009-02-22 16:48:54 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	m_file.Seek(m_blocksize * block_num, SEEK_SET); | 
					
						
							|  |  |  | 	m_file.ReadBytes(lpSector, m_blocksize); | 
					
						
							| 
									
										
										
										
											2009-02-22 16:48:54 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	memcpy(out_ptr, lpSector, m_blocksize); | 
					
						
							|  |  |  | 	delete[] lpSector; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-12 15:33:41 -04:00
										 |  |  | bool DriveReader::ReadMultipleAlignedBlocks(u64 block_num, u64 num_blocks, u8* out_ptr) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | 	u32 NotUsed; | 
					
						
							|  |  |  | 	u64 offset = m_blocksize * block_num; | 
					
						
							|  |  |  | 	LONG off_low = (LONG)offset & 0xFFFFFFFF; | 
					
						
							|  |  |  | 	LONG off_high = (LONG)(offset >> 32); | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	SetFilePointer(m_disc_handle, off_low, &off_high, FILE_BEGIN); | 
					
						
							|  |  |  | 	if (!ReadFile(m_disc_handle, out_ptr, (DWORD)(m_blocksize * num_blocks), (LPDWORD)&NotUsed, nullptr)) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-01-13 02:05:58 +00:00
										 |  |  | 		PanicAlertT("Disc Read Error"); | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2009-02-21 23:44:40 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-09-01 15:48:02 -04:00
										 |  |  | 	fseeko(m_file.GetHandle(), (m_blocksize * block_num), SEEK_SET); | 
					
						
							|  |  |  | 	if (fread(out_ptr, 1, (m_blocksize * num_blocks), m_file.GetHandle()) != (m_blocksize * num_blocks)) | 
					
						
							| 
									
										
										
										
											2010-01-11 23:28:54 +00:00
										 |  |  | 		return false; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-08 05:30:24 +00:00
										 |  |  | }  // namespace
 |