Index: /trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 43567)
+++ /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 43568)
@@ -60,4 +60,5 @@
 #include "PIIX3ATABmDma.h"
 #include "ide.h"
+#include "ATAPIPassthrough.h"
 #include "VBoxDD.h"
 
@@ -305,10 +306,6 @@
     /** The revision string for SCSI INQUIRY commands. */
     char                                szInquiryRevision[ATAPI_INQUIRY_REVISION_LENGTH+1];
-    /** Size of the current CUE sheet in bytes. */
-    uint32_t                            cbCueSheet;
-    /** Align pbCueSheet correctly. */
-    uint32_t                            u32Alignment3;
-    /** The current CUE Sheet if passthrough is used. */
-    R3PTRTYPE(uint8_t *)                pbCueSheet;
+    /** The current tracklist of the loaded medium if passthrough is used. */
+    R3PTRTYPE(PTRACKLIST)               pTrackList;
 
     uint8_t                             abAlignment4[HC_ARCH_BITS == 64 ? 7 : 3];
@@ -1161,115 +1158,4 @@
 
     return iRes;
-}
-
-/**
- * Return the correct sector size from the given LBA.
- *
- * @returns Sector size.
- * @param   s            ATA Device state.
- * @param   iATAPILBA    The LBA.
- */
-static size_t atapiGetSectorSizeFromLba(ATADevState *s, uint32_t iATAPILBA)
-{
-    size_t cbATAPISector = 2048;
-
-    /*
-     * Check if there is a valid CUE Sheet we can use,
-     * otherwise we just return the standard sector size.
-     */
-    if (s->pbCueSheet)
-    {
-        uint8_t *pbCueSheetEntry = NULL;
-        uint8_t iMSF[3];
-
-        /*
-         * Convert the LBA to the MSF format so we can look it up in the cue sheet.
-         * Note that it is possible to have negative LBA values for the Lead-In area.
-         * See MMC6 spec chapter 6.46.3.3 for more details.
-         */
-        LogFlowFunc(("iATAPILBA=%#x (signed: %d unsigned: %u)\n",
-                     iATAPILBA, (int32_t)iATAPILBA, iATAPILBA));
-
-        if (   iATAPILBA > UINT32_C(0xffff4fa1)
-            && (int32_t)iATAPILBA < -150)
-        {
-            /* Lead-In area, this is always the first entry in the cue sheet. */
-            pbCueSheetEntry = s->pbCueSheet;
-            LogFlowFunc(("Selected Lead-In area\n"));
-        }
-        else
-        {
-            iATAPILBA += 150;
-            iMSF[0] = (iATAPILBA / 75) / 60;
-            iMSF[1] = (iATAPILBA / 75) % 60;
-            iMSF[2] = iATAPILBA % 75;
-
-            pbCueSheetEntry = s->pbCueSheet + 8; /* Start after the Lead-in track. */
-
-            /* Go through the CUE sheet and find the correct entry. */
-            for (unsigned i = 0; i < (s->cbCueSheet / 8) - 2; i++)
-            {
-                if (   atapiCmpMSF(&pbCueSheetEntry[5], iMSF) != 1
-                    && atapiCmpMSF(&pbCueSheetEntry[8+5], iMSF) == 1)
-                    break;
-                pbCueSheetEntry += 8;
-            }
-            LogFlowFunc(("Selected CUE sheet entry iMin=%u iSec=%u iFrame=%u\n",
-                         pbCueSheetEntry[5], pbCueSheetEntry[6], pbCueSheetEntry[7]));
-        }
-
-        if (pbCueSheetEntry)
-        {
-            /* Determine size of main data based on the data form field. */
-            switch (pbCueSheetEntry[3] & 0x3f)
-            {
-                case 0x00: /* CD-DA with data. */
-                case 0x11: /* CD-ROM mode 1 */
-                case 0x13:
-                case 0x21: /* CD-ROM XA, CD-I */
-                case 0x23:
-                case 0x31: /* CD-ROM Mode 2 */
-                case 0x33:
-                    cbATAPISector = 2352;
-                    break;
-                case 0x01: /* CD-DA without data (used for pauses between tracks). */
-                case 0x14:
-                case 0x24:
-                case 0x34:
-                    cbATAPISector = 0;
-                    break;
-                case 0x10: /* CD-ROM mode 1 */
-                case 0x12:
-                    cbATAPISector = 2048;
-                    break;
-                case 0x20: /* CD-ROM XA, CD-I */
-                case 0x22:
-                case 0x30: /* CD-ROM Mode 2 */
-                case 0x32:
-                    cbATAPISector = 2336;
-                    break;
-                default: /* Reserved, invalid mode. Log and leave default sector size. */
-                    LogRel(("ATA: Invalid data form mode %u for current CUE sheet\n",
-                            pbCueSheetEntry[3] & 0x3f));
-            }
-
-            /* Determine size of sub channel data based on data form field. */
-            switch ((pbCueSheetEntry[3] & 0xc0) >> 6)
-            {
-                case 0x00: /* Sub channel all zeroes, autogenerated by the drive. */
-                    break;
-                case 0x01:
-                case 0x03:
-                    cbATAPISector += 96;
-                    break;
-                default:
-                    LogRel(("ATA: Invalid sub-channel data form mode %u for current CUE sheet\n",
-                            pbCueSheetEntry[3] & 0xc0));
-            }
-        }
-    }
-
-    LogFlowFunc(("cbATAPISector=%zu\n", cbATAPISector));
-    return cbATAPISector;
 }
 
@@ -2243,30 +2129,19 @@
             case SCSI_SEND_CUE_SHEET:
             {
-                /* Save the CUE sheet to determine sector sizes during writes */
-                if (s->pbCueSheet)
-                {
-                    s->cbCueSheet = 0;
-                    RTMemFree(s->pbCueSheet);
-                }
-
-                s->pbCueSheet = (uint8_t *)RTMemAllocZ(s->cbElementaryTransfer);
-                if (s->pbCueSheet)
-                {
-                    s->cbCueSheet = s->cbElementaryTransfer;
-                    memcpy(s->pbCueSheet, s->CTX_SUFF(pbIOBuffer), s->cbElementaryTransfer);
-                }
-                else if (s->cErrors++ < MAX_LOG_REL_ERRORS)
-                    LogRel(("ATA: Out of memory while saving the CUE sheet, burning disc might fail\n"));
+                if (!s->pTrackList)
+                    rc = ATAPIPassthroughTrackListCreateEmpty(&s->pTrackList);
+
+                if (RT_SUCCESS(rc))
+                    rc = ATAPIPassthroughTrackListUpdate(s->pTrackList, s->aATAPICmd, s->CTX_SUFF(pbIOBuffer));
+
+                if (   RT_FAILURE(rc)
+                    && s->cErrors++ < MAX_LOG_REL_ERRORS)
+                    LogRel(("ATA: Error (%Rrc) while updating the tracklist during SEND CUE SHEET, burning the disc might fail\n",
+                            rc));
                 break;
             }
             case SCSI_SYNCHRONIZE_CACHE:
             {
-                /* Free the current CUE sheet after session at once recording. */
-                if (s->pbCueSheet)
-                {
-                    s->cbCueSheet = 0;
-                    RTMemFree(s->pbCueSheet);
-                    s->pbCueSheet = NULL;
-                }
+                ATAPIPassthroughTrackListClear(s->pTrackList);
                 break;
             }
@@ -3773,5 +3648,8 @@
             iATAPILBA = ataBE2H_U32(pbPacket + 2);
             cSectors = ataBE2H_U16(pbPacket + 7);
-            s->cbATAPISector = atapiGetSectorSizeFromLba(s, iATAPILBA);
+            if (s->pTrackList)
+                s->cbATAPISector = ATAPIPassthroughTrackListGetSectorSizeFromLba(s->pTrackList, iATAPILBA);
+            else
+                s->cbATAPISector = 2048;
             Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector));
             cbTransfer = cSectors * s->cbATAPISector;
@@ -3781,5 +3659,8 @@
             iATAPILBA = ataBE2H_U32(pbPacket + 2);
             cSectors = ataBE2H_U32(pbPacket + 6);
-            s->cbATAPISector = atapiGetSectorSizeFromLba(s, iATAPILBA);
+            if (s->pTrackList)
+                s->cbATAPISector = ATAPIPassthroughTrackListGetSectorSizeFromLba(s->pTrackList, iATAPILBA);
+            else
+                s->cbATAPISector = 2048;
             Log2(("ATAPI PT: lba %d sectors %d sector size %d\n", iATAPILBA, cSectors, s->cbATAPISector));
             cbTransfer = cSectors * s->cbATAPISector;
@@ -6323,8 +6204,8 @@
         for (uint32_t iIf = 0; iIf < RT_ELEMENTS(pThis->aCts[i].aIfs); iIf++)
         {
-            if (pThis->aCts[i].aIfs[iIf].pbCueSheet)
+            if (pThis->aCts[i].aIfs[iIf].pTrackList)
             {
-                RTMemFree(pThis->aCts[i].aIfs[iIf].pbCueSheet);
-                pThis->aCts[i].aIfs[iIf].pbCueSheet = NULL;
+                ATAPIPassthroughTrackListDestroy(pThis->aCts[i].aIfs[iIf].pTrackList);
+                pThis->aCts[i].aIfs[iIf].pTrackList = NULL;
             }
         }
Index: /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
===================================================================
--- /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 43567)
+++ /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp	(revision 43568)
@@ -830,6 +830,5 @@
     GEN_CHECK_OFF(ATADevState, szInquiryRevision);
     GEN_CHECK_OFF(ATADevState, szInquiryRevision[ATAPI_INQUIRY_REVISION_LENGTH]);
-    GEN_CHECK_OFF(ATADevState, cbCueSheet);
-    GEN_CHECK_OFF(ATADevState, pbCueSheet);
+    GEN_CHECK_OFF(ATADevState, pTrackList);
     GEN_CHECK_SIZE(ATATransferRequest);
     GEN_CHECK_OFF(ATATransferRequest, iIf);
