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 | |
| 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')
| -rw-r--r-- | Source/Core/DiscIO/Src/Blob.cpp | 4 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/DriveBlob.cpp | 130 | ||||
| -rw-r--r-- | Source/Core/DiscIO/Src/DriveBlob.h | 41 |
3 files changed, 154 insertions, 21 deletions
diff --git a/Source/Core/DiscIO/Src/Blob.cpp b/Source/Core/DiscIO/Src/Blob.cpp index c592c61c33..4d0161a4ed 100644 --- a/Source/Core/DiscIO/Src/Blob.cpp +++ b/Source/Core/DiscIO/Src/Blob.cpp @@ -94,8 +94,8 @@ bool SectorReader::Read(u64 offset, u64 size, u8* out_ptr) IBlobReader* CreateBlobReader(const char* filename) { - //if (strlen(filename) < 4 && filename[1] == ':') // Drive, for sure. - // return DriveReader::Create(filename); + if(File::IsDisk(filename)) + return DriveReader::Create(filename); if (!File::Exists(filename)) return 0; 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 diff --git a/Source/Core/DiscIO/Src/DriveBlob.h b/Source/Core/DiscIO/Src/DriveBlob.h index 46154fe2fd..41aad2f09c 100644 --- a/Source/Core/DiscIO/Src/DriveBlob.h +++ b/Source/Core/DiscIO/Src/DriveBlob.h @@ -22,36 +22,41 @@ #ifdef _WIN32 #include <windows.h> +#include <winioctl.h> #endif namespace DiscIO { -#ifdef _WIN32 class DriveReader : public SectorReader { - HANDLE hDisc; - private: - DriveReader(const char *drive) { - /* - char path[MAX_PATH]; - strncpy(path, drive, 3); - path[2] = 0; - sprintf(path, "\\\\.\\%s", drive); - hDisc = CreateFile(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - SetSectorSize(2048); - */ - } - + DriveReader(const char *drive); + void DriveReader::SetSectorSize(int blocksize); + enum { CACHE_SIZE = 32 }; + int m_blocksize; + u8* cache[CACHE_SIZE]; + u64 cache_tags[CACHE_SIZE]; + int cache_age[CACHE_SIZE]; + void GetBlock(u64 block_num, u8 *out_ptr); +#ifdef _WIN32 + HANDLE hDisc; + PREVENT_MEDIA_REMOVAL pmrLockCDROM; +#else + FILE* file_; +#endif + s64 size; + u64 *block_pointers; public: - static DriveReader *Create(const char *drive) { - return NULL;// new DriveReader(drive); - } + static DriveReader *Create(const char *drive); + ~DriveReader(); + u64 GetDataSize() const { return size; } + u64 GetRawSize() const { return size; } + bool Read(u64 offset, u64 nbytes, u8* out_ptr); + const u8 *GetBlockData(u64 block_num); }; -#endif |
