#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 #if defined (_MSC_VER) || defined (_MINGW32) 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) { std::vector r; String probed; if (!canprobe()) throw GeneralException("Can't probe CD devices on this platform."); #ifdef __linux__ #endif #if defined (_MSC_VER) || defined (__MINGW32__) #endif return r; } #if defined (_MSC_VER) || defined (__MINGW32__) 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; wsprintf(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 #if defined (_MSC_VER) || defined (__MINGW32__) 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; }