summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2003-10-12 05:15:00 +0000
committerpixel <pixel>2003-10-12 05:15:00 +0000
commit7787631c6ee37a489732c95cb0864422e3a3bdd1 (patch)
tree4f6374a3dcc58661ea7b116e2b87cdf84e14e414
parent7cf5187c0a8cedba390a5455b63ed4ecf867be32 (diff)
AT LAST!!!
Windows 2k/XP CD reading works using raw ioctls!!!! HURRAY!!!!!!!!
-rw-r--r--MSVC/Tools/Tools.vcproj12
-rw-r--r--MSVC/Tools/master.mak9
-rw-r--r--PE/nmakefile2
-rw-r--r--PE/pepatch.cpp7
-rw-r--r--Xenogears/main_dump.cpp2
-rw-r--r--cd-tool.cpp2
-rw-r--r--includes/cdabstract.h40
-rw-r--r--includes/cdreader.h11
-rw-r--r--lib/cdabstract.cpp147
-rw-r--r--lib/cdreader.cpp56
10 files changed, 270 insertions, 18 deletions
diff --git a/MSVC/Tools/Tools.vcproj b/MSVC/Tools/Tools.vcproj
index 2e2174b..a8c93ac 100644
--- a/MSVC/Tools/Tools.vcproj
+++ b/MSVC/Tools/Tools.vcproj
@@ -107,6 +107,9 @@
Name="Parasite Eve tools"
Filter="">
<File
+ RelativePath="..\..\PE\Aya.bmp">
+ </File>
+ <File
RelativePath="..\..\PE\aya.ico">
</File>
<File
@@ -128,6 +131,15 @@
RelativePath="..\..\PE\nmakefile">
</File>
<File
+ RelativePath="..\..\PE\pepatch-res.h">
+ </File>
+ <File
+ RelativePath="..\..\PE\pepatch.cpp">
+ </File>
+ <File
+ RelativePath="..\..\PE\pepatch.rc">
+ </File>
+ <File
RelativePath="..\..\PE\reinsert-res.h">
</File>
<File
diff --git a/MSVC/Tools/master.mak b/MSVC/Tools/master.mak
index 82a7f16..11ee305 100644
--- a/MSVC/Tools/master.mak
+++ b/MSVC/Tools/master.mak
@@ -48,9 +48,9 @@ _XSD=xsd.exe
#define our basic link line for managed code
!IFDEF DEBUG
-_LINK=link.exe /INCREMENTAL /NOLOGO /DEBUG /SUBSYSTEM:CONSOLE /MACHINE:I386 /NODEFAULTLIB:LIBC
+_LINK=link.exe /INCREMENTAL /NOLOGO /DEBUG /MACHINE:I386 /NODEFAULTLIB:LIBC USER32.LIB
!ELSE
-_LINK=link.exe /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:I386 /NODEFAULTLIB:LIBCD
+_LINK=link.exe /INCREMENTAL /NOLOGO /MACHINE:I386 /NODEFAULTLIB:LIBCD USER32.LIB
!ENDIF
#this is used for compiling C# samples
@@ -134,8 +134,9 @@ _RMDIR=deltree /y
.cpp.exe:
if not exist $(_OUTDIR) md $(_OUTDIR)
$(_CL) $(_CDFLAGS) $*.cpp
- if not exist $*.res $(_LINK) $(_LFLAGS) $(_LIBS) $*.obj
- if exist $*.res $(_LINK) $(_LFLAGS) $(_LIBS) $*.obj $*.res
+ if not exist $*.res $(_LINK) /SUBSYSTEM:CONSOLE $(_LFLAGS) $(_LIBS) $*.obj
+ if exist $*.res $(_LINK) /SUBSYSTEM:CONSOLE $(_LFLAGS) $(_LIBS) $*.obj $*.res
+ if exist $*.paq copy /b $*.exe+$*.paq $*.exe
.lex.c:
if not exist $(_OUTDIR) md $(_OUTDIR)
diff --git a/PE/nmakefile b/PE/nmakefile
index bafe2fe..158bcf9 100644
--- a/PE/nmakefile
+++ b/PE/nmakefile
@@ -9,7 +9,7 @@ _LIBS = "..\MSVC\Baltisot - generic\Release\Baltisot - generic.lib" "..\MSVC\PSX
#------------------------------------------------------------------
-TARGETS = reinsert.res extract.exe extract-rooms.exe extract-various.exe reinsert.exe compil.c compil.exe compilall.exe
+TARGETS = reinsert.res pepatch.res extract.exe extract-rooms.exe extract-various.exe reinsert.exe compil.c compil.exe compilall.exe pepatch.exe
all : $(TARGETS)
diff --git a/PE/pepatch.cpp b/PE/pepatch.cpp
index e69de29..be67faf 100644
--- a/PE/pepatch.cpp
+++ b/PE/pepatch.cpp
@@ -0,0 +1,7 @@
+#include <Main.h>
+
+CODE_BEGINS
+virtual int startup() throw (GeneralException) {
+ return 0;
+}
+CODE_ENDS
diff --git a/Xenogears/main_dump.cpp b/Xenogears/main_dump.cpp
index 65b7466..1610ec1 100644
--- a/Xenogears/main_dump.cpp
+++ b/Xenogears/main_dump.cpp
@@ -99,7 +99,7 @@ virtual int startup() throw (GeneralException)
iso_filename = argv[2];
printm(M_STATUS, "Begin processing iso file.\n");
- f_iso = open_iso(iso_filename);
+ f_iso = cdabstract::open_cd(iso_filename);
if (check_iso()) {
printm(M_ERROR, "Invalid iso file for " + title + "\n");
diff --git a/cd-tool.cpp b/cd-tool.cpp
index e748aec..d5d766b 100644
--- a/cd-tool.cpp
+++ b/cd-tool.cpp
@@ -113,7 +113,7 @@ virtual int startup() throw (GeneralException) {
exit(-1);
}
- iso_r = open_iso(iso_name);
+ iso_r = cdabstract::open_cd(iso_name);
cdutil = new cdutils(iso_r);
diff --git a/includes/cdabstract.h b/includes/cdabstract.h
index 66aa909..60061d4 100644
--- a/includes/cdabstract.h
+++ b/includes/cdabstract.h
@@ -1,8 +1,44 @@
#ifndef __CD_ABSTRACT_H__
#define __CD_ABSTRACT_H__
-#include "Handle.h"
+#if defined (_MSC_VER) || defined (__MINGW32__)
+#include <windowsx.h>
+
+#define IOCTL_SCSI_BASE 0x00000004
+
+#define METHOD_BUFFERED 0
+#define METHOD_OUT_DIRECT 2
+
+#define FILE_ANY_ACCESS 0
+#define FILE_READ_ACCESS 0x0001
+
+#define CTL_CODE( DevType, Function, Method, Access ) ( \
+ ((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
+)
+#define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS )
+#define FILE_DEVICE_CD_ROM 0x00000002
+#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
+#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
+
+#endif
+
+#include <vector>
+#include <Exceptions.h>
+#include <Handle.h>
-Handle * open_iso(const String &);
+class cdabstract : public Base {
+ public:
+ static Handle * open_cd(const String &);
+ static bool canprobe();
+ static std::vector<String> probe() throw (GeneralException);
+#if defined (_MSC_VER) || defined (__MINGW32__)
+ protected:
+ static HANDLE OpenIOCTLFile(char cLetter);
+ static void GetIOCTLAdapter(HANDLE hF, int * iDA, int * iDT, int * iDL);
+#endif
+ private:
+ static bool subprobe(String &);
+ friend class cdreader;
+};
#endif
diff --git a/includes/cdreader.h b/includes/cdreader.h
index 8ebe362..acf6765 100644
--- a/includes/cdreader.h
+++ b/includes/cdreader.h
@@ -1,11 +1,11 @@
#ifndef __CDREADER_H__
#define __CDREADER_H__
-#ifdef __cplusplus
#include <sys/types.h>
#include <time.h>
#include <BString.h>
#include <Handle.h>
+#include "cdabstract.h"
class cdreader : public Handle {
public:
@@ -15,6 +15,9 @@ class cdreader : public Handle {
virtual bool CanWrite() const;
virtual bool CanRead() const;
virtual bool CanSeek() const;
+#if defined (_MSC_VER) || defined (__MINGW32__)
+ virtual void close() throw (GeneralException);
+#endif
virtual ssize_t read(void *buf, size_t count) throw (GeneralException);
virtual off_t seek(off_t, int = SEEK_SET) throw (GeneralException);
virtual String GetName() const;
@@ -25,9 +28,9 @@ class cdreader : public Handle {
private:
String n;
int sector;
+#if defined (_MSC_VER) || defined (__MINGW32__)
+ HANDLE hF;
+#endif
};
-#else
-#error This only works with a C++ compiler
-#endif
#endif
diff --git a/lib/cdabstract.cpp b/lib/cdabstract.cpp
index b79960f..f5f0d08 100644
--- a/lib/cdabstract.cpp
+++ b/lib/cdabstract.cpp
@@ -2,14 +2,151 @@
#include "Input.h"
#include "cdreader.h"
-Handle * open_iso(const String & nom) {
-#ifdef USE_CDREADER
+#ifdef __linux__
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/cdrom.h>
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+#include <windowsx.h>
+#endif
+
+Handle * cdabstract::open_cd(const String & nom) {
if (nom.extract(0, 2).toupper() == "CD:") {
return new cdreader(nom.extract(3));
} else {
-#else
- {
-#endif
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<String> cdabstract::probe() throw (GeneralException) {
+ std::vector<String> 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;
+}
diff --git a/lib/cdreader.cpp b/lib/cdreader.cpp
index 32e815f..5e88e98 100644
--- a/lib/cdreader.cpp
+++ b/lib/cdreader.cpp
@@ -12,6 +12,7 @@
#else
#define _(x) x
#endif
+#include "cdabstract.h"
bool cdreader::CanWrite() const {
return 0;
@@ -120,5 +121,60 @@ void cdreader::getsector(void *buf, int sec) throw (GeneralException) {
sector++;
}
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+cdreader::cdreader(const String & no) throw (GeneralException) :
+ Handle(-1), n(no), sector(0) {
+ if (!(hF = cdabstract::OpenIOCTLFile(no[0])))
+ throw GeneralException("Error opening device " + no);
+}
+
+cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n), hF(i.hF) {
+}
+
+void cdreader::close() throw (GeneralException) {
+ CloseHandle(hF);
+}
+
+typedef enum _TRACK_MODE_TYPE {
+ YellowMode2,
+ XAForm2,
+ CDDA
+} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
+
+typedef struct _RAW_READ_INFO {
+ LARGE_INTEGER DiskOffset;
+ ULONG SectorCount;
+ TRACK_MODE_TYPE TrackMode;
+} RAW_READ_INFO, *PRAW_READ_INFO;
+
+void cdreader::getsector(void *buf, int sec) throw (GeneralException) {
+ RAW_READ_INFO rawIOCTL;
+ DWORD dwRet;
+ BOOL bStat;
+ bool done = false;
+ if (sec >= 0)
+ sector = sec;
+
+ rawIOCTL.DiskOffset.QuadPart = sector * 2048;
+ rawIOCTL.SectorCount = 1;
+ rawIOCTL.TrackMode = YellowMode2;
+
+ while (!done) {
+ SetLastError(0);
+ bStat = DeviceIoControl(hF, IOCTL_CDROM_RAW_READ,
+ &rawIOCTL, sizeof(RAW_READ_INFO),
+ buf, 2352, &dwRet, NULL);
+ if (!bStat) {
+ DWORD dwErrCode = GetLastError();
+ if (dwErrCode != ERROR_IO_PENDING) {
+ throw GeneralException("Gave up on reading CD");
+ }
+ } else {
+ done = true;
+ }
+ }
+}
#endif