diff options
| author | LPFaint99 <lpfaint99@gmail.com> | 2009-02-21 23:44:40 +0000 |
|---|---|---|
| committer | LPFaint99 <lpfaint99@gmail.com> | 2009-02-21 23:44:40 +0000 |
| commit | 9cfa4e93851e2551d0237ab6727bd03dd229b34d (patch) | |
| tree | 91f9b74d93aa18944ea65e3ab1c1a926ffc62526 /Source/Core/DiscIO/Src/DriveBlob.cpp | |
| parent | b4b94fe594b117dad33ca98a8962231d926ed10e (diff) | |
Adds IsDrive to FileUtil for win32,
Adds booting from drive to gui. disabled as it is currently too slow unless it is a virtual drive
Changes DriveUtil to start checking at D: as it is unlikely that a, b, or c will be a cd/dvd drive
Addes DriveBlob functions, untested on linux/osx probably needs more work
Removes duplicate message from EXI_DeviceMemoryCard.cpp when creating a brand new memcard
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2345 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DiscIO/Src/DriveBlob.cpp')
| -rw-r--r-- | Source/Core/DiscIO/Src/DriveBlob.cpp | 130 |
1 files changed, 129 insertions, 1 deletions
diff --git a/Source/Core/DiscIO/Src/DriveBlob.cpp b/Source/Core/DiscIO/Src/DriveBlob.cpp index 11f99faada..edca16638b 100644 --- a/Source/Core/DiscIO/Src/DriveBlob.cpp +++ b/Source/Core/DiscIO/Src/DriveBlob.cpp @@ -16,10 +16,138 @@ // 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, 0, NULL); + if (hDisc == INVALID_HANDLE_VALUE) + { + PanicAlert("Load from DVD backup failed"); + } + else + { + 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 + + + DriveReader * DriveReader::Create(const char *drive) + { + return new DriveReader(drive); + } + + bool DriveReader::Read(u64 offset, u64 nbytes, u8* out_ptr) + { + u64 startingBlock = offset / m_blocksize; + u64 remain = nbytes; + int positionInBlock = (int)(offset % m_blocksize); + u64 block = startingBlock; + + while (remain > 0) + { + const u8* data = GetBlockData(block); + if (!data) + return false; + + u32 toCopy = m_blocksize - positionInBlock; + if (toCopy >= remain) + { + // yay, we are done! + memcpy(out_ptr, data + positionInBlock, (size_t)remain); + return true; + } + else + { + memcpy(out_ptr, data + positionInBlock, toCopy); + out_ptr += toCopy; + remain -= toCopy; + positionInBlock = 0; + block++; + } + } + return true; + } // DriveReader::Read + + void DriveReader::GetBlock(u64 block_num, u8 *out_ptr) + { + u32 NotUsed; + u8 * lpSector = new u8[m_blocksize]; +#ifdef _WIN32 + // TODO: Fix for 64bit block_num, SetFilePointer uses LONG + SetFilePointer (hDisc, m_blocksize*block_num, NULL, 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; + } + + void DriveReader::SetSectorSize(int blocksize) + { + for (int i = 0; i < CACHE_SIZE; i++) + { + cache[i] = new u8[blocksize]; + cache_tags[i] = (u64)(s64) - 1; + } + m_blocksize = blocksize; + } + + const u8 *DriveReader::GetBlockData(u64 block_num) + { + if (cache_tags[0] == block_num) + { + return cache[0]; + } + else + { + GetBlock(block_num, cache[0]); + cache_tags[0] = block_num; + return cache[0]; + } + } } // namespace |
