Charles Davis : ntdll: Implement CDROM_RawRead() on Mac OS.

Alexandre Julliard julliard at winehq.org
Wed Oct 14 09:02:00 CDT 2009


Module: wine
Branch: master
Commit: 6368dbbd5939bf71b04f3c441dd3af8cd027b7fb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6368dbbd5939bf71b04f3c441dd3af8cd027b7fb

Author: Charles Davis <cdavis at mymail.mines.edu>
Date:   Tue Oct 13 12:58:59 2009 -0600

ntdll: Implement CDROM_RawRead() on Mac OS.

---

 dlls/ntdll/cdrom.c |  149 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 149 insertions(+), 0 deletions(-)

diff --git a/dlls/ntdll/cdrom.c b/dlls/ntdll/cdrom.c
index 8e334df..c0389f9 100644
--- a/dlls/ntdll/cdrom.c
+++ b/dlls/ntdll/cdrom.c
@@ -1449,6 +1449,155 @@ static NTSTATUS CDROM_RawRead(int fd, const RAW_READ_INFO* raw, void* buffer, DW
         FIXME("NIY: %d\n", raw->TrackMode);
         return STATUS_INVALID_PARAMETER;
     }
+#elif defined(__APPLE__)
+    switch (raw->TrackMode)
+    {
+    case YellowMode2:
+    {
+        /* Mac OS, on the other hand, DOES read only one part of the sector
+         * at a time. Therefore, we have to read each part of the sector, in
+         * order, to get the whole raw sector in.
+         * This means that we have to read each sector one at a time, as on
+         * Linux.
+         */
+        dk_cd_read_t cdrd;
+        UInt64 lba = raw->DiskOffset.QuadPart >> 11;
+        PBYTE bp;
+        int i;
+
+        for (i = 0, bp = buffer; i < raw->SectorCount;
+             i++, lba++, bp += kCDSectorSizeWhole)
+        {
+            cdrd.offset = lba * kCDSectorSizeWhole;
+            cdrd.sectorType = kCDSectorTypeMode2;
+
+            /* First, the sync area */
+            cdrd.sectorArea = kCDSectorAreaSync;
+            cdrd.buffer = bp;
+            cdrd.bufferLength = 12;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i;
+                return CDROM_GetStatusCode(io);
+            }
+
+            /* Then the header */
+            cdrd.offset += 12;
+            cdrd.sectorArea = kCDSectorAreaHeader;
+            cdrd.buffer = (PBYTE)cdrd.buffer + 12;
+            cdrd.bufferLength = 4;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i + 12;
+                return CDROM_GetStatusCode(io);
+            }
+
+            /* And finally the sector proper */
+            cdrd.offset += 4;
+            cdrd.sectorArea = kCDSectorAreaUser;
+            cdrd.buffer = (PBYTE)cdrd.buffer + 4;
+            cdrd.bufferLength = kCDSectorSizeMode2;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i + 16;
+                return CDROM_GetStatusCode(io);
+            }
+        }
+
+        break;
+    }
+
+    case XAForm2:
+    {
+        /* Same here */
+        dk_cd_read_t cdrd;
+        UInt64 lba = raw->DiskOffset.QuadPart >> 11;
+        PBYTE bp;
+        int i;
+
+        for (i = 0, bp = buffer; i < raw->SectorCount;
+             i++, lba++, bp += kCDSectorSizeWhole)
+        {
+            cdrd.offset = lba * kCDSectorSizeWhole;
+            cdrd.sectorType = kCDSectorTypeMode2Form2;
+
+            /* First, the sync area */
+            cdrd.sectorArea = kCDSectorAreaSync;
+            cdrd.buffer = bp;
+            cdrd.bufferLength = 12;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i;
+                return CDROM_GetStatusCode(io);
+            }
+
+            /* Then the header */
+            cdrd.offset += 12;
+            cdrd.sectorArea = kCDSectorAreaHeader;
+            cdrd.buffer = (PBYTE)cdrd.buffer + 12;
+            cdrd.bufferLength = 4;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i + 12;
+                return CDROM_GetStatusCode(io);
+            }
+
+            /* And the sub-header */
+            cdrd.offset += 4;
+            cdrd.sectorArea = kCDSectorAreaSubHeader;
+            cdrd.buffer = (PBYTE)cdrd.buffer + 4;
+            cdrd.bufferLength = 8;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i + 16;
+                return CDROM_GetStatusCode(io);
+            }
+
+            /* And finally the sector proper */
+            cdrd.offset += 8;
+            cdrd.sectorArea = kCDSectorAreaUser;
+            cdrd.buffer = (PBYTE)cdrd.buffer + 8;
+            cdrd.bufferLength = kCDSectorSizeMode2;
+            io = ioctl(fd, DKIOCCDREAD, &cdrd);
+            if (io != 0)
+            {
+                *sz = kCDSectorSizeWhole * i + 24;
+                return CDROM_GetStatusCode(io);
+            }
+        }
+
+        break;
+    }
+
+    case CDDA:
+    {
+        /* With CDDA, the whole raw sector is considered user data, so there's
+         * no need to read one at a time.
+         */
+        dk_cd_read_t cdrd;
+
+        cdrd.offset = (raw->DiskOffset.QuadPart >> 11) * kCDSectorSizeCDDA;
+        cdrd.sectorArea = kCDSectorAreaUser;
+        cdrd.sectorType = kCDSectorTypeCDDA;
+        cdrd.buffer = buffer;
+        cdrd.bufferLength = len < raw->SectorCount*kCDSectorSizeCDDA ? len :
+                            raw->SectorCount*kCDSectorSizeCDDA;
+
+        io = ioctl(fd, DKIOCCDREAD, &cdrd);
+        if (io != 0) return CDROM_GetStatusCode(io);
+        break;
+    }
+
+    default:
+        FIXME("NIY: %d\n", raw->TrackMode);
+        return STATUS_INVALID_PARAMETER;
+    }
 #else
     switch (raw->TrackMode)
     {




More information about the wine-cvs mailing list