VirtualBox

Ignore:
Timestamp:
Apr 6, 2007 6:14:10 AM (18 years ago)
Author:
vboxsync
Message:

HostDVD support for Darwin.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DrvHostBase.cpp

    r262 r1965  
    2626*******************************************************************************/
    2727#define LOG_GROUP LOG_GROUP_DRV_HOST_BASE
    28 #ifdef __LINUX__
     28#ifdef __DARWIN__
     29# include <mach/mach.h>
     30# include <Carbon/Carbon.h>
     31# include <IOKit/IOKitLib.h>
     32# include <IOKit/storage/IOStorageDeviceCharacteristics.h>
     33# include <IOKit/scsi-commands/SCSITaskLib.h>
     34# include <IOKit/scsi-commands/SCSICommandOperationCodes.h>
     35# include <mach/mach_error.h>
     36# include <VBox/scsi.h>
     37
     38#elif defined(__L4ENV__)
     39  /* Nothing special requires... yeah, right. */
     40
     41#elif defined(__LINUX__)
    2942# include <sys/ioctl.h>
    3043# include <sys/fcntl.h>
     
    7992        /*IN*/ FS_INFORMATION_CLASS FileSystemInformationClass );
    8093
    81 #elif defined(__L4ENV__)
    82 
    83 #else /* !__WIN__ nor __LINUX__ nor __L4ENV__ */
     94#else
    8495# error "Unsupported Platform."
    85 #endif /* !__WIN__ nor __LINUX__ nor __L4ENV__ */
     96#endif
    8697
    8798#include <VBox/pdm.h>
     
    100111#include <iprt/asm.h>
    101112#include <iprt/critsect.h>
     113#include <iprt/ctype.h>
    102114
    103115#include "DrvHostBase.h"
     
    120132     */
    121133    int rc;
     134#ifdef __DARWIN__
     135    if (    pThis->fMediaPresent
     136        &&  pThis->ppScsiTaskDI
     137        &&  pThis->cbBlock)
     138#else
    122139    if (pThis->fMediaPresent)
    123     {
     140#endif
     141    {
     142#ifdef __DARWIN__
     143        /*
     144         * Issue a READ(12) request.
     145         */
     146        const uint32_t LBA = off / pThis->cbBlock;
     147        AssertReturn(!(off % pThis->cbBlock), VERR_INVALID_PARAMETER);
     148        const uint32_t cBlocks = cbRead / pThis->cbBlock;
     149        AssertReturn(!(cbRead % pThis->cbBlock), VERR_INVALID_PARAMETER);
     150        uint8_t abCmd[16] =
     151        {
     152            SCSI_READ_12, 0,
     153            RT_BYTE4(LBA),     RT_BYTE3(LBA),     RT_BYTE2(LBA),     RT_BYTE1(LBA),
     154            RT_BYTE4(cBlocks), RT_BYTE3(cBlocks), RT_BYTE2(cBlocks), RT_BYTE1(cBlocks),
     155            0, 0, 0, 0, 0
     156        };
     157        rc = DRVHostBaseScsiCmd(pThis, abCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, &cbRead, NULL, 0, 0);
     158
     159#else
    124160        /*
    125161         * Seek and read.
     
    143179            Log(("%s-%d: drvHostBaseRead: RTFileSeek(%d,%#llx,) -> %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName,
    144180                 pThis->pDrvIns->iInstance, pThis->FileDevice, off, rc));
     181#endif
    145182    }
    146183    else
     
    172209        if (pThis->fMediaPresent)
    173210        {
     211#ifdef __DARWIN__
     212            /** @todo write support... */
     213            rc = VERR_WRITE_PROTECT;
     214
     215#else
    174216            /*
    175217             * Seek and write.
     
    187229                Log(("%s-%d: drvHostBaseWrite: RTFileSeek(%d,%#llx,) -> %Vrc\n",
    188230                     pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->FileDevice, off, rc));
     231#endif
    189232        }
    190233        else
     
    211254    if (pThis->fMediaPresent)
    212255    {
     256#ifdef __DARWIN__
     257        rc = VINF_SUCCESS;
     258        /** @todo scsi device buffer flush... */
     259#else
    213260        rc = RTFileFlush(pThis->FileDevice);
     261#endif
    214262    }
    215263    else
     
    512560
    513561/**
    514  * Wrapper for open / RTFileOpen.
     562 * Wrapper for open / RTFileOpen / IOKit.
     563 *
     564 * @remark  The Darwin code must correspond exactly to the enumeration
     565 *          done in Main/darwin/iokit.c.
    515566 */
    516567static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileDevice, bool fReadOnly)
    517568{
    518 #ifdef __LINUX__
     569#ifdef __DARWIN__
     570    /* Darwin is kind of special... */
     571    Assert(!pFileDevice); NOREF(pFileDevice);
     572    Assert(!pThis->cbBlock);
     573    Assert(!pThis->MasterPort);
     574    Assert(!pThis->ppMMCDI);
     575    Assert(!pThis->ppScsiTaskDI);
     576
     577    /*
     578     * Open the master port on the first invocation.
     579     */
     580    kern_return_t krc = IOMasterPort(MACH_PORT_NULL, &pThis->MasterPort);
     581    AssertReturn(krc == KERN_SUCCESS, VERR_GENERAL_FAILURE);
     582
     583    /*
     584     * Create a matching dictionary for searching for DVD services in the IOKit.
     585     *
     586     * [If I understand this correctly, plain CDROMs doesn't show up as
     587     * IODVDServices. Too keep things simple, we will only support DVDs
     588     * until somebody complains about it and we get hardware to test it on.
     589     * (Unless I'm much mistaken, there aren't any (orignal) intel macs with
     590     * plain cdroms.)]
     591     */
     592    CFMutableDictionaryRef RefMatchingDict = IOServiceMatching("IODVDServices");
     593    AssertReturn(RefMatchingDict, NULL);
     594
     595    /*
     596     * do the search and get a collection of keyboards.
     597     */
     598    io_iterator_t DVDServices = NULL;
     599    IOReturn irc = IOServiceGetMatchingServices(pThis->MasterPort, RefMatchingDict, &DVDServices);
     600    AssertMsgReturn(irc == kIOReturnSuccess, ("irc=%d\n", irc), NULL);
     601    RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */
     602
     603    /*
     604     * Enumerate the DVD drives (services).
     605     * (This enumeration must be identical to the one performed in DrvHostBase.cpp.)
     606     */
     607    int rc = VERR_FILE_NOT_FOUND;
     608    unsigned i = 0;
     609    io_object_t DVDService;
     610    while ((DVDService = IOIteratorNext(DVDServices)) != 0)
     611    {
     612        /*
     613         * Get the properties we use to identify the DVD drive.
     614         *
     615         * While there is a (weird 12 byte) GUID, it isn't persistent
     616         * accross boots. So, we have to use a combination of the
     617         * vendor name and product name properties with an optional
     618         * sequence number for identification.
     619         */
     620        CFMutableDictionaryRef PropsRef = 0;
     621        kern_return_t krc = IORegistryEntryCreateCFProperties(DVDService, &PropsRef, kCFAllocatorDefault, kNilOptions);
     622        if (krc == KERN_SUCCESS)
     623        {
     624            /* Get the Device Characteristics dictionary. */
     625            CFDictionaryRef DevCharRef = (CFDictionaryRef)CFDictionaryGetValue(PropsRef, CFSTR(kIOPropertyDeviceCharacteristicsKey));
     626            if (DevCharRef)
     627            {
     628                /* The vendor name. */
     629                char szVendor[128];
     630                char *pszVendor = &szVendor[0];
     631                CFTypeRef ValueRef = CFDictionaryGetValue(DevCharRef, CFSTR(kIOPropertyVendorNameKey));
     632                if (    ValueRef
     633                    &&  CFGetTypeID(ValueRef) == CFStringGetTypeID()
     634                    &&  CFStringGetCString((CFStringRef)ValueRef, szVendor, sizeof(szVendor), kCFStringEncodingUTF8))
     635                    pszVendor = RTStrStrip(szVendor);
     636                else
     637                    *pszVendor = '\0';
     638
     639                /* The product name. */
     640                char szProduct[128];
     641                char *pszProduct = &szProduct[0];
     642                ValueRef = CFDictionaryGetValue(DevCharRef, CFSTR(kIOPropertyProductNameKey));
     643                if (    ValueRef
     644                    &&  CFGetTypeID(ValueRef) == CFStringGetTypeID()
     645                    &&  CFStringGetCString((CFStringRef)ValueRef, szProduct, sizeof(szProduct), kCFStringEncodingUTF8))
     646                    pszProduct = RTStrStrip(szProduct);
     647                else
     648                    *pszProduct = '\0';
     649
     650                /* Construct the two names and compare thwm with the one we're searching for. */
     651                char szName1[256 + 32];
     652                char szName2[256 + 32];
     653                if (*pszVendor || *pszProduct)
     654                {
     655                    if (*pszVendor && *pszProduct)
     656                    {
     657                        RTStrPrintf(szName1, sizeof(szName1), "%s %s", pszVendor, pszProduct);
     658                        RTStrPrintf(szName2, sizeof(szName2), "%s %s (#%u)", pszVendor, pszProduct, i);
     659                    }
     660                    else
     661                    {
     662                        strcpy(szName1, *pszVendor ? pszVendor : pszProduct);
     663                        RTStrPrintf(szName2, sizeof(szName2), "%s %s (#%u)", *pszVendor ? pszVendor : pszProduct, i);
     664                    }
     665                }
     666                else
     667                {
     668                    RTStrPrintf(szName1, sizeof(szName1), "(#%u)", i);
     669                    strcpy(szName2, szName1);
     670                }
     671
     672                if (    !strcmp(szName1, pThis->pszDeviceOpen)
     673                    ||  !strcmp(szName2, pThis->pszDeviceOpen))
     674                {
     675                    /*
     676                     * Found it! Now, get the client interface and stuff.
     677                     * Note that we could also query kIOSCSITaskDeviceUserClientTypeID here if the
     678                     * MMC client plugin is missing. For now we assume this won't be necessary.
     679                     */
     680                    SInt32 Score = 0;
     681                    IOCFPlugInInterface **ppPlugInInterface = NULL;
     682                    krc = IOCreatePlugInInterfaceForService(DVDService, kIOMMCDeviceUserClientTypeID, kIOCFPlugInInterfaceID,
     683                                                            &ppPlugInInterface, &Score);
     684                    if (krc == KERN_SUCCESS)
     685                    {
     686                        HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
     687                                                                           CFUUIDGetUUIDBytes(kIOMMCDeviceInterfaceID),
     688                                                                           (LPVOID *)&pThis->ppMMCDI);
     689                        (*ppPlugInInterface)->Release(ppPlugInInterface);
     690                        ppPlugInInterface = NULL;
     691                        if (hrc == S_OK)
     692                        {
     693                            pThis->ppScsiTaskDI = (*pThis->ppMMCDI)->GetSCSITaskDeviceInterface(pThis->ppMMCDI);
     694                            if (pThis->ppScsiTaskDI)
     695                                rc = VINF_SUCCESS;
     696                            else
     697                            {
     698                                LogRel(("GetSCSITaskDeviceInterface failed on '%s'\n", pThis->pszDeviceOpen));
     699                                rc = VERR_NOT_SUPPORTED;
     700                                (*pThis->ppMMCDI)->Release(pThis->ppMMCDI);
     701                            }
     702                        }
     703                        else
     704                        {
     705                            rc = VERR_GENERAL_FAILURE;//RTErrConvertFromDarwinCOM(krc);
     706                            pThis->ppMMCDI = NULL;
     707                        }
     708                    }
     709                    else /* Check for kIOSCSITaskDeviceUserClientTypeID? */
     710                        rc = VERR_GENERAL_FAILURE;//RTErrConvertFromDarwinKern(krc);
     711
     712                    /*
     713                     * Obtain exclusive access to the device
     714                     * (to prevent the host and/or user from interfering).
     715                     */
     716                    if (VBOX_SUCCESS(rc))
     717                    {
     718                        irc = (*pThis->ppScsiTaskDI)->ObtainExclusiveAccess(pThis->ppScsiTaskDI);
     719                        if (irc == kIOReturnSuccess)
     720                            rc = VINF_SUCCESS;
     721                        else if (irc == kIOReturnBusy)
     722                            rc = VERR_DRIVE_LOCKED;         /* mounted. */
     723                        else if (irc == kIOReturnExclusiveAccess)
     724                            rc = VERR_SHARING_VIOLATION;    /* already used exclusivly. */
     725                        else
     726                            rc = VERR_GENERAL_FAILURE;
     727                    }
     728
     729                    /* Cleanup on failure. */
     730                    if (VBOX_FAILURE(rc))
     731                    {
     732                        if (pThis->ppScsiTaskDI)
     733                        {
     734                            (*pThis->ppScsiTaskDI)->Release(pThis->ppScsiTaskDI);
     735                            pThis->ppScsiTaskDI = NULL;
     736                        }
     737                        if (pThis->ppMMCDI)
     738                        {
     739                            (*pThis->ppMMCDI)->Release(pThis->ppMMCDI);
     740                            pThis->ppMMCDI = NULL;
     741                        }
     742                    }
     743
     744                    IOObjectRelease(DVDService);
     745                    break;
     746                }
     747            }
     748            CFRelease(PropsRef);
     749        }
     750        else
     751            AssertMsgFailed(("krc=%#x\n", krc));
     752
     753        IOObjectRelease(DVDService);
     754        i++;
     755    }
     756
     757    IOObjectRelease(DVDServices);
     758    return rc;
     759
     760#elif defined(__LINUX__)
     761    /** @todo we've got RTFILE_O_NON_BLOCK now. Change the code to use RTFileOpen. */
    519762    int FileDevice = open(pThis->pszDeviceOpen, (pThis->fReadOnlyConfig ? O_RDONLY : O_RDWR) | O_NONBLOCK);
    520763    if (FileDevice < 0)
     
    522765    *pFileDevice = FileDevice;
    523766    return VINF_SUCCESS;
     767
    524768#else
    525769    return RTFileOpen(pFileDevice, pThis->pszDeviceOpen,
     
    528772}
    529773
     774
    530775/**
    531776 * (Re)opens the device.
     777 *
     778 * This is used to open the device during construction, but it's also used to re-open
     779 * the device when a media is inserted. This re-open will kill off any cached data
     780 * that Linux for some peculiar reason thinks should survive a media change...
    532781 *
    533782 * @returns VBOX status code.
     
    536785static int drvHostBaseReopen(PDRVHOSTBASE pThis)
    537786{
     787#ifndef __DARWIN__ /* Only *one* open for darwin. */
    538788    LogFlow(("%s-%d: drvHostBaseReopen: '%s'\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->pszDeviceOpen));
    539789
    540     /*
    541      * Reopen the device to kill any cached data which for some peculiar reason stays on some OSes (linux)...
    542      */
    543790    RTFILE FileDevice;
    544791    int rc = drvHostBaseOpen(pThis, &FileDevice, pThis->fReadOnlyConfig);
     
    564811        RTFileClose(pThis->FileDevice);
    565812    pThis->FileDevice = FileDevice;
     813#endif /* !__DARWIN__ */
    566814    return VINF_SUCCESS;
    567815}
     
    577825static int drvHostBaseGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
    578826{
    579 #ifdef __WIN__
     827#ifdef __DARWIN__
     828    /*
     829     * Try a READ_CAPACITY command...
     830     */
     831    struct
     832    {
     833        uint32_t cBlocks;
     834        uint32_t cbBlock;
     835    } Buf = {0, 0};
     836    size_t cbBuf = sizeof(Buf);
     837    uint8_t abCmd[16] =
     838    {
     839        SCSI_READ_CAPACITY, 0, 0, 0, 0, 0, 0,
     840        0,0,0,0,0,0,0,0,0
     841    };
     842    int rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_FROM_DEVICE, &Buf, &cbBuf, NULL, 0, 0);
     843    if (VBOX_SUCCESS(rc))
     844    {
     845        Assert(cbBuf == sizeof(Buf));
     846        Buf.cBlocks = RT_BE2H_U32(Buf.cBlocks);
     847        Buf.cbBlock = RT_BE2H_U32(Buf.cbBlock);
     848        //if (Buf.cbBlock > 2048) /* everyone else is doing this... check if it needed/right.*/
     849        //    Buf.cbBlock = 2048;
     850        pThis->cbBlock = Buf.cbBlock;
     851
     852        *pcb = (uint64_t)Buf.cBlocks * Buf.cbBlock;
     853    }
     854    return rc;
     855
     856#elif defined(__WIN__)
    580857    /* use NT api, retry a few times if the media is being verified. */
    581858    IO_STATUS_BLOCK             IoStatusBlock = {0};
     
    610887#endif
    611888}
     889
     890
     891#ifdef __DARWIN__
     892/**
     893 * Execute a SCSI command.
     894 *
     895 * @param pThis             The instance data.
     896 * @param pbCmd             Pointer to the SCSI command.
     897 * @param cbCmd             The size of the SCSI command.
     898 * @param enmTxDir          The transfer direction.
     899 * @param pvBuf             The buffer. Can be NULL if enmTxDir is PDMBLOCKTXDIR_NONE.
     900 * @param pcbBuf            Where to get the buffer size from and put the actual transfer size. Can be NULL.
     901 * @param pbSense           Where to put the sense data. Can be NULL.
     902 * @param cbSense           Size of the sense data buffer.
     903 * @param cTimeoutMillies   The timeout. 0 mean the default timeout.
     904 *
     905 * @returns VINF_SUCCESS on success (no sense code).
     906 * @returns VERR_UNRESOLVED_ERROR if sense code is present.
     907 * @returns Some other VBox status code on failures without sense code.
     908 *
     909 * @todo Fix VERR_UNRESOLVED_ERROR abuse.
     910 */
     911DECLCALLBACK(int) DRVHostBaseScsiCmd(PDRVHOSTBASE pThis, const uint8_t *pbCmd, size_t cbCmd, PDMBLOCKTXDIR enmTxDir,
     912                                     void *pvBuf, size_t *pcbBuf, uint8_t *pbSense, size_t cbSense, uint32_t cTimeoutMillies)
     913{
     914    /*
     915     * Minimal input validation.
     916     */
     917    Assert(enmTxDir == PDMBLOCKTXDIR_NONE || enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE || enmTxDir == PDMBLOCKTXDIR_TO_DEVICE);
     918    Assert(!pvBuf || (pcbBuf && *pcbBuf));
     919    Assert(pvBuf || enmTxDir == PDMBLOCKTXDIR_NONE);
     920    Assert(pbSense || !cbSense);
     921    AssertPtr(pbCmd);
     922    Assert(cbCmd <= 16 && cbCmd >= 1);
     923    const size_t cbBuf = pcbBuf ? *pcbBuf : 0;
     924    if (pcbBuf)
     925        *pcbBuf = 0;
     926
     927# ifdef __DARWIN__
     928    Assert(pThis->ppScsiTaskDI);
     929
     930    int rc = VERR_GENERAL_FAILURE;
     931    SCSITaskInterface **ppScsiTaskI = (*pThis->ppScsiTaskDI)->CreateSCSITask(pThis->ppScsiTaskDI);
     932    if (!ppScsiTaskI)
     933        return VERR_NO_MEMORY;
     934    do
     935    {
     936        /* Setup the scsi command. */
     937        SCSICommandDescriptorBlock cdb = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
     938        memcpy(&cdb[0], pbCmd, cbCmd);
     939        IOReturn irc = (*ppScsiTaskI)->SetCommandDescriptorBlock(ppScsiTaskI, cdb, cbCmd);
     940        AssertBreak(irc == kIOReturnSuccess,);
     941
     942        /* Setup the buffer. */
     943        if (enmTxDir == PDMBLOCKTXDIR_NONE)
     944            irc = (*ppScsiTaskI)->SetScatterGatherEntries(ppScsiTaskI, NULL, 0, 0, kSCSIDataTransfer_NoDataTransfer);
     945        else
     946        {
     947            IOVirtualRange Range = { (IOVirtualAddress)pvBuf, cbBuf };
     948            irc = (*ppScsiTaskI)->SetScatterGatherEntries(ppScsiTaskI, &Range, 1, cbBuf,
     949                                                          enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE
     950                                                          ? kSCSIDataTransfer_FromTargetToInitiator
     951                                                          : kSCSIDataTransfer_FromInitiatorToTarget);
     952        }
     953        AssertBreak(irc == kIOReturnSuccess,);
     954
     955        /* Set the timeout. */
     956        irc = (*ppScsiTaskI)->SetTimeoutDuration(ppScsiTaskI, cTimeoutMillies ? cTimeoutMillies : 30000 /*ms*/);
     957        AssertBreak(irc == kIOReturnSuccess,);
     958
     959        /* Execute the command and get the response. */
     960        SCSI_Sense_Data SenseData = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
     961        SCSIServiceResponse     ServiceResponse = kSCSIServiceResponse_Request_In_Process;
     962        SCSITaskStatus TaskStatus = kSCSITaskStatus_GOOD;
     963        UInt64 cbReturned = 0;
     964        irc = (*ppScsiTaskI)->ExecuteTaskSync(ppScsiTaskI, &SenseData, &TaskStatus, &cbReturned);
     965        AssertBreak(irc == kIOReturnSuccess,);
     966        if (pcbBuf)
     967            *pcbBuf = cbReturned;
     968
     969        irc = (*ppScsiTaskI)->GetSCSIServiceResponse(ppScsiTaskI, &ServiceResponse);
     970        AssertBreak(irc == kIOReturnSuccess,);
     971        AssertBreak(ServiceResponse == kSCSIServiceResponse_TASK_COMPLETE,);
     972
     973        if (TaskStatus == kSCSITaskStatus_GOOD)
     974            rc = VINF_SUCCESS;
     975        else if (   TaskStatus == kSCSITaskStatus_CHECK_CONDITION
     976                 && pbSense)
     977        {
     978            memset(pbSense, 0, cbSense); /* lazy */
     979            memcpy(pbSense, &SenseData, RT_MIN(sizeof(SenseData), cbSense));
     980            rc = VERR_UNRESOLVED_ERROR;
     981        }
     982        /** @todo convert sense codes when caller doesn't wish to do this himself. */
     983        /*else if (   TaskStatus == kSCSITaskStatus_CHECK_CONDITION
     984                 && SenseData.ADDITIONAL_SENSE_CODE == 0x3A)
     985            rc = VERR_MEDIA_NOT_PRESENT; */
     986        else
     987        {
     988            rc = enmTxDir == PDMBLOCKTXDIR_NONE
     989               ? VERR_DEV_IO_ERROR
     990               : enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE
     991               ? VERR_READ_ERROR
     992               : VERR_WRITE_ERROR;
     993            if (pThis->cLogRelErrors++ < 10)
     994                LogRel(("DVD scsi error: cmd={%.*Rhxs} TaskStatus=%#x key=%#x ASC=%#x ASCQ=%#x (%Vrc)\n",
     995                        cbCmd, pbCmd, TaskStatus, SenseData.SENSE_KEY, SenseData.ADDITIONAL_SENSE_CODE,
     996                        SenseData.ADDITIONAL_SENSE_CODE_QUALIFIER, rc));
     997        }
     998    } while (0);
     999
     1000    (*ppScsiTaskI)->Release(ppScsiTaskI);
     1001
     1002# endif
     1003
     1004    return rc;
     1005}
     1006#endif
    6121007
    6131008
     
    9071302     */
    9081303    if (    pThis->fLocked
     1304#ifdef __DARWIN__
     1305        &&  pThis->ppScsiTaskDI
     1306#else
    9091307        &&  pThis->FileDevice != NIL_RTFILE
     1308#endif
    9101309        &&  pThis->pfnDoLock)
    9111310    {
     
    9331332#endif
    9341333
     1334#ifdef __DARWIN__
     1335    if (pThis->ppScsiTaskDI)
     1336    {
     1337        (*pThis->ppScsiTaskDI)->ReleaseExclusiveAccess(pThis->ppScsiTaskDI);
     1338        (*pThis->ppScsiTaskDI)->Release(pThis->ppScsiTaskDI);
     1339        pThis->ppScsiTaskDI = NULL;
     1340    }
     1341    if (pThis->ppMMCDI)
     1342    {
     1343        (*pThis->ppMMCDI)->Release(pThis->ppMMCDI);
     1344        pThis->ppMMCDI = NULL;
     1345    }
     1346    if (pThis->MasterPort)
     1347    {
     1348        mach_port_deallocate(mach_task_self(), pThis->MasterPort);
     1349        pThis->MasterPort = NULL;
     1350    }
     1351#else
    9351352    if (pThis->FileDevice != NIL_RTFILE)
    9361353    {
     
    9391356        pThis->FileDevice = NIL_RTFILE;
    9401357    }
     1358#endif
    9411359
    9421360    if (pThis->pszDevice)
     
    9801398    pThis->pDrvIns                          = pDrvIns;
    9811399    pThis->ThreadPoller                     = NIL_RTTHREAD;
     1400#ifdef __DARWIN__
     1401    pThis->MasterPort                       = NULL;
     1402    pThis->ppMMCDI                          = NULL;
     1403    pThis->ppScsiTaskDI                     = NULL;
     1404    pThis->cbBlock                          = 0;
     1405#else
    9821406    pThis->FileDevice                       = NIL_RTFILE;
     1407#endif
    9831408    pThis->enmType                          = enmType;
     1409    //pThis->cErrors                          = 0;
    9841410
    9851411    pThis->pfnGetMediaSize                  = drvHostBaseGetMediaSize;
     
    11971623     * Open the device.
    11981624     */
     1625#ifdef __DARWIN__
     1626    rc = drvHostBaseOpen(pThis, NULL, pThis->fReadOnlyConfig);
     1627#else
    11991628    rc = drvHostBaseReopen(pThis);
     1629#endif
    12001630    if (VBOX_FAILURE(rc))
    12011631    {
    1202         char pszPathReal[256];
    12031632        char *pszDevice = pThis->pszDevice;
    1204         if (RT_SUCCESS(RTPathReal(pszDevice, pszPathReal, sizeof(pszPathReal))))
    1205             pszDevice = pszPathReal;
    1206         AssertMsgFailed(("Could not open host device %s, rc=%Vrc\n", pThis->pszDevice, rc));
     1633#ifndef __DARWIN__
     1634        char szPathReal[256];
     1635        if (RT_SUCCESS(RTPathReal(pszDevice, szPathReal, sizeof(szPathReal))))
     1636            pszDevice = szPathReal;
    12071637        pThis->FileDevice = NIL_RTFILE;
     1638#endif
     1639        AssertMsgFailed(("Could not open host device %s, rc=%Vrc\n", pszDevice, rc));
    12081640        switch (rc)
    12091641        {
     
    12191651                           "of that device"),
    12201652#endif
    1221                        pszPathReal, pThis->fReadOnlyConfig ? "readonly" : "read/write",
    1222                        pszPathReal);
     1653                       pszDevice, pThis->fReadOnlyConfig ? "readonly" : "read/write",
     1654                       pszDevice);
    12231655            default:
    12241656                return rc;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette