/* * PSX-Tools Bundle Pack * Copyright (C) 2002-2003 Nicolas "Pixel" Noble * * 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; either version 2 of the License, or * (at your option) any later version. * * 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* $Id: cdabstract.cpp,v 1.9 2004-11-27 21:47:56 pixel Exp $ */ #include "cdabstract.h" #include "Input.h" #include "cdreader.h" #ifdef __linux__ #include #include #include #include #endif #if defined (_MSC_VER) || defined (__MINGW32__) #include #endif Handle * cdabstract::open_cd(const String & nom) { if (nom.extract(0, 2).toupper() == "CD:") { return new cdreader(nom.extract(3)); } else { return new Input(nom); } } bool cdabstract::canprobe() { #ifdef __linux__ return true; #endif #ifdef _WIN32 OSVERSIONINFO ov; memset(&ov, 0, sizeof(OSVERSIONINFO)); ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&ov); return ((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4)); #endif return false; } std::vector cdabstract::probe() throw (GeneralException) { int i; std::vector r; String probed; if (!canprobe()) throw GeneralException("Can't probe CD devices on this platform."); #ifdef __linux__ if (subprobe(probed = "/dev/cdrom")) r.push_back(probed); for (i = 0; i < 63; i++) { probed.set("/dev/cdroms/cdrom%i", i); if (subprobe(probed)) r.push_back(probed); } for (i = 'a'; i <= 'z'; i++) { probed.set("/dev/hd%c", i); if (subprobe(probed)) r.push_back(probed); } #endif #ifdef _WIN32 for (i = 'A'; i <= 'Z'; i++) { probed.set("%c:\\", i); if (subprobe(probed)) r.push_back(probed); } #endif return r; } #ifdef _WIN32 HANDLE cdabstract::OpenIOCTLFile(char cLetter) { HANDLE hF; char szFName[16]; OSVERSIONINFO ov; DWORD dwFlags; DWORD dwIOCTLAttr = 0; memset(&ov, 0, sizeof(OSVERSIONINFO)); ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&ov); if((ov.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion > 4)) dwFlags = GENERIC_READ | GENERIC_WRITE; // add gen write on W2k/XP else dwFlags = GENERIC_READ; sprintf(szFName, "\\\\.\\%c:", cLetter); hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // open drive NULL, OPEN_EXISTING, dwIOCTLAttr, NULL); if (hF == INVALID_HANDLE_VALUE) { // mmm... no success? dwFlags ^= GENERIC_WRITE; // -> try write toggle hF = CreateFile(szFName, dwFlags, FILE_SHARE_READ, // -> open drive again NULL, OPEN_EXISTING, dwIOCTLAttr, NULL); if (hF == INVALID_HANDLE_VALUE) return NULL; } return hF; } typedef struct { ULONG Length; UCHAR PortNumber; UCHAR PathId; UCHAR TargetId; UCHAR Lun; } SCSI_ADDRESS, *PSCSI_ADDRESS; void cdabstract::GetIOCTLAdapter(HANDLE hF, int * iDA, int * iDT, int * iDL) { char szBuf[1024]; PSCSI_ADDRESS pSA; DWORD dwRet; *iDA = *iDT = *iDL = -1; if (hF == NULL) return; memset(szBuf,0,1024); pSA = (PSCSI_ADDRESS)szBuf; pSA->Length = sizeof(SCSI_ADDRESS); if (!DeviceIoControl(hF, IOCTL_SCSI_GET_ADDRESS, NULL, 0, pSA, sizeof(SCSI_ADDRESS), &dwRet, NULL)) return; *iDA = pSA->PortNumber; *iDT = pSA->TargetId; *iDL = pSA->Lun; } #endif bool cdabstract::subprobe(String & probed) { #ifdef __linux__ int h, caps; h = open(probed.to_charp(), O_RDONLY | O_NONBLOCK); if (ioctl(h, CDROM_GET_CAPABILITY, &caps) < 0) { close(h); return false; } else { close(h); return true; } #endif #ifdef _WIN32 int iDA, iDT, iDL; char letter[4]; HANDLE h; if (GetDriveType(probed.to_charp()) == DRIVE_CDROM) { h = OpenIOCTLFile(probed[0]); GetIOCTLAdapter(h, &iDA, &iDT, &iDL); CloseHandle(h); if ((iDA != -1) && (iDT != -1) && (iDL != -1)) { probed += String().set(" [%i:%i:%i]", iDA, iDT, iDL); return true; } } #endif return false; }