Index: trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 32087)
+++ trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 32088)
@@ -98,4 +98,9 @@
 #define ATA_EVENT_STATUS_MEDIA_CHANGED          3    /**< medium was removed + new medium was inserted */
 #define ATA_EVENT_STATUS_MEDIA_EJECT_REQUESTED  4    /**< medium eject requested (eject button pressed) */
+
+/* Media track type */
+#define ATA_MEDIA_TYPE_UNKNOWN                  0    /**< unknown CD type */
+#define ATA_MEDIA_TYPE_DATA                     1    /**< Data CD */
+#define ATA_MEDIA_TYPE_CDDA                     2    /**< CD-DA  (audio) CD type */
 
 /**
@@ -207,5 +212,6 @@
     volatile uint32_t MediaEventStatus;
 
-    uint32_t Alignment0;
+    /** Media type if known. */
+    volatile uint32_t MediaTrackType;
 
     /** The status LED state for this drive. */
@@ -1878,4 +1884,11 @@
 }
 
+/**
+ * Sets the given media track type.
+ */
+static uint32_t ataMediumTypeSet(ATADevState *s, uint32_t MediaTrackType)
+{
+    return ASMAtomicXchgU32(&s->MediaTrackType, MediaTrackType);
+}
 
 static bool atapiPassthroughSS(ATADevState *s)
@@ -2034,4 +2047,33 @@
                 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 16, "CD-ROM", 16);
                 ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 32, "1.0", 4);
+            }
+            else if (s->aATAPICmd[0] == SCSI_READ_TOC_PMA_ATIP)
+            {
+                /* Set the media type if we can detect it. */
+                uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
+
+                /** @todo: Implemented only for formatted TOC now. */
+                if (   (s->aATAPICmd[1] & 0xf) == 0
+                    && cbTransfer >= 6)
+                {
+                    uint32_t NewMediaType;
+                    uint32_t OldMediaType;
+
+                    if (pbBuf[5] & 0x4)
+                        NewMediaType = ATA_MEDIA_TYPE_DATA;
+                    else
+                        NewMediaType = ATA_MEDIA_TYPE_CDDA;
+
+                    OldMediaType = ataMediumTypeSet(s, NewMediaType);
+
+                    if (OldMediaType != NewMediaType)
+                        LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough, detected %s CD\n",
+                                s->iLUN,
+                                NewMediaType == ATA_MEDIA_TYPE_DATA
+                                ? "data"
+                                : "audio"));
+                }
+                else /* Play safe and set to unknown. */
+                    ataMediumTypeSet(s, ATA_MEDIA_TYPE_UNKNOWN);
             }
             if (cbTransfer)
@@ -3189,8 +3231,38 @@
             goto sendcmd;
         case SCSI_READ_CD:
-            s->cbATAPISector = 2048; /**< @todo this size is not always correct */
+        {
+            /* Get sector size based on the expected sector type field. */
+            switch ((pbPacket[1] >> 2) & 0x7)
+            {
+                case 0x0: /* All types. */
+                    if (ASMAtomicReadU32(&s->MediaTrackType) == ATA_MEDIA_TYPE_CDDA)
+                        s->cbATAPISector = 2352;
+                    else
+                        s->cbATAPISector = 2048; /* Might be incorrect if we couldn't determine the type. */
+                    break;
+                case 0x1: /* CD-DA */
+                    s->cbATAPISector = 2352;
+                    break;
+                case 0x2: /* Mode 1 */
+                    s->cbATAPISector = 2048;
+                    break;
+                case 0x3: /* Mode 2 formless */
+                    s->cbATAPISector = 2336;
+                    break;
+                case 0x4: /* Mode 2 form 1 */
+                    s->cbATAPISector = 2048;
+                    break;
+                case 0x5: /* Mode 2 form 2 */
+                    s->cbATAPISector = 2324;
+                    break;
+                default: /* Reserved */
+                    AssertMsgFailed(("Unknown sector type\n"));
+                    s->cbATAPISector = 0; /** @todo we should probably fail the command here already. */
+            }
+
             cbTransfer = ataBE2H_U24(pbPacket + 6) * s->cbATAPISector;
             uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
             goto sendcmd;
+        }
         case SCSI_READ_CD_MSF:
             cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
@@ -3435,5 +3507,4 @@
 }
 
-
 /**
  * Called when a media is mounted.
@@ -3461,4 +3532,5 @@
         pIf->cNotifiedMediaChange = 2;
     ataMediumInserted(pIf);
+    ataMediumTypeSet(pIf, ATA_MEDIA_TYPE_UNKNOWN);
 }
 
@@ -3481,4 +3553,5 @@
     pIf->cNotifiedMediaChange = 4;
     ataMediumRemoved(pIf);
+    ataMediumTypeSet(pIf, ATA_MEDIA_TYPE_UNKNOWN);
 }
 
@@ -3497,4 +3570,5 @@
     s->cNotifiedMediaChange = 0;
     ASMAtomicWriteU32(&s->MediaEventStatus, ATA_EVENT_STATUS_UNCHANGED);
+    ASMAtomicWriteU32(&s->MediaTrackType, ATA_MEDIA_TYPE_UNKNOWN);
     ataUnsetIRQ(s);
 
Index: trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 32087)
+++ trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 32088)
@@ -713,4 +713,5 @@
     GEN_CHECK_OFF(ATADevState, cNotifiedMediaChange);
     GEN_CHECK_OFF(ATADevState, MediaEventStatus);
+    GEN_CHECK_OFF(ATADevState, MediaTrackType);
     GEN_CHECK_OFF(ATADevState, Led);
     GEN_CHECK_OFF(ATADevState, cbIOBuffer);
