Ticket #45: host-cdflop.diff

File host-cdflop.diff, 28.5 KB (added by Valery V. Sedletski, 8 years ago)

host CD/floppy attach code

  • src/VBox/Devices/Storage/DrvHostBase.cpp

     
    9696        /*IN*/ ULONG                Length,
    9797        /*IN*/ FS_INFORMATION_CLASS FileSystemInformationClass );
    9898
     99#elif defined(RT_OS_OS2)
     100# define  OS2EMX_PLAIN_CHAR
     101# define  INCL_BASE
     102# define  INCL_DOSDEVIOCTL
     103# include <os2.h>
     104# define  IOCTL_CDROMDISK2         0x82
     105# define  CDROMDISK_WRITELONG      0x52
     106# define  CDROMDISK2_FEATURES      0x63
     107# define  FEATURE_EXECMD_SUPPORT   0x00000004L
    99108#elif defined(RT_OS_FREEBSD)
    100109# include <sys/cdefs.h>
    101110# include <sys/param.h>
     
    181190            pvBuf   = (uint8_t *)pvBuf + cbRead32;
    182191        } while ((cbRead > 0) && RT_SUCCESS(rc));
    183192
     193#elif defined(RT_OS_OS2)
     194        // parameter packet
     195        #pragma pack(1)
     196        struct ReadLong_param {
     197            ULONG       ID_code;                // 'CD01'
     198            UCHAR       address_mode;           // Addressing format of start_sector:
     199                                                //  00 - Logical Block format
     200                                                //  01 - Minutes/Seconds/Frame format
     201            USHORT      transfer_count;         // Numbers of sectors to read.
     202                                                //  Must  be non zero
     203            ULONG       start_sector;           // Starting sector number of the read operation
     204            UCHAR       reserved;               // Reserved. Must be 0
     205            UCHAR       interleave_size;        // Not used. Must be 0
     206            UCHAR       interleave_skip_factor; // Not used. Must be 0
     207        } parm;
     208        ULONG parmlen = sizeof(parm);
     209        #pragma pack()
     210
     211        #define SECTORSIZE      2048
     212
     213        // data packet
     214        struct ReadLong_data_CD {
     215            UCHAR        sync_pattern[12];
     216            UCHAR        msf[3];
     217            UCHAR        data_mode;
     218            UCHAR        data_area[SECTORSIZE];
     219            UCHAR        edc_ecc[288];
     220        } data_CD;
     221
     222        struct ReadLong_data_DVD {
     223            UCHAR        data_area[SECTORSIZE];
     224        } data_DVD;
     225
     226        char *data = NULL;
     227        ULONG datalen, data_offset;
     228        uint32_t cbRead32;
     229
     230        /* parameter packet */
     231        #pragma pack(1)
     232        struct PARM {
     233            unsigned char command;
     234            unsigned char drive;
     235        } parm2;
     236        #pragma pack()
     237        /* data packet      */
     238        BIOSPARAMETERBLOCK bpb;
     239        ULONG parmlen2 = sizeof(parm2);
     240        ULONG datalen2 = sizeof(bpb);
     241
     242        parm2.command = 1;
     243        parm2.drive = 0;
     244
     245        if ( (rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     246                               &parm2, parmlen2, &parmlen2, &bpb, datalen2, &datalen2)) )
     247            return RTErrConvertFromOS2(rc);
     248
     249        if (pThis->enmType == PDMBLOCKTYPE_CDROM || pThis->enmType == PDMBLOCKTYPE_DVD)
     250        {
     251            switch (bpb.bMedia & 0x7f)
     252            {
     253                // CD
     254                case 4:  // CD-R
     255                case 5:  // CD-ROM
     256                case 8:  // CD-RW
     257                case 12: // DDCD-ROM
     258                case 13: // DDCD-R
     259                case 14: // DDCD-RW
     260                    data = (char *)&data_CD;
     261                    datalen = sizeof(data_CD);
     262                    break;
     263                // DVD
     264                default:
     265                    data = (char *)&data_DVD;
     266                    datalen = sizeof(data_DVD);
     267            }
     268        }
     269
     270        #define BUFSIZE 0x4000
     271        #define SECSIZE 512
     272
     273        ULONG parmlen4 = sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * (bpb.usSectorsPerTrack - 1);
     274        char trkbuf[sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * 0xffff];
     275        PTRACKLAYOUT ptrk = (PTRACKLAYOUT)trkbuf;
     276        ULONG datalen4 = BUFSIZE;
     277        USHORT cyl, head, sec, n;
     278
     279        switch (pThis->enmType)
     280        {
     281            case PDMBLOCKTYPE_CDROM:
     282            case PDMBLOCKTYPE_DVD:
     283                AssertReturn(!(off % SECTORSIZE), VERR_INVALID_PARAMETER);
     284                cbRead32 = (cbRead > SECTORSIZE) ? SECTORSIZE : (uint32_t)cbRead;
     285                AssertReturn(!(cbRead % SECTORSIZE), VERR_INVALID_PARAMETER);
     286
     287                memset(&parm, 0, sizeof(parm));
     288                parm.ID_code = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     289                parm.address_mode = 0; // lba
     290
     291                do
     292                {
     293                    parm.transfer_count = 1;
     294                    parm.start_sector = (ULONG)(off / SECTORSIZE);
     295
     296                    rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice), IOCTL_CDROMDISK, CDROMDISK_READLONG,
     297                                     &parm, parmlen, &parmlen, data, datalen, &datalen);
     298
     299                    rc = RTErrConvertFromOS2(rc);
     300
     301                    if (RT_SUCCESS(rc))
     302                    {
     303                        switch (bpb.bMedia & 0x7f)
     304                        {
     305                            // CD
     306                            case 4:  // CD-R
     307                            case 5:  // CD-ROM
     308                            case 8:  // CD-RW
     309                            case 12: // DDCD-ROM
     310                            case 13: // DDCD-R
     311                            case 14: // DDCD-RW
     312                                switch (data_CD.data_mode)
     313                                {
     314                                    case 0:
     315                                        // Mode 0
     316                                        data_offset = 16;
     317                                        break;
     318                                    case 1:
     319                                        // Mode 1
     320                                        data_offset = 16;
     321                                        break;
     322                                    case 2:
     323                                        // Mode 2
     324                                        data_offset = 24;
     325                                        break;
     326                                    default:
     327                                        data_offset = 16;
     328                                }
     329                                break;
     330
     331                            // DVD
     332                            default:
     333                                data_offset = 0;
     334                        }
     335                        memcpy((char *)pvBuf, data + data_offset, cbRead32);
     336                    }
     337
     338                    off    += cbRead32;
     339                    cbRead -= cbRead32;
     340                    pvBuf   = (uint8_t *)pvBuf + cbRead32;
     341
     342                } while ((cbRead > 0) && RT_SUCCESS(rc));
     343                break;
     344
     345            case PDMBLOCKTYPE_FLOPPY_360:
     346            case PDMBLOCKTYPE_FLOPPY_720:
     347            case PDMBLOCKTYPE_FLOPPY_1_20:
     348            case PDMBLOCKTYPE_FLOPPY_1_44:
     349            case PDMBLOCKTYPE_FLOPPY_2_88:
     350            case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:
     351            case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:
     352            case PDMBLOCKTYPE_HARD_DISK:
     353                cbRead32 = (cbRead > BUFSIZE) ? BUFSIZE : (uint32_t)cbRead;
     354
     355                memset((char *)trkbuf, 0, sizeof(trkbuf));
     356
     357                do
     358                {
     359                    cyl = off / (SECSIZE * bpb.cHeads * bpb.usSectorsPerTrack);
     360                    head = (off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl) / bpb.usSectorsPerTrack;
     361                    sec = off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl - head * bpb.usSectorsPerTrack;
     362
     363                    if (sec + cbRead32 / SECSIZE > bpb.usSectorsPerTrack)
     364                        n = bpb.usSectorsPerTrack - sec + 1;
     365                    else
     366                        n = cbRead32 / SECSIZE;
     367
     368                    ptrk->bCommand = 1;
     369                    ptrk->usHead = head;
     370                    ptrk->usCylinder = cyl;
     371                    ptrk->usFirstSector = sec;
     372                    ptrk->cSectors = n;
     373
     374                    for (int i = 0; i < bpb.usSectorsPerTrack; i++)
     375                    {
     376                        ptrk->TrackTable[i].usSectorNumber = i + 1;
     377                        ptrk->TrackTable[i].usSectorSize = SECSIZE;
     378                    }
     379
     380                    rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice), IOCTL_DISK, DSK_READTRACK,
     381                                     trkbuf, parmlen4, &parmlen4, pvBuf, datalen4, &datalen4);
     382
     383                    rc = RTErrConvertFromOS2(rc);
     384
     385                    off    += cbRead32;
     386                    cbRead -= cbRead32;
     387                    pvBuf   = (uint8_t *)pvBuf + cbRead32;
     388
     389                } while ((cbRead > 0) && RT_SUCCESS(rc));
     390                break;
     391
     392            default:
     393                rc = VERR_NOT_SUPPORTED;
     394        }
     395
    184396#else
    185397        /*
    186398         * Seek and read.
     
    230442            /** @todo write support... */
    231443            rc = VERR_WRITE_PROTECT;
    232444
     445#elif defined(RT_OS_OS2)
     446        // parameter packet
     447        #pragma pack(1)
     448        struct WriteLong_param {
     449            ULONG       ID_code;                // 'CD01'
     450            UCHAR       address_mode;           // Addressing format of start_sector:
     451                                                //  00 - Logical Block format
     452                                                //  01 - Minutes/Seconds/Frame format
     453            USHORT      transfer_count;         // Numbers of sectors to read.
     454                                                //  Must  be non zero
     455            ULONG       start_sector;           // Starting sector number of the read operation
     456            UCHAR       reserved;               // Reserved. Must be 0
     457            UCHAR       interleave_size;        // Not used. Must be 0
     458            UCHAR       interleave_skip_factor; // Not used. Must be 0
     459        } parm;
     460        ULONG parmlen = sizeof(parm);
     461        #pragma pack()
     462
     463        #define SECTORSIZE      2048
     464
     465        // data packet
     466        struct WriteLong_data {
     467            UCHAR       sector_data[2048]; // Sector to be written to the disk
     468        } data;
     469
     470        ULONG datalen, data_offset;
     471        uint32_t cbWrite32;
     472
     473        datalen = sizeof(data);
     474
     475        /* parameter packet */
     476        #pragma pack(1)
     477        struct PARM {
     478            unsigned char command;
     479            unsigned char drive;
     480        } parm2;
     481        #pragma pack()
     482        /* data packet      */
     483        BIOSPARAMETERBLOCK bpb;
     484        ULONG parmlen2 = sizeof(parm2);
     485        ULONG datalen2 = sizeof(bpb);
     486
     487        parm2.command = 1;
     488        parm2.drive = 0;
     489
     490        if ( (rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     491                               &parm2, parmlen2, &parmlen2, &bpb, datalen2, &datalen2)) )
     492            return RTErrConvertFromOS2(rc);
     493
     494        #define BUFSIZE 0x4000
     495        #define SECSIZE 512
     496
     497        ULONG parmlen4 = sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * (bpb.usSectorsPerTrack - 1);
     498        char trkbuf[sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * 0xffff];
     499        PTRACKLAYOUT ptrk = (PTRACKLAYOUT)trkbuf;
     500        ULONG datalen4 = BUFSIZE;
     501        USHORT cyl, head, sec, n;
     502
     503        switch (pThis->enmType)
     504        {
     505            case PDMBLOCKTYPE_CDROM:
     506            case PDMBLOCKTYPE_DVD:
     507                AssertReturn(!(off % SECTORSIZE), VERR_INVALID_PARAMETER);
     508                cbWrite32 = (cbWrite > SECTORSIZE) ? SECTORSIZE : (uint32_t)cbWrite;
     509                AssertReturn(!(cbWrite % SECTORSIZE), VERR_INVALID_PARAMETER);
     510
     511                memset(&parm, 0, sizeof(parm));
     512                parm.ID_code = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     513                parm.address_mode = 0; // lba
     514
     515                do
     516                {
     517                    parm.transfer_count = 1;
     518                    parm.start_sector = (ULONG)(off / SECTORSIZE);
     519
     520                    rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice), IOCTL_CDROMDISK, CDROMDISK_WRITELONG,
     521                                     &parm, parmlen, &parmlen, &data, datalen, &datalen);
     522
     523                    rc = RTErrConvertFromOS2(rc);
     524
     525                    if (RT_SUCCESS(rc))
     526                        memcpy((char *)pvBuf, &data, cbWrite32);
     527
     528                    off += cbWrite32;
     529                    cbWrite -= cbWrite32;
     530                    pvBuf = (uint8_t *)pvBuf + cbWrite32;
     531
     532                } while ((cbWrite > 0) && RT_SUCCESS(rc));
     533                break;
     534
     535            case PDMBLOCKTYPE_FLOPPY_360:
     536            case PDMBLOCKTYPE_FLOPPY_720:
     537            case PDMBLOCKTYPE_FLOPPY_1_20:
     538            case PDMBLOCKTYPE_FLOPPY_1_44:
     539            case PDMBLOCKTYPE_FLOPPY_2_88:
     540            case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:
     541            case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:
     542            case PDMBLOCKTYPE_HARD_DISK:
     543                cbWrite32 = (cbWrite > BUFSIZE) ? BUFSIZE : (uint32_t)cbWrite;
     544
     545                memset((char *)trkbuf, 0, sizeof(trkbuf));
     546
     547                do
     548                {
     549                    cyl = off / (SECSIZE * bpb.cHeads * bpb.usSectorsPerTrack);
     550                    head = (off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl) / bpb.usSectorsPerTrack;
     551                    sec = off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl - head * bpb.usSectorsPerTrack;
     552
     553                    if (sec + cbWrite32 / SECSIZE > bpb.usSectorsPerTrack)
     554                        n = bpb.usSectorsPerTrack - sec + 1;
     555                    else
     556                        n = cbWrite32 / SECSIZE;
     557
     558                    ptrk->bCommand = 1;
     559                    ptrk->usHead = head;
     560                    ptrk->usCylinder = cyl;
     561                    ptrk->usFirstSector = sec;
     562                    ptrk->cSectors = n;
     563
     564                    for (int i = 0; i < bpb.usSectorsPerTrack; i++)
     565                    {
     566                        ptrk->TrackTable[i].usSectorNumber = i + 1;
     567                        ptrk->TrackTable[i].usSectorSize = SECSIZE;
     568                    }
     569
     570                    rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice), IOCTL_DISK, DSK_WRITETRACK,
     571                                     trkbuf, parmlen4, &parmlen4, (void *)pvBuf, datalen4, &datalen4);
     572
     573                    rc = RTErrConvertFromOS2(rc);
     574
     575                    off    += cbWrite32;
     576                    cbWrite -= cbWrite32;
     577                    pvBuf   = (uint8_t *)pvBuf + cbWrite32;
     578
     579                } while ((cbWrite > 0) && RT_SUCCESS(rc));
     580                break;
     581
     582            default:
     583                rc = VERR_NOT_SUPPORTED;
     584        }
     585
    233586#else
    234587            /*
    235588             * Seek and write.
     
    10591412    RTFileClose(hFileDevice);
    10601413    return rc;
    10611414
     1415#elif defined(RT_OS_OS2)
     1416    APIRET rc;
     1417    ULONG  sig, feat, cmd = 0;
     1418    ULONG  parmlen = sizeof(sig);
     1419    ULONG  datalen = sizeof(sig);
     1420    ULONG  ulAction;
     1421    HFILE  hDisk = NULLHANDLE;
     1422
     1423    if (! (rc = DosOpen(pThis->pszDeviceOpen, &hDisk,
     1424                        &ulAction, 0, FILE_NORMAL,
     1425                        OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
     1426                        OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE |
     1427                        OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, NULL)) )
     1428    {
     1429        if (! hDisk)
     1430            return VERR_MEDIA_NOT_PRESENT;
     1431
     1432        if (pThis->enmType == PDMBLOCKTYPE_CDROM || pThis->enmType == PDMBLOCKTYPE_DVD)
     1433        {
     1434            // identify CDROM driver
     1435            sig = ('C') | ('D' << 8) | ('9' << 16) | ('9' << 24);
     1436
     1437            if ( (rc = DosDevIOCtl(hDisk, IOCTL_CDROMDISK, CDROMDISK_GETDRIVER,
     1438                                   &sig, sizeof(sig), NULL,
     1439                                   &sig, sizeof(sig), NULL)) ||
     1440                  sig != (('C') | ('D' << 8) | ('0' << 16) | ('1' << 24)) )
     1441                return VERR_MEDIA_NOT_PRESENT;
     1442        }
     1443    }
     1444    else
     1445        return RTErrConvertFromOS2(rc);
     1446
     1447    RTFileFromNative(pFileDevice, hDisk);
     1448
     1449    return VINF_SUCCESS;
    10621450#else
    10631451    uint32_t fFlags = (fReadOnly ? RTFILE_O_READ : RTFILE_O_READWRITE) | RTFILE_O_OPEN | RTFILE_O_DENY_NONE;
    10641452# ifdef RT_OS_LINUX
     
    11281516    }
    11291517    RTFILE hFileRawDevice;
    11301518    int rc = drvHostBaseOpen(pThis, &hFileDevice, &hFileRawDevice, pThis->fReadOnlyConfig);
     1519#elif defined(RT_OS_OS2)
     1520    if (pThis->hFileDevice != NIL_RTFILE)
     1521    {
     1522        RTFileClose(pThis->hFileDevice);
     1523        pThis->hFileDevice = NIL_RTFILE;
     1524    }
     1525    int rc = drvHostBaseOpen(pThis, &hFileDevice, pThis->fReadOnlyConfig);
    11311526#else
    11321527    int rc = drvHostBaseOpen(pThis, &hFileDevice, pThis->fReadOnlyConfig);
    11331528#endif
     
    12481643    }
    12491644    LogFlow(("drvHostBaseGetMediaSize: NtQueryVolumeInformationFile -> %#lx\n", rcNt, rc));
    12501645    return rc;
     1646#elif defined(RT_OS_OS2)
     1647    ULONG parm = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     1648    ULONG parmlen = sizeof(parm);
     1649    ULONG data = 0;
     1650    ULONG datalen = sizeof(data);
     1651    APIRET rc;
     1652
     1653    /* parameter packet */
     1654    #pragma pack(1)
     1655    struct PARM {
     1656        unsigned char command;
     1657        unsigned char drive;
     1658    } parm2;
     1659    #pragma pack()
     1660    /* data packet      */
     1661    BIOSPARAMETERBLOCK bpb;
     1662    ULONG cbSectors;
     1663    ULONG parmlen2 = sizeof(parm2);
     1664    ULONG datalen2 = sizeof(bpb);
     1665
     1666    switch (pThis->enmType)
     1667    {
     1668        case PDMBLOCKTYPE_DVD:
     1669        case PDMBLOCKTYPE_CDROM:
     1670            if ( (rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice),
     1671                                   IOCTL_CDROMDISK, CDROMDISK_DEVICESTATUS,
     1672                                   &parm, parmlen, &parmlen,
     1673                                   &data, datalen, &datalen)) )
     1674                return RTErrConvertFromOS2(rc);
     1675
     1676            if (data & (1 << 11))
     1677                // disk does not present
     1678                return VERR_MEDIA_NOT_PRESENT;
     1679
     1680            parm = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     1681
     1682            if ( (rc = DosDevIOCtl(RTFileToNative(pThis->hFileDevice),
     1683                                   IOCTL_CDROMDISK, CDROMDISK_GETVOLUMESIZE,
     1684                                   &parm, parmlen, &parmlen,
     1685                                   &data, datalen, &datalen)) )
     1686                return RTErrConvertFromOS2(rc);
     1687
     1688            // return disk size in bytes
     1689            *pcb = data * 2048;
     1690            return VINF_SUCCESS;
     1691
     1692        case PDMBLOCKTYPE_FLOPPY_360:
     1693        case PDMBLOCKTYPE_FLOPPY_720:
     1694        case PDMBLOCKTYPE_FLOPPY_1_20:
     1695        case PDMBLOCKTYPE_FLOPPY_1_44:
     1696        case PDMBLOCKTYPE_FLOPPY_2_88:
     1697        case PDMBLOCKTYPE_FLOPPY_FAKE_15_6:
     1698        case PDMBLOCKTYPE_FLOPPY_FAKE_63_5:
     1699        case PDMBLOCKTYPE_HARD_DISK:
     1700            parm2.command = 1; // Return the BPB for the media currently in the drive
     1701            parm2.drive = 0;   // unused
     1702
     1703            memset(&bpb, 0, sizeof(bpb));
     1704
     1705            rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     1706                             &parm2, parmlen2, &parmlen2,
     1707                             &bpb, datalen2, &datalen2);
     1708
     1709            if (! rc) {
     1710                cbSectors = bpb.cCylinders * bpb.cHeads * bpb.usSectorsPerTrack;
     1711                *pcb = cbSectors * bpb.usBytesPerSector;
     1712                rc = VINF_SUCCESS;
     1713            }
     1714            else
     1715            {
     1716                rc = RTErrConvertFromOS2(rc);
     1717                Log(("DrvHostBaseGetMediaSize: ioctl DSK_GETDEVICEPARAMS(%s) failed, rc=%Rrc\n",
     1718                     pThis->pszDevice, rc));
     1719                return rc;
     1720            }
     1721            return rc;
     1722
     1723        default:
     1724            return VERR_NOT_SUPPORTED;
     1725    }
    12511726#else
    12521727    return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
    12531728#endif
     
    20412516    pThis->fAttachFailError = fAttachFailError;
    20422517
    20432518    /* name to open & watch for */
    2044 #ifdef RT_OS_WINDOWS
     2519#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    20452520    int iBit = RT_C_TO_UPPER(pThis->pszDevice[0]) - 'A';
    20462521    if (    iBit > 'Z' - 'A'
    20472522        ||  pThis->pszDevice[1] != ':'
     
    20512526        return VERR_INVALID_PARAMETER;
    20522527    }
    20532528    pThis->fUnitMask = 1 << iBit;
     2529#if defined(RT_OS_WINDOWS)
    20542530    RTStrAPrintf(&pThis->pszDeviceOpen, "\\\\.\\%s", pThis->pszDevice);
     2531#else
     2532    RTStrAPrintf(&pThis->pszDeviceOpen, "%s", pThis->pszDevice);
     2533#endif
    20552534
    20562535#elif defined(RT_OS_SOLARIS)
    20572536    char *pszBlockDevName = getfullblkname(pThis->pszDevice);
     
    21992678            }
    22002679        }
    22012680    }
    2202 #ifdef RT_OS_WINDOWS
     2681#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    22032682    if (RT_SUCCESS(src))
    22042683        DRVHostBaseMediaPresent(pThis);
    22052684#endif
  • src/VBox/Devices/Storage/DrvHostDVD.cpp

     
    8686# undef _interlockedbittestandreset64
    8787# undef USE_MEDIA_POLLING
    8888
     89#elif defined(RT_OS_OS2)
     90# define  INCL_BASE
     91# define  INCL_DOSDEVICES
     92# define  INCL_DOSDEVIOCTL
     93# include <os2.h>
     94
    8995#elif defined(RT_OS_FREEBSD)
    9096# include <sys/cdefs.h>
    9197# include <sys/param.h>
     
    106112#include <iprt/string.h>
    107113#include <iprt/thread.h>
    108114#include <iprt/critsect.h>
     115#include <iprt/mem.h>
    109116#include <VBox/scsi.h>
    110117
    111118#include "VBoxDD.h"
     
    202209                AssertMsgFailed(("Failed to open '%s' for ejecting this tray.\n",  rc));
    203210
    204211
     212#elif defined(RT_OS_OS2)
     213            ULONG parm = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     214            ULONG parmlen = sizeof(parm);
     215
     216            if (! (rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice),
     217                               IOCTL_CDROMDISK, CDROMDISK_EJECTDISK,
     218                               &parm, parmlen, &parmlen,
     219                               NULL, 0, NULL)))
     220                rc = VINF_SUCCESS;
     221            else
     222                rc = RTErrConvertFromOS2(rc);
    205223#else
    206224            AssertMsgFailed(("Eject is not implemented!\n"));
    207225            rc = VINF_SUCCESS;
     
    280298        /** @todo figure out the return codes for already locked. */
    281299        rc = RTErrConvertFromWin32(GetLastError());
    282300
     301#elif defined(RT_OS_OS2)
     302    #pragma pack(1)
     303    typedef struct _PARM
     304    {
     305        ULONG sig;
     306        char flag;
     307    } PARM;
     308    #pragma pack()
     309
     310    ULONG  parmlen, datalen = 0;
     311    PARM   parm;
     312    APIRET rc;
     313
     314    parm.sig = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     315    parm.flag = fLock ? 1 : 0;
     316
     317    if (! (rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice), IOCTL_CDROMDISK, CDROMDISK_LOCKUNLOCKDOOR,
     318                            &parm, sizeof(PARM), &parmlen,
     319                            0, datalen, &datalen)))
     320        rc = VINF_SUCCESS;
     321    else
     322        rc = RTErrConvertFromOS2(rc);
    283323#else
    284324    AssertMsgFailed(("Lock/Unlock is not implemented!\n"));
    285325    int rc = VINF_SUCCESS;
     
    631671        rc = RTErrConvertFromWin32(GetLastError());
    632672    Log2(("%s: scsistatus=%d bytes returned=%d tlength=%d\n", __FUNCTION__, Req.spt.ScsiStatus, cbReturned, Req.spt.DataTransferLength));
    633673
     674#elif defined(RT_OS_OS2)
     675    #define CDROMDISK_EXECMD  0x7A
     676    int flags;
     677
     678    struct ExecCMD {
     679       ULONG        ID_code;          // 'CD01'
     680       USHORT       data_length;      // length of the Data Packet
     681       USHORT       cmd_length;       // length of the Command Buffer
     682       USHORT       flags;            // flags
     683       UCHAR        cmd_buffer[16];   // Command Buffer for SCSI command
     684       ULONG        cmd_timeout;      // Timeout for executing command (0 - default)
     685    } cmd;
     686    // flags:
     687    #define EX_DIRECTION_IN  0x0001
     688    #define EX_PLAYING_CHK   0x0002
     689    #define EX_RETURN_STATUS 0x0004
     690    #define EX_SET_TIMEOUT   0x0008
     691
     692    struct RetStatus {
     693        UCHAR       sense_key;    // Sense Key
     694        UCHAR       asc_code;     // Additional Sense Code (ASC)
     695        UCHAR       ascq_code;    // Additional Sense Code Qualifier (ASCQ)
     696    };
     697
     698    ULONG cmdlen = sizeof(cmd);
     699    ULONG datalen;
     700    char  *data;
     701
     702    switch (enmTxDir)
     703    {
     704        case PDMBLOCKTXDIR_NONE:
     705            Assert(*pcbBuf == 0);
     706            flags = 0;
     707            break;
     708        case PDMBLOCKTXDIR_FROM_DEVICE:
     709            Assert(*pcbBuf != 0);
     710            /* Make sure that the buffer is clear for commands reading
     711             * data. The actually received data may be shorter than what
     712             * we expect, and due to the unreliable feedback about how much
     713             * data the ioctl actually transferred, it's impossible to
     714             * prevent that. Returning previous buffer contents may cause
     715             * security problems inside the guest OS, if users can issue
     716             * commands to the CDROM device. */
     717            memset(pvBuf, 0, *pcbBuf);
     718            flags = EX_DIRECTION_IN;
     719            break;
     720        case PDMBLOCKTXDIR_TO_DEVICE:
     721            Assert(*pcbBuf != 0);
     722            flags = 0;
     723            break;
     724        default:
     725            AssertMsgFailed(("enmTxDir invalid!\n"));
     726            flags = 0;
     727    }
     728    flags |= EX_SET_TIMEOUT | EX_RETURN_STATUS;
     729    memset(&cmd, 0, sizeof(cmd));
     730    cmd.ID_code = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     731    cmd.cmd_length = sizeof(cmd.cmd_buffer);
     732    memcpy((char *)cmd.cmd_buffer, (char *)pbCmd, 12);
     733    cmd.flags = flags;
     734    cmd.cmd_timeout = cTimeoutMillies;
     735    cmd.data_length = *pcbBuf + cbSense;
     736    data = (char *)RTMemAllocZ(cmd.data_length);
     737    datalen = cmd.data_length;
     738    memcpy(data, pvBuf, *pcbBuf);
     739
     740    if (! (rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice),
     741                    IOCTL_CDROMDISK, CDROMDISK_EXECMD,
     742                    &cmd, cmdlen, &cmdlen, data, datalen, &datalen)) )
     743    {
     744        if (datalen > cmd.data_length)
     745            memcpy(pabSense, (char *)pvBuf + *pcbBuf, cbSense);
     746        else
     747            memset(pabSense, 0, cbSense);
     748 
     749        memcpy(pvBuf, data, *pcbBuf);
     750        RTMemFree(data);
     751    }
     752    else
     753        rc = RTErrConvertFromOS2(rc);
     754
     755    Log2(("%s: bytes returned=%d\n", __FUNCTION__, *pcbBuf));
     756   
    634757#else
    635758# error "Unsupported platform."
    636759#endif
  • src/VBox/Devices/Storage/DrvHostFloppy.cpp

     
    2828# include <sys/fcntl.h>
    2929# include <errno.h>
    3030
    31 # elif defined(RT_OS_WINDOWS)
     31#elif defined(RT_OS_WINDOWS)
    3232# include <windows.h>
    3333# include <dbt.h>
    3434
     35#elif defined(RT_OS_OS2)
     36# define  INCL_BASE
     37# define  INCL_DOSDEVIOCTL
     38# include <os2.h>
    3539#elif defined(RT_OS_L4)
    3640
    3741#else /* !RT_OS_WINDOWS nor RT_OS_LINUX nor RT_OS_L4 */
     
    101105}
    102106#endif /* RT_OS_WINDOWS */
    103107
     108#ifdef RT_OS_OS2
     109
     110/* parameter packet */
     111#pragma pack(1)
     112struct PARM {
     113    unsigned char command;
     114    unsigned char drive;
     115};
     116#pragma pack()
     117
     118/**
     119 * Get media size - needs a special IOCTL.
     120 *
     121 * @param   pThis   The instance data.
     122 */
     123static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
     124{
     125    struct PARM parm;
     126    BIOSPARAMETERBLOCK bpb;
     127    ULONG cbSectors;
     128    ULONG parmlen = sizeof(parm);
     129    ULONG datalen = sizeof(bpb);
     130    APIRET rc;
     131
     132    parm.command = 1; // Return the BPB for the media currently in the drive
     133    parm.drive = 0;   // unused
     134
     135    memset(&bpb, 0, sizeof(bpb));
     136
     137    rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     138                     &parm, parmlen, &parmlen,
     139                     &bpb, datalen, &datalen);
     140
     141    if (! rc) {
     142        cbSectors = bpb.cCylinders * bpb.cHeads * bpb.usSectorsPerTrack;
     143        *pcb = cbSectors * bpb.usBytesPerSector;
     144        rc = VINF_SUCCESS;
     145    }
     146    else
     147    {
     148        rc = RTErrConvertFromOS2(rc);
     149        Log(("DrvHostFloppy: ioctl DSK_GETDEVICEPARAMS(%s) failed, rc=%Rrc\n",
     150             pThis->pszDevice, rc));
     151        return rc;
     152    }
     153
     154    return rc;
     155}
     156#endif /* RT_OS_OS2 */
     157
    104158#ifdef RT_OS_LINUX
    105159/**
    106160 * Get media size and do change processing.
     
    198252            /*
    199253             * Override stuff.
    200254             */
    201 #ifdef RT_OS_WINDOWS
     255#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    202256            pThis->Base.pfnGetMediaSize = drvHostFloppyGetMediaSize;
    203257#endif
    204258#ifdef RT_OS_LINUX
  • src/VBox/Devices/Storage/DrvHostBase.h

     
    129129    /** The unit mask. */
    130130    DWORD                   fUnitMask;
    131131#endif
     132#ifdef RT_OS_OS2
     133    /** The unit mask. */
     134    ULONG                   fUnitMask;
     135#endif
    132136
    133137#ifdef RT_OS_LINUX
    134138    /** Double buffer required for ioctl with the Linux kernel as long as we use