Ticket #45: host-cdflop-upd.diff

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

Added forgotten VBoxManage changes

  • include/iprt/file.h

     
    4747# define RTFILE_LINEFEED    "\n"
    4848#endif
    4949
     50#ifdef RT_OS_OS2
     51/* internal file handle structure     */
     52#pragma pack (1)
     53struct RTFILEINT
     54{
     55    uint32_t hFile;   /* native file handle            */
     56    uint8_t type;     /* file handle type (see below)  */
     57    uint8_t rawfs;    /* use RAW FS (UNC pathnames)    */
     58    uint64_t off;     /* seek offset                   */
     59};
     60#pragma pack ()
     61/* normal file handle */
     62# define FILE_TYPE_NORMAL 0
     63/* volume open with flag OPEN_FLAGS_DASD   */
     64# define FILE_TYPE_DASD   1
     65/* cdrom file handle, cdrom ioctl          */
     66# define FILE_TYPE_CD     2
     67/* phys disk open using phys disk ioctl    */
     68# define FILE_TYPE_RAW    3
     69#endif
     70
    5071/** Platform specific native standard input "handle". */
    5172#ifdef RT_OS_WINDOWS
    5273# define RTFILE_NATIVE_STDIN ((uint32_t)-10)
  • src/VBox/Runtime/r3/posix/fileio-posix.cpp

     
    4545#ifdef RT_OS_LINUX
    4646# include <sys/file.h>
    4747#endif
    48 #if defined(RT_OS_OS2) && (!defined(__INNOTEK_LIBC__) || __INNOTEK_LIBC__ < 0x006)
    49 # include <io.h>
     48
     49#if defined(RT_OS_OS2)
     50# define  OS2EMX_PLAIN_CHAR
     51# define  INCL_BASE
     52# define  INCL_DOSDEVIOCTL
     53# include <os2.h>
     54# include <stdio.h>
     55# define  IOCTL_CDROMDISK2         0x82
     56# define  CDROMDISK_READDATA       0x76
     57# define  CDROMDISK_WRITEDATA      0x56
     58# define  CDROMDISK2_FEATURES      0x63
     59# define  CDROMDISK2_DRIVELETTERS  0x60
     60# define  FEATURE_EXECMD_SUPPORT   0x00000004L
     61# include <ctype.h> // for tolower
     62# if (!defined(__INNOTEK_LIBC__) || __INNOTEK_LIBC__ < 0x006)
     63#  include <io.h>
     64# endif
    5065#endif
    5166#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
    5267# include <sys/disk.h>
     
    6176#include <iprt/path.h>
    6277#include <iprt/assert.h>
    6378#include <iprt/string.h>
     79#include <iprt/mem.h>
    6480#include <iprt/err.h>
    6581#include <iprt/log.h>
    6682#include "internal/file.h"
     
    98114    return fRc;
    99115}
    100116
     117#ifdef RT_OS_OS2
     118// check if the driveletter is cdrom one
     119static bool rtOs2IsCdRom(const char *pszFilename)
     120{
     121    typedef struct _CDROMDeviceMap
     122    {
     123        USHORT usDriveCount;
     124        USHORT usFirstLetter;
     125    } CDROMDeviceMap;
    101126
     127    HFILE hf;
     128    ULONG ulAction = 0;
     129    CDROMDeviceMap CDMap;
     130    ULONG ulParamSize = sizeof(ulAction);
     131    ULONG ulDataSize = sizeof(CDROMDeviceMap);
     132    char driveName[3] = { '?', ':', '\0' };
     133
     134    if (DosOpen("\\DEV\\CD-ROM2$", &hf, &ulAction, 0, FILE_NORMAL,
     135                OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
     136                OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL))
     137        return false;
     138
     139    DosDevIOCtl(hf, IOCTL_CDROMDISK2, CDROMDISK2_DRIVELETTERS,
     140                NULL, 0, &ulParamSize,
     141                (PVOID)&CDMap, sizeof(CDROMDeviceMap), &ulDataSize);
     142    DosClose(hf);
     143
     144    for (int drv = CDMap.usFirstLetter; drv < CDMap.usFirstLetter + CDMap.usDriveCount; drv++)
     145    {
     146        driveName[0] = 'A' + drv;
     147        if (!stricmp(driveName, pszFilename))
     148            return true;
     149    }
     150
     151    return false;
     152}
     153
     154static int rtOs2ExtraFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen, int fOpenMode, int fMode)
     155{
     156    int    fh;
     157    APIRET rc;
     158    ULONG  dummy;
     159
     160    errno = 0;
     161    (*pFile)->rawfs = 0;
     162
     163    // in case someone appended the default
     164    // path to a drive letter, truncate path
     165    // (otherwise we'll get n:\dir\w: or n:/dir/w:)
     166    // and it will trap trying to open it
     167    int len = strlen(pszFilename);
     168
     169    // access via the raw filesystem
     170    if ( !strncmp(pszFilename, "\\\\.\\", 4) )
     171        //(*pFile)->type = FILE_TYPE_RAWFS;
     172        (*pFile)->rawfs = 1;
     173    // handle d:\path\to\w: or d:\path\to/w: case (truncate path)
     174    else if (len >= 3 &&
     175        pszFilename[len - 1] == ':' &&
     176        (pszFilename[len - 3] == '\\' || pszFilename[len - 3] == '/'))
     177        pszFilename += len - 2;
     178
     179     // a special case of opening the drive letter
     180     // in OPEN_FLAGS_DASD mode (logical disk or CDROM or floppy)
     181     // otherwise, opening "w:" causes VERR_IS_A_DIRECTORY error    if ( (tolower(pszFilename[0]) <= 'z' &&
     182    if ( (*pFile)->rawfs ||
     183         (tolower(pszFilename[0]) >= 'a' &&
     184         tolower(pszFilename[0]) <= 'z' &&
     185         pszFilename[1] == ':' &&
     186         pszFilename[2] == '\0') )
     187    {
     188        // logical disk
     189        ULONG  ulAction;
     190        ULONG  sig;
     191        ULONG  parmlen = sizeof(sig);
     192        ULONG  datalen = sizeof(sig);
     193        //HFILE  hDisk = NULLHANDLE;
     194        ULONG  fsOpenMode = OPEN_SHARE_DENYNONE | OPEN_FLAGS_NOINHERIT | OPEN_FLAGS_FAIL_ON_ERROR;
     195
     196        if (! (*pFile)->rawfs)
     197            fsOpenMode |= OPEN_FLAGS_DASD;
     198
     199        switch (fOpen & RTFILE_O_ACCESS_MASK)
     200        {
     201            case RTFILE_O_READ:
     202                fsOpenMode |= OPEN_ACCESS_READONLY;
     203                break;
     204            case RTFILE_O_WRITE:
     205                fsOpenMode |= OPEN_ACCESS_WRITEONLY;
     206                break;
     207            case RTFILE_O_READWRITE:
     208                fsOpenMode |= OPEN_ACCESS_READWRITE;
     209                break;
     210            default:
     211                AssertMsgFailed(("RTFileOpen received an invalid RW value, fOpen=%#llx\n", fOpen));
     212                return VERR_INVALID_PARAMETER;
     213        }
     214
     215        rc = DosOpenL(pszFilename, (PHFILE)&fh,
     216                      &ulAction, 0, FILE_NORMAL,
     217                      OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,
     218                      fsOpenMode, NULL);
     219
     220        if (rc == 0)
     221        {
     222            if (! fh)
     223                return VERR_MEDIA_NOT_PRESENT;
     224
     225            if (rtOs2IsCdRom(pszFilename))
     226            {
     227                // identify CDROM driver
     228                sig = ('C') | ('D' << 8) | ('9' << 16) | ('9' << 24);
     229
     230                if ( (rc = DosDevIOCtl(fh, IOCTL_CDROMDISK, CDROMDISK_GETDRIVER,
     231                                       &sig, sizeof(sig), NULL,
     232                                       &sig, sizeof(sig), NULL)) ||
     233                      sig != (('C') | ('D' << 8) | ('0' << 16) | ('1' << 24)) )
     234                    return VERR_MEDIA_NOT_PRESENT;
     235
     236                RTFileFromNative(pFile, fh);
     237                (*pFile)->type = FILE_TYPE_CD;
     238
     239                // lock drive
     240                if ( (rc = DosDevIOCtl(fh, IOCTL_DISK, DSK_LOCKDRIVE,
     241                                       &dummy, sizeof(dummy), NULL,
     242                                       &dummy, sizeof(dummy), NULL)) )
     243                    return RTErrConvertFromOS2(rc);
     244
     245                return VINF_SUCCESS;
     246            }
     247
     248            RTFileFromNative(pFile, fh);
     249
     250            if (! strncmp(pszFilename, "\\\\.\\Physical_Disk", 17))
     251            {
     252                (*pFile)->type = FILE_TYPE_RAW;
     253
     254                // lock drive
     255                if ( (rc = DosDevIOCtl(fh, IOCTL_PHYSICALDISK, PDSK_LOCKPHYSDRIVE,
     256                                       &dummy, sizeof(dummy), NULL,
     257                                       &dummy, sizeof(dummy), NULL)) )
     258                    return RTErrConvertFromOS2(rc);
     259            }
     260            else
     261            {
     262                (*pFile)->type = FILE_TYPE_DASD;
     263
     264                // lock drive
     265                if ( (rc = DosDevIOCtl(fh, IOCTL_DISK, DSK_LOCKDRIVE,
     266                                       &dummy, sizeof(dummy), NULL,
     267                                       &dummy, sizeof(dummy), NULL)) )
     268                    return RTErrConvertFromOS2(rc);
     269            }
     270
     271            return VINF_SUCCESS;
     272        }
     273
     274        return RTErrConvertFromOS2(rc);
     275    }
     276    else if (pszFilename[0] <= '9' &&
     277             pszFilename[0] >= '0' &&
     278             pszFilename[1] == ':' &&
     279             pszFilename[2] == '\0')
     280    {
     281        // physical disk number
     282        rc = DosPhysicalDisk(INFO_GETIOCTLHANDLE,
     283                             (PHFILE)&fh,
     284                             2L,
     285                             (PSZ)pszFilename,
     286                             strlen((PSZ)pszFilename) + 1);
     287
     288        if (! rc)
     289        {
     290            if (! fh)
     291                return VERR_MEDIA_NOT_PRESENT;
     292
     293            RTFileFromNative(pFile, fh);
     294            (*pFile)->type = FILE_TYPE_RAW;
     295
     296            // lock drive
     297            if ( (rc = DosDevIOCtl(fh, IOCTL_PHYSICALDISK, PDSK_LOCKPHYSDRIVE,
     298                                   &dummy, sizeof(dummy), NULL,
     299                                   &dummy, sizeof(dummy), NULL)) )
     300                return RTErrConvertFromOS2(rc);
     301
     302            return VINF_SUCCESS;
     303        }
     304
     305        return RTErrConvertFromOS2(rc);
     306    }
     307    else
     308    {
     309        fh = open(pszFilename, fOpenMode, fMode);
     310        RTFileFromNative(pFile, fh);
     311        return -1;
     312    }
     313
     314    return VINF_SUCCESS;
     315}
     316
     317static int rtOs2ExtraFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, off_t *poffActual)
     318{
     319    static const unsigned aSeekRecode[] =
     320    {
     321        SEEK_SET,
     322        SEEK_CUR,
     323        SEEK_END,
     324    };
     325
     326    #pragma pack(1)
     327
     328    /* parameter packet */
     329    struct {
     330        UCHAR command;
     331        UCHAR drive;
     332    } parm;
     333
     334    struct {
     335        UCHAR command;
     336    } parmphys;
     337
     338    #pragma pack()
     339
     340    /* data packet      */
     341    BIOSPARAMETERBLOCK bpb;
     342    DEVICEPARAMETERBLOCK dpb;
     343    ULONG parm2 = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     344    ULONG parmlen2 = sizeof(parm2);
     345    ULONG data2 = 0;
     346    ULONG datalen2 = sizeof(data2);
     347    int rc = NO_ERROR;
     348
     349    LONGLONG cb;
     350    ULONG cbSectors;
     351    ULONG parmlen;
     352    ULONG datalen;
     353
     354    if (hFile->type == FILE_TYPE_NORMAL)
     355    {
     356        rc = lseek(RTFileToNative(hFile), (off_t)offSeek, aSeekRecode[uMethod]);
     357
     358        if (rc < 0)
     359            rc = RTErrConvertFromErrno(errno);
     360        else
     361        {
     362            hFile->off = rc;
     363            rc = 0;
     364        }
     365    }
     366    else
     367    {
     368        switch (uMethod)
     369        {
     370            case RTFILE_SEEK_BEGIN:
     371                hFile->off = offSeek;
     372                break;
     373
     374            case RTFILE_SEEK_CURRENT:
     375                hFile->off += offSeek;
     376                break;
     377
     378            case RTFILE_SEEK_END:
     379                switch (hFile->type)
     380                {
     381                    case FILE_TYPE_CD:
     382                        if ( (rc = DosDevIOCtl(RTFileToNative(hFile),
     383                                               IOCTL_CDROMDISK, CDROMDISK_DEVICESTATUS,
     384                                               &parm2, parmlen2, &parmlen2,
     385                                               &data2, datalen2, &datalen2)) )
     386                            break;
     387
     388                        if (data2 & (1 << 11))
     389                        {
     390                            // disk does not present
     391                            rc = ERROR_UNCERTAIN_MEDIA;
     392                            break;
     393                        }
     394
     395                        parm2 = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     396
     397                        if ( (rc = DosDevIOCtl(RTFileToNative(hFile),
     398                                               IOCTL_CDROMDISK, CDROMDISK_GETVOLUMESIZE,
     399                                               &parm2, parmlen2, &parmlen2,
     400                                               &data2, datalen2, &datalen2)) )
     401                            break;
     402
     403                        // return disk size in bytes
     404                        hFile->off = data2 << 11; // multiply by sector size (2048)
     405                        rc = NO_ERROR;
     406                        break;
     407
     408                    case FILE_TYPE_DASD:
     409                        parmlen = sizeof(parm);
     410                        datalen = sizeof(bpb);
     411
     412                        memset(&bpb, 0, sizeof(bpb));
     413
     414                        parm.command = 1; // Return the BPB for the media currently in the drive
     415                        parm.drive = 0;   // unused
     416
     417                        if ( (rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     418                                               &parm, parmlen, &parmlen,
     419                                               &bpb, datalen, &datalen)) )
     420                            break;
     421
     422                        hFile->off = bpb.cCylinders
     423                                   * bpb.cHeads
     424                                   * bpb.usSectorsPerTrack;
     425                        hFile->off <<= 9; // multiply by sector size (512)
     426                        break;
     427
     428                    case FILE_TYPE_RAW:
     429                        parmlen = sizeof(parmphys);
     430                        datalen = sizeof(dpb);
     431
     432                        memset(&dpb, 0, sizeof(dpb));
     433
     434                        parmphys.command = 1;
     435
     436                        if ( (rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_PHYSICALDISK, PDSK_GETPHYSDEVICEPARAMS,
     437                                               &parmphys, parmlen, &parmlen,
     438                                               &dpb, datalen, &datalen)) )
     439                            break;
     440
     441                        hFile->off = dpb.cCylinders
     442                                   * dpb.cHeads
     443                                   * dpb.cSectorsPerTrack;
     444                        hFile->off <<= 9; // multiply by sector size (512)
     445                        break;
     446
     447                    default:
     448                        AssertMsgFailed(("Incorrect handle type!\n"));
     449                }
     450                hFile->off -= offSeek;
     451                break;
     452
     453            default:
     454                AssertMsgFailed(("Incorrect seek type!\n"));
     455        }
     456    }
     457    *poffActual = hFile->off;
     458    rc = RTErrConvertFromOS2(rc);
     459    return rc;
     460}
     461
     462static int rtOs2ExtraFileRead(RTFILE hFile, void *pvBuf, size_t cbToRead, ssize_t *pcbRead)
     463{
     464    #pragma pack(1)
     465
     466    // parameter packet
     467    struct ReadData_param {
     468        ULONG       ID_code;                // 'CD01'
     469        UCHAR       address_mode;           // Addressing format of start_sector:
     470                                            //  00 - Logical Block format
     471                                            //  01 - Minutes/Seconds/Frame format
     472        USHORT      transfer_count;         // Numbers of sectors to read.
     473                                            //  Must  be non zero
     474        ULONG       start_sector;           // Starting sector number of the read operation
     475        UCHAR       reserved;               // Reserved. Must be 0
     476        UCHAR       interleave_size;        // Not used. Must be 0
     477        UCHAR       interleave_skip_factor; // Not used. Must be 0
     478    } parm;
     479    ULONG parmlen = sizeof(parm);
     480
     481    #define SECTORSIZE      2048
     482
     483    struct ReadData_data {
     484        UCHAR        data_area[SECTORSIZE];
     485    } data;
     486
     487    ULONG datalen = sizeof(data);
     488    uint32_t cbRead32;
     489
     490    /* parameter packet */
     491    struct PARM {
     492        unsigned char command;
     493        unsigned char drive;
     494    } parm2;
     495
     496    #pragma pack()
     497
     498    /* data packet      */
     499    BIOSPARAMETERBLOCK bpb;
     500    ULONG parmlen2 = sizeof(parm2);
     501    ULONG datalen2 = sizeof(bpb);
     502    int32_t rc = 0;
     503
     504    parm2.command = 1;
     505    parm2.drive = 0;
     506
     507    struct {
     508        unsigned char command;
     509    } parmphys;
     510    DEVICEPARAMETERBLOCK dpb;
     511    ULONG parmphyslen = sizeof(parmphys);
     512    ULONG dataphyslen = sizeof(dpb);
     513
     514    parmphys.command = 0;
     515
     516    if (hFile->type == FILE_TYPE_DASD || hFile->type == FILE_TYPE_CD)
     517    {
     518        if ( (rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     519                               &parm2, parmlen2, &parmlen2, &bpb, datalen2, &datalen2)) )
     520            return RTErrConvertFromOS2(rc);
     521    }
     522    else if (hFile->type == FILE_TYPE_RAW)
     523    {
     524        if ( (rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_PHYSICALDISK, PDSK_GETPHYSDEVICEPARAMS,
     525                               &parmphys, parmphyslen, &parmphyslen, &dpb, dataphyslen, &dataphyslen)) )
     526            return RTErrConvertFromOS2(rc);
     527    }
     528
     529    #define BUFSIZE 0x4000
     530    #define SECSIZE 512
     531    ULONG parmlen4 = sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * (bpb.usSectorsPerTrack - 1);
     532    char trkbuf[sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * 255];
     533    PTRACKLAYOUT ptrk = (PTRACKLAYOUT)trkbuf;
     534    ULONG datalen4 = BUFSIZE;
     535    USHORT cyl, head, sec, n;
     536    ssize_t cbRead = 0;
     537
     538    if (hFile->rawfs)
     539    {
     540        rc = DosRead(RTFileToNative(hFile), pvBuf, cbToRead, (PULONG)&cbRead);
     541        rc = RTErrConvertFromOS2(rc);
     542    }
     543    else
     544    {
     545        switch (hFile->type)
     546        {
     547            case FILE_TYPE_NORMAL:
     548                cbRead = read(RTFileToNative(hFile), pvBuf, cbToRead);
     549
     550                if (cbRead < 0)
     551                    rc = RTErrConvertFromErrno(errno);
     552                else
     553                    rc = VINF_SUCCESS;
     554                break;
     555
     556            case FILE_TYPE_CD:
     557                AssertReturn(!(hFile->off % SECTORSIZE), VERR_INVALID_PARAMETER);
     558                cbRead32 = (cbToRead > SECTORSIZE) ? SECTORSIZE : (uint32_t)cbToRead;
     559                AssertReturn(!(cbToRead % SECTORSIZE), VERR_INVALID_PARAMETER);
     560
     561                memset(&parm, 0, sizeof(parm));
     562                parm.ID_code = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     563                parm.address_mode = 0; // lba
     564
     565                do
     566                {
     567                    parm.transfer_count = 1;
     568                    parm.start_sector = (ULONG)(hFile->off / SECTORSIZE);
     569
     570                    rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_CDROMDISK, CDROMDISK_READDATA,
     571                                     &parm, parmlen, &parmlen, &data, datalen, &datalen);
     572
     573                    rc = RTErrConvertFromOS2(rc);
     574
     575                    if (RT_SUCCESS(rc))
     576                        memcpy((char *)pvBuf, &data, cbRead32);
     577                    else
     578                        break;
     579
     580                    hFile->off    += cbRead32;
     581                    cbRead        += cbRead32;
     582                    cbToRead      -= cbRead32;
     583                    pvBuf         = (uint8_t *)pvBuf + cbRead32;
     584
     585                } while ((cbToRead > 0) && RT_SUCCESS(rc));
     586                break;
     587
     588            case FILE_TYPE_DASD:
     589                cbRead32 = (cbToRead > BUFSIZE) ? BUFSIZE : (uint32_t)cbToRead;
     590
     591                memset((char *)trkbuf, 0, sizeof(trkbuf));
     592
     593                for (int i = 0; i < bpb.usSectorsPerTrack; i++)
     594                {
     595                    ptrk->TrackTable[i].usSectorNumber = i + 1;
     596                    ptrk->TrackTable[i].usSectorSize = SECSIZE;
     597                }
     598
     599                do
     600                {
     601                    cyl = hFile->off / (SECSIZE * bpb.cHeads * bpb.usSectorsPerTrack);
     602                    head = (hFile->off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl) / bpb.usSectorsPerTrack;
     603                    sec = hFile->off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl - head * bpb.usSectorsPerTrack;
     604
     605                    if (sec + cbRead32 / SECSIZE > bpb.usSectorsPerTrack)
     606                        n = bpb.usSectorsPerTrack - sec + 1;
     607                    else
     608                        n = cbRead32 / SECSIZE;
     609
     610                    ptrk->bCommand = 1;
     611                    ptrk->usHead = head;
     612                    ptrk->usCylinder = cyl;
     613                    ptrk->usFirstSector = sec;
     614                    ptrk->cSectors = n;
     615
     616                    rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_DISK, DSK_READTRACK,
     617                                     trkbuf, parmlen4, &parmlen4, pvBuf, datalen4, &datalen4);
     618
     619                    rc = RTErrConvertFromOS2(rc);
     620
     621                    if (RT_FAILURE(rc))
     622                        break;
     623
     624                    hFile->off    += cbRead32;
     625                    cbToRead      -= cbRead32;
     626                    cbRead        += cbRead32;
     627                    pvBuf         = (uint8_t *)pvBuf + cbRead32;
     628
     629                } while ((cbToRead > 0) && RT_SUCCESS(rc));
     630                break;
     631
     632            case FILE_TYPE_RAW:
     633                cbRead32 = (cbToRead > BUFSIZE) ? BUFSIZE : (uint32_t)cbToRead;
     634
     635                memset((char *)trkbuf, 0, sizeof(trkbuf));
     636
     637                for (int i = 0; i < dpb.cSectorsPerTrack; i++)
     638                {
     639                    ptrk->TrackTable[i].usSectorNumber = i + 1;
     640                    ptrk->TrackTable[i].usSectorSize = SECSIZE;
     641                }
     642
     643                do
     644                {
     645                    cyl = hFile->off / (SECSIZE * dpb.cHeads * dpb.cSectorsPerTrack);
     646                    head = (hFile->off / SECSIZE - dpb.cHeads * dpb.cSectorsPerTrack * cyl) / dpb.cSectorsPerTrack;
     647                    sec = hFile->off / SECSIZE - dpb.cHeads * dpb.cSectorsPerTrack * cyl - head * dpb.cSectorsPerTrack;
     648
     649                    if (sec + cbRead32 / SECSIZE > dpb.cSectorsPerTrack)
     650                        n = dpb.cSectorsPerTrack - sec + 1;
     651                    else
     652                        n = cbRead32 / SECSIZE;
     653
     654                    ptrk->bCommand = 1;
     655                    ptrk->usHead = head;
     656                    ptrk->usCylinder = cyl;
     657                    ptrk->usFirstSector = sec;
     658                    ptrk->cSectors = n;
     659
     660                    rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_PHYSICALDISK, PDSK_READPHYSTRACK,
     661                                     trkbuf, parmlen4, &parmlen4, (void *)pvBuf, datalen4, &datalen4);
     662
     663                    rc = RTErrConvertFromOS2(rc);
     664
     665                    if (RT_FAILURE(rc))
     666                        break;
     667
     668                    hFile->off += cbRead32;
     669                    cbRead     += cbRead32;
     670                    cbToRead   -= cbRead32;
     671                    pvBuf      =  (uint8_t *)pvBuf + cbRead32;
     672
     673                } while ((cbToRead > 0) && RT_SUCCESS(rc));
     674                break;
     675
     676            default:
     677                rc = VERR_NOT_SUPPORTED;
     678        }
     679    }
     680    *pcbRead = cbRead;
     681    return rc;
     682}
     683
     684static int rtOs2ExtraFileWrite(RTFILE hFile, const void *pvBuf, size_t cbToWrite, ssize_t *pcbWritten)
     685{
     686    #pragma pack(1)
     687
     688    // parameter packet
     689    struct WriteData_param {
     690        ULONG       ID_code;                // 'CD01'
     691        UCHAR       address_mode;           // Addressing format of start_sector:
     692                                            //  00 - Logical Block format
     693                                            //  01 - Minutes/Seconds/Frame format
     694        USHORT      transfer_count;         // Numbers of sectors to read.
     695                                            //  Must  be non zero
     696        ULONG       start_sector;           // Starting sector number of the read operation
     697        UCHAR       reserved;               // Reserved. Must be 0
     698        UCHAR       interleave_size;        // Not used. Must be 0
     699        UCHAR       interleave_skip_factor; // Not used. Must be 0
     700    } parm;
     701    ULONG parmlen = sizeof(parm);
     702
     703    #define SECTORSIZE      2048
     704
     705    // data packet
     706    struct WriteData_data {
     707        UCHAR       sector_data[2048]; // Sector to be written to the disk
     708    } data;
     709
     710    ULONG datalen, data_offset;
     711    uint32_t cbWrite32;
     712
     713    datalen = sizeof(data);
     714
     715    /* parameter packet */
     716    struct {
     717        unsigned char command;
     718        unsigned char drive;
     719    } parm2;
     720
     721    #pragma pack()
     722
     723    /* data packet      */
     724    BIOSPARAMETERBLOCK bpb;
     725    ULONG parmlen2 = sizeof(parm2);
     726    ULONG datalen2 = sizeof(bpb);
     727    int32_t rc = 0;
     728
     729    parm2.command = 1;
     730    parm2.drive = 0;
     731
     732    struct {
     733        unsigned char command;
     734    } parmphys;
     735    DEVICEPARAMETERBLOCK dpb;
     736    ULONG parmphyslen = sizeof(parmphys);
     737    ULONG dataphyslen = sizeof(dpb);
     738
     739    parmphys.command = 0;
     740
     741    if (hFile->type == FILE_TYPE_DASD || hFile->type == FILE_TYPE_CD)
     742    {
     743        if ( (rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     744                               &parm2, parmlen2, &parmlen2, &bpb, datalen2, &datalen2)) )
     745            return RTErrConvertFromOS2(rc);
     746    }
     747    else if (hFile->type == FILE_TYPE_RAW)
     748    {
     749        if ( (rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_PHYSICALDISK, PDSK_GETPHYSDEVICEPARAMS,
     750                               &parmphys, parmphyslen, &parmphyslen, &dpb, dataphyslen, &dataphyslen)) )
     751            return RTErrConvertFromOS2(rc);
     752    }
     753
     754    #define BUFSIZE 0x4000
     755    #define SECSIZE 512
     756
     757    ULONG parmlen4;
     758
     759    if (hFile->type == FILE_TYPE_DASD || hFile->type == FILE_TYPE_CD)
     760        parmlen4 = sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * (bpb.usSectorsPerTrack - 1);
     761    else if (hFile->type == FILE_TYPE_RAW)
     762        parmlen4 = sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * (dpb.cSectorsPerTrack - 1);
     763
     764    char trkbuf[sizeof(TRACKLAYOUT) + sizeof(USHORT) * 2 * 255];
     765    PTRACKLAYOUT ptrk = (PTRACKLAYOUT)trkbuf;
     766    ULONG datalen4 = BUFSIZE;
     767    USHORT cyl, head, sec, n;
     768    ssize_t cbWritten = 0;
     769
     770    if (hFile->rawfs)
     771    {
     772        rc = DosWrite(RTFileToNative(hFile), pvBuf, cbToWrite, (PULONG)&cbWritten);
     773        rc = RTErrConvertFromOS2(rc);
     774    }
     775    else
     776    {
     777        switch (hFile->type)
     778        {
     779            case FILE_TYPE_NORMAL:
     780                cbWritten = write(RTFileToNative(hFile), pvBuf, cbToWrite);
     781
     782                if (cbWritten < 0)
     783                    rc = RTErrConvertFromErrno(errno);
     784                else
     785                    rc = VINF_SUCCESS;
     786                break;
     787
     788            case FILE_TYPE_CD:
     789                AssertReturn(!(hFile->off % SECTORSIZE), VERR_INVALID_PARAMETER);
     790                cbWrite32 = (cbToWrite > SECTORSIZE) ? SECTORSIZE : (uint32_t)cbToWrite;
     791                AssertReturn(!(cbToWrite % SECTORSIZE), VERR_INVALID_PARAMETER);
     792
     793                memset(&parm, 0, sizeof(parm));
     794                memset(&data, 0, sizeof(data));
     795
     796                parm.ID_code = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     797                parm.address_mode = 0; // lba
     798
     799                do
     800                {
     801                    parm.transfer_count = 1;
     802                    parm.start_sector = (ULONG)(hFile->off / SECTORSIZE);
     803
     804                    memcpy(&data, (char *)pvBuf, cbWrite32);
     805
     806                    rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_CDROMDISK, CDROMDISK_WRITEDATA,
     807                                     &parm, parmlen, &parmlen, &data, datalen, &datalen);
     808
     809                    rc = RTErrConvertFromOS2(rc);
     810
     811                    if (RT_FAILURE(rc))
     812                        break;
     813
     814                    hFile->off += cbWrite32;
     815                    cbWritten  += cbWrite32;
     816                    cbToWrite  -= cbWrite32;
     817                    pvBuf      =  (uint8_t *)pvBuf + cbWrite32;
     818
     819                } while ((cbToWrite > 0) && RT_SUCCESS(rc));
     820                break;
     821
     822            case FILE_TYPE_DASD:
     823                cbWrite32 = (cbToWrite > BUFSIZE) ? BUFSIZE : (uint32_t)cbToWrite;
     824
     825                memset((char *)trkbuf, 0, sizeof(trkbuf));
     826
     827                for (int i = 0; i < bpb.usSectorsPerTrack; i++)
     828                {
     829                    ptrk->TrackTable[i].usSectorNumber = i + 1;
     830                    ptrk->TrackTable[i].usSectorSize = SECSIZE;
     831                }
     832
     833                do
     834                {
     835                    cyl = hFile->off / (SECSIZE * bpb.cHeads * bpb.usSectorsPerTrack);
     836                    head = (hFile->off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl) / bpb.usSectorsPerTrack;
     837                    sec = hFile->off / SECSIZE - bpb.cHeads * bpb.usSectorsPerTrack * cyl - head * bpb.usSectorsPerTrack;
     838
     839                    if (sec + cbWrite32 / SECSIZE > bpb.usSectorsPerTrack)
     840                        n = bpb.usSectorsPerTrack - sec + 1;
     841                    else
     842                        n = cbWrite32 / SECSIZE;
     843
     844                    ptrk->bCommand = 1;
     845                    ptrk->usHead = head;
     846                    ptrk->usCylinder = cyl;
     847                    ptrk->usFirstSector = sec;
     848                    ptrk->cSectors = n;
     849
     850                    rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_DISK, DSK_WRITETRACK,
     851                                     trkbuf, parmlen4, &parmlen4, (void *)pvBuf, datalen4, &datalen4);
     852
     853                    rc = RTErrConvertFromOS2(rc);
     854
     855                    if (RT_FAILURE(rc))
     856                        break;
     857
     858                    hFile->off += cbWrite32;
     859                    cbWritten  += cbWrite32;
     860                    cbToWrite  -= cbWrite32;
     861                    pvBuf      =  (uint8_t *)pvBuf + cbWrite32;
     862
     863                } while ((cbToWrite > 0) && RT_SUCCESS(rc));
     864                break;
     865
     866            case FILE_TYPE_RAW:
     867                cbWrite32 = (cbToWrite > BUFSIZE) ? BUFSIZE : (uint32_t)cbToWrite;
     868
     869                memset((char *)trkbuf, 0, sizeof(trkbuf));
     870
     871                for (int i = 0; i < dpb.cSectorsPerTrack; i++)
     872                {
     873                    ptrk->TrackTable[i].usSectorNumber = i + 1;
     874                    ptrk->TrackTable[i].usSectorSize = SECSIZE;
     875                }
     876
     877                do
     878                {
     879                    cyl = hFile->off / (SECSIZE * dpb.cHeads * dpb.cSectorsPerTrack);
     880                    head = (hFile->off / SECSIZE - dpb.cHeads * dpb.cSectorsPerTrack * cyl) / dpb.cSectorsPerTrack;
     881                    sec = hFile->off / SECSIZE - dpb.cHeads * dpb.cSectorsPerTrack * cyl - head * dpb.cSectorsPerTrack;
     882
     883                    if (sec + cbWrite32 / SECSIZE > dpb.cSectorsPerTrack)
     884                        n = dpb.cSectorsPerTrack - sec + 1;
     885                    else
     886                        n = cbWrite32 / SECSIZE;
     887
     888                    ptrk->bCommand = 1;
     889                    ptrk->usHead = head;
     890                    ptrk->usCylinder = cyl;
     891                    ptrk->usFirstSector = sec;
     892                    ptrk->cSectors = n;
     893
     894                    rc = DosDevIOCtl(RTFileToNative(hFile), IOCTL_PHYSICALDISK, PDSK_WRITEPHYSTRACK,
     895                                     trkbuf, parmlen4, &parmlen4, (void *)pvBuf, datalen4, &datalen4);
     896
     897                    rc = RTErrConvertFromOS2(rc);
     898
     899                    if (RT_FAILURE(rc))
     900                        break;
     901
     902                    hFile->off += cbWrite32;
     903                    cbWritten  += cbWrite32;
     904                    cbToWrite  -= cbWrite32;
     905                    pvBuf      =  (uint8_t *)pvBuf + cbWrite32;
     906
     907                } while ((cbToWrite > 0) && RT_SUCCESS(rc));
     908                break;
     909
     910            default:
     911                rc = VERR_NOT_SUPPORTED;
     912        }
     913    }
     914    *pcbWritten = cbWritten;
     915    return rc;
     916}
     917#endif
     918
    102919RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen)
    103920{
    104921    /*
     
    108925    *pFile = NIL_RTFILE;
    109926    AssertPtrReturn(pszFilename, VERR_INVALID_POINTER);
    110927
     928#ifdef RT_OS_OS2
     929    *pFile = (RTFILE)RTMemAllocZ(sizeof(struct RTFILEINT));
     930
     931    (*pFile)->type = FILE_TYPE_NORMAL;
     932    (*pFile)->off = 0;
     933#endif
     934
    111935    /*
    112936     * Merge forced open flags and validate them.
    113937     */
     
    2021026    if (RT_FAILURE(rc))
    2031027        return (rc);
    2041028
    205     int fh = open(pszNativeFilename, fOpenMode, fMode);
     1029    int fh = 0;
     1030#ifdef RT_OS_OS2
     1031    int ret = rtOs2ExtraFileOpen(pFile, pszNativeFilename,
     1032                                 fOpen, fOpenMode, fMode);
     1033
    2061034    int iErr = errno;
     1035    fh = RTFileToNative(*pFile);
    2071036
     1037    if (RT_FAILURE(ret) && ret != -1)
     1038        return ret;
     1039#else
     1040    fh = open(pszNativeFilename, fOpenMode, fMode);
     1041    iErr = errno;
     1042#endif
     1043
    2081044#ifdef O_CLOEXEC
    2091045    if (   (fOpenMode & O_CLOEXEC)
    2101046        && s_fHave_O_CLOEXEC == 0)
     
    2161052            iErr = errno;
    2171053        }
    2181054        else if (fh >= 0)
     1055        {
    2191056            s_fHave_O_CLOEXEC = fcntl(fh, F_GETFD, 0) > 0 ? 1 : -1;
     1057        }
    2201058    }
    2211059#endif
    2221060
     
    3281166         */
    3291167        if (iErr == 0)
    3301168        {
    331             *pFile = (RTFILE)(uintptr_t)fh;
    332             Assert((intptr_t)*pFile == fh);
     1169            RTFileFromNative(pFile, fh);
    3331170            LogFlow(("RTFileOpen(%p:{%RTfile}, %p:{%s}, %#llx): returns %Rrc\n",
    3341171                     pFile, *pFile, pszFilename, pszFilename, fOpen, rc));
    3351172            return VINF_SUCCESS;
     
    3371174
    3381175        close(fh);
    3391176    }
     1177#ifdef RT_OS_OS2
     1178    // it traps in some cases if we free it at this point
     1179    // (in an unsuccessful open case)
     1180    //RTMemFree(*pFile);
     1181#endif
    3401182    return RTErrConvertFromErrno(iErr);
    3411183}
    3421184
     
    3551197{
    3561198    if (hFile == NIL_RTFILE)
    3571199        return VINF_SUCCESS;
     1200#ifdef RT_OS_OS2
     1201    // lock drive
     1202    ULONG  dummy;
     1203    APIRET rc;
     1204
     1205    if (hFile->type == FILE_TYPE_DASD || hFile->type == FILE_TYPE_CD)
     1206    {
     1207        if ( (rc = DosDevIOCtl(RTFileToNative(hFile),
     1208                               IOCTL_DISK, DSK_UNLOCKDRIVE,
     1209                               &dummy, sizeof(dummy), NULL,
     1210                               &dummy, sizeof(dummy), NULL)) )
     1211            return RTErrConvertFromOS2(rc);
     1212    }
     1213    else if (hFile->type == FILE_TYPE_RAW)
     1214    {
     1215        if ( (rc = DosDevIOCtl(RTFileToNative(hFile),
     1216                               IOCTL_PHYSICALDISK, PDSK_UNLOCKPHYSDRIVE,
     1217                               &dummy, sizeof(dummy), NULL,
     1218                               &dummy, sizeof(dummy), NULL)) )
     1219            return RTErrConvertFromOS2(rc);
     1220    }
     1221
     1222    if (! hFile->rawfs && hFile->type == FILE_TYPE_RAW)
     1223    {
     1224        // physical disk handle
     1225        HFILE fh = RTFileToNative(hFile);
     1226        DosPhysicalDisk(INFO_FREEIOCTLHANDLE,
     1227                        NULL,
     1228                        0L,
     1229                        &fh,
     1230                        2L);
     1231    }
     1232    else
     1233#endif
    3581234    if (close(RTFileToNative(hFile)) == 0)
     1235    {
     1236#ifdef RT_OS_OS2
     1237        RTMemFree(hFile);
     1238#endif
    3591239        return VINF_SUCCESS;
     1240    }
    3601241    return RTErrConvertFromErrno(errno);
    3611242}
    3621243
    3631244
    3641245RTR3DECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative)
    3651246{
     1247#ifndef RT_OS_OS2
    3661248    AssertCompile(sizeof(uNative) == sizeof(*pFile));
     1249#endif
    3671250    if (uNative < 0)
    3681251    {
    3691252        AssertMsgFailed(("%p\n", uNative));
    3701253        *pFile = NIL_RTFILE;
    3711254        return VERR_INVALID_HANDLE;
    3721255    }
     1256#ifdef RT_OS_OS2
     1257    (*pFile)->hFile = uNative;
     1258#else
    3731259    *pFile = (RTFILE)uNative;
     1260#endif
    3741261    return VINF_SUCCESS;
    3751262}
    3761263
     
    3781265RTR3DECL(RTHCINTPTR) RTFileToNative(RTFILE hFile)
    3791266{
    3801267    AssertReturn(hFile != NIL_RTFILE, -1);
     1268#ifdef RT_OS_OS2
     1269    return (intptr_t)hFile->hFile;
     1270#else
    3811271    return (intptr_t)hFile;
     1272#endif
    3821273}
    3831274
    3841275
     
    4151306    return rc;
    4161307}
    4171308
    418 
    4191309RTR3DECL(int)  RTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, uint64_t *poffActual)
    4201310{
    4211311    static const unsigned aSeekRecode[] =
     
    4431333        return VERR_NOT_SUPPORTED;
    4441334    }
    4451335
    446     off_t offCurrent = lseek(RTFileToNative(hFile), (off_t)offSeek, aSeekRecode[uMethod]);
     1336    off_t offCurrent;
     1337#ifdef RT_OS_OS2
     1338    int ret = rtOs2ExtraFileSeek(hFile, offSeek, uMethod, &offCurrent);
     1339#else
     1340    offCurrent = lseek(RTFileToNative(hFile), (off_t)offSeek, aSeekRecode[uMethod]);
     1341    int ret = VINF_SUCCESS;
     1342
     1343    if (ret < 0)
     1344        ret = RTErrConvertFromErrno(errno);
     1345#endif
    4471346    if (offCurrent != ~0)
    4481347    {
    4491348        if (poffActual)
    4501349            *poffActual = (uint64_t)offCurrent;
    4511350        return VINF_SUCCESS;
    4521351    }
    453     return RTErrConvertFromErrno(errno);
     1352    return ret;
    4541353}
    4551354
    456 
    4571355RTR3DECL(int)  RTFileRead(RTFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead)
    4581356{
    4591357    if (cbToRead <= 0)
     
    4621360    /*
    4631361     * Attempt read.
    4641362     */
    465     ssize_t cbRead = read(RTFileToNative(hFile), pvBuf, cbToRead);
     1363    ssize_t cbRead;
     1364#ifdef RT_OS_OS2
     1365    if ((rtOs2ExtraFileRead(hFile, pvBuf, cbToRead, &cbRead) == VINF_SUCCESS) && (cbRead >= 0))
     1366#else
     1367    cbRead = read(RTFileToNative(hFile), pvBuf, cbToRead);
    4661368    if (cbRead >= 0)
     1369#endif
    4671370    {
    4681371        if (pcbRead)
    4691372            /* caller can handle partial read. */
     
    4731376            /* Caller expects all to be read. */
    4741377            while ((ssize_t)cbToRead > cbRead)
    4751378            {
    476                 ssize_t cbReadPart = read(RTFileToNative(hFile), (char*)pvBuf + cbRead, cbToRead - cbRead);
     1379                ssize_t cbReadPart;
     1380                int rc;
     1381#ifdef RT_OS_OS2
     1382                if (((rc = rtOs2ExtraFileRead(hFile, (char *)pvBuf + cbRead, cbToRead - cbRead,
     1383                                           &cbReadPart)) != VINF_SUCCESS) || (cbReadPart <= 0))
     1384                {
     1385                    if (cbReadPart == 0)
     1386                        return VERR_EOF;
     1387                    return rc;
     1388                }
     1389#else
     1390                cbReadPart = read(RTFileToNative(hFile), (char*)pvBuf + cbRead, cbToRead - cbRead);
    4771391                if (cbReadPart <= 0)
    4781392                {
    4791393                    if (cbReadPart == 0)
    4801394                        return VERR_EOF;
    4811395                    return RTErrConvertFromErrno(errno);
    4821396                }
     1397#endif
    4831398                cbRead += cbReadPart;
    4841399            }
    4851400        }
     
    4981413    /*
    4991414     * Attempt write.
    5001415     */
    501     ssize_t cbWritten = write(RTFileToNative(hFile), pvBuf, cbToWrite);
     1416    ssize_t cbWritten;
     1417#ifdef RT_OS_OS2
     1418    if ((rtOs2ExtraFileWrite(hFile, pvBuf, cbToWrite, &cbWritten) == VINF_SUCCESS) && (cbWritten >= 0))
     1419#else
     1420    cbWritten = write(RTFileToNative(hFile), pvBuf, cbToWrite);
    5021421    if (cbWritten >= 0)
     1422#endif
    5031423    {
    5041424        if (pcbWritten)
    5051425            /* caller can handle partial write. */
     
    5091429            /* Caller expects all to be write. */
    5101430            while ((ssize_t)cbToWrite > cbWritten)
    5111431            {
    512                 ssize_t cbWrittenPart = write(RTFileToNative(hFile), (const char *)pvBuf + cbWritten, cbToWrite - cbWritten);
     1432                ssize_t cbWrittenPart;
     1433                int rc;
     1434#ifdef RT_OS_OS2
     1435                if (((rc = rtOs2ExtraFileWrite(hFile, (char *)pvBuf + cbWritten, cbToWrite - cbWritten,
     1436                                            &cbWrittenPart)) != VINF_SUCCESS) || (cbWrittenPart <= 0))
     1437                    return rc;
     1438#else
     1439                cbWrittenPart = write(RTFileToNative(hFile), (const char *)pvBuf + cbWritten, cbToWrite - cbWritten);
    5131440                if (cbWrittenPart <= 0)
    5141441                    return RTErrConvertFromErrno(errno);
     1442#endif
    5151443                cbWritten += cbWrittenPart;
    5161444            }
    5171445        }
     
    6751603
    6761604RTR3DECL(int)  RTFileFlush(RTFILE hFile)
    6771605{
     1606#ifdef RT_OS_OS2
     1607    // Access to a physical disk is not mediated by
     1608    // a filesystem cache, so it is synchronous
     1609    if (hFile->type != FILE_TYPE_RAW)
     1610#endif
    6781611    if (fsync(RTFileToNative(hFile)))
    6791612        return RTErrConvertFromErrno(errno);
    6801613    return VINF_SUCCESS;
  • 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>
    99104#elif defined(RT_OS_FREEBSD)
    100105# include <sys/cdefs.h>
    101106# include <sys/param.h>
     
    11281133    }
    11291134    RTFILE hFileRawDevice;
    11301135    int rc = drvHostBaseOpen(pThis, &hFileDevice, &hFileRawDevice, pThis->fReadOnlyConfig);
     1136#elif defined(RT_OS_OS2)
     1137    if (pThis->hFileDevice != NIL_RTFILE)
     1138    {
     1139        RTFileClose(pThis->hFileDevice);
     1140        pThis->hFileDevice = NIL_RTFILE;
     1141    }
     1142    int rc = drvHostBaseOpen(pThis, &hFileDevice, pThis->fReadOnlyConfig);
    11311143#else
    11321144    int rc = drvHostBaseOpen(pThis, &hFileDevice, pThis->fReadOnlyConfig);
    11331145#endif
     
    20412053    pThis->fAttachFailError = fAttachFailError;
    20422054
    20432055    /* name to open & watch for */
    2044 #ifdef RT_OS_WINDOWS
     2056#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    20452057    int iBit = RT_C_TO_UPPER(pThis->pszDevice[0]) - 'A';
    20462058    if (    iBit > 'Z' - 'A'
    20472059        ||  pThis->pszDevice[1] != ':'
     
    20512063        return VERR_INVALID_PARAMETER;
    20522064    }
    20532065    pThis->fUnitMask = 1 << iBit;
     2066#if defined(RT_OS_WINDOWS)
    20542067    RTStrAPrintf(&pThis->pszDeviceOpen, "\\\\.\\%s", pThis->pszDevice);
     2068#else
     2069    RTStrAPrintf(&pThis->pszDeviceOpen, "%s", pThis->pszDevice);
     2070#endif
    20552071
    20562072#elif defined(RT_OS_SOLARIS)
    20572073    char *pszBlockDevName = getfullblkname(pThis->pszDevice);
     
    21992215            }
    22002216        }
    22012217    }
    2202 #ifdef RT_OS_WINDOWS
     2218#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    22032219    if (RT_SUCCESS(src))
    22042220        DRVHostBaseMediaPresent(pThis);
    22052221#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# include <stdio.h> // printf
     95
    8996#elif defined(RT_OS_FREEBSD)
    9097# include <sys/cdefs.h>
    9198# include <sys/param.h>
     
    106113#include <iprt/string.h>
    107114#include <iprt/thread.h>
    108115#include <iprt/critsect.h>
     116#include <iprt/mem.h>
    109117#include <VBox/scsi.h>
    110118
    111119#include "VBoxDD.h"
     
    202210                AssertMsgFailed(("Failed to open '%s' for ejecting this tray.\n",  rc));
    203211
    204212
     213#elif defined(RT_OS_OS2)
     214            ULONG parm = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     215            ULONG parmlen = sizeof(parm);
     216
     217            if (! (rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice),
     218                               IOCTL_CDROMDISK, CDROMDISK_EJECTDISK,
     219                               &parm, parmlen, &parmlen,
     220                               NULL, 0, NULL)))
     221                rc = VINF_SUCCESS;
     222            else
     223                rc = RTErrConvertFromOS2(rc);
    205224#else
    206225            AssertMsgFailed(("Eject is not implemented!\n"));
    207226            rc = VINF_SUCCESS;
     
    280299        /** @todo figure out the return codes for already locked. */
    281300        rc = RTErrConvertFromWin32(GetLastError());
    282301
     302#elif defined(RT_OS_OS2)
     303    #pragma pack(1)
     304    typedef struct _PARM
     305    {
     306        ULONG sig;
     307        char flag;
     308    } PARM;
     309    #pragma pack()
     310
     311    ULONG  parmlen, datalen = 0;
     312    PARM   parm;
     313    APIRET rc;
     314
     315    parm.sig = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     316    parm.flag = fLock ? 1 : 0;
     317
     318    if (! (rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice), IOCTL_CDROMDISK, CDROMDISK_LOCKUNLOCKDOOR,
     319                            &parm, sizeof(PARM), &parmlen,
     320                            0, datalen, &datalen)))
     321        rc = VINF_SUCCESS;
     322    else
     323        rc = RTErrConvertFromOS2(rc);
    283324#else
    284325    AssertMsgFailed(("Lock/Unlock is not implemented!\n"));
    285326    int rc = VINF_SUCCESS;
     
    631672        rc = RTErrConvertFromWin32(GetLastError());
    632673    Log2(("%s: scsistatus=%d bytes returned=%d tlength=%d\n", __FUNCTION__, Req.spt.ScsiStatus, cbReturned, Req.spt.DataTransferLength));
    633674
     675#elif defined(RT_OS_OS2)
     676    #define CDROMDISK_EXECMD 0x7A
     677    uint16_t flags;
     678
     679    #pragma pack(1)
     680
     681    struct ExecCMD {
     682        ULONG        ID_code;          // 'CD01'
     683        USHORT       data_length;      // length of the Data Packet
     684        USHORT       cmd_length;       // length of the Command Buffer
     685        USHORT       flags;            // flags
     686        UCHAR        cmd_buffer[16];   // Command Buffer for SCSI command
     687        ULONG        cmd_timeout;      // Timeout for executing command (0 - default)
     688    } cmd;
     689
     690    // flags:
     691    #define EX_DIRECTION_IN  0x0001
     692    #define EX_PLAYING_CHK   0x0002
     693    #define EX_RETURN_STATUS 0x0004
     694    #define EX_SET_TIMEOUT   0x0008
     695
     696    #define DATA_TRANSFER_SIZE 2048
     697
     698    struct RetStatus {
     699        UCHAR       sense_key;    // Sense Key
     700        UCHAR       asc_code;     // Additional Sense Code (ASC)
     701        UCHAR       ascq_code;    // Additional Sense Code Qualifier (ASCQ)
     702    };
     703
     704    #pragma pack()
     705
     706    ULONG cmdlen = sizeof(cmd);
     707    ULONG datalen;
     708    char  *data;
     709
     710    switch (enmTxDir)
     711    {
     712        case PDMBLOCKTXDIR_NONE:
     713            Assert(*pcbBuf == 0);
     714            flags = EX_DIRECTION_IN;
     715            break;
     716        case PDMBLOCKTXDIR_FROM_DEVICE:
     717            Assert(*pcbBuf != 0);
     718            /* Make sure that the buffer is clear for commands reading
     719             * data. The actually received data may be shorter than what
     720             * we expect, and due to the unreliable feedback about how much
     721             * data the ioctl actually transferred, it's impossible to
     722             * prevent that. Returning previous buffer contents may cause
     723             * security problems inside the guest OS, if users can issue
     724             * commands to the CDROM device. */
     725            memset(pvBuf, 0, *pcbBuf);
     726            flags = EX_DIRECTION_IN;
     727            break;
     728        case PDMBLOCKTXDIR_TO_DEVICE:
     729            Assert(*pcbBuf != 0);
     730            flags = 0;
     731            break;
     732        default:
     733            AssertMsgFailed(("enmTxDir invalid!\n"));
     734            flags = 0;
     735    }
     736
     737    flags |= EX_SET_TIMEOUT | EX_RETURN_STATUS;
     738
     739    uint32_t cbTransferred = 0;
     740    int32_t  cbSize   = (int32_t)*pcbBuf;
     741    uint16_t cbSize32 = (cbSize >= DATA_TRANSFER_SIZE) ? DATA_TRANSFER_SIZE : cbSize;
     742    char     *pBuf    = (char *)pvBuf;
     743
     744    if (! cbSize32)
     745        cbSize32 = 4;
     746
     747    data = (char *)RTMemAllocZ(cbSize32 + cbSense);
     748
     749    do
     750    {
     751        memset(&cmd, 0, sizeof(cmd));
     752        memset(data, 0, cbSize32 + cbSense);
     753
     754        cmd.ID_code = ('C') | ('D' << 8) | ('0' << 16) | ('1' << 24);
     755        cmd.cmd_length = sizeof(cmd.cmd_buffer);
     756        memcpy((char *)cmd.cmd_buffer, (char *)pbCmd, 12);
     757        cmd.flags = flags;
     758        cmd.cmd_timeout = (cTimeoutMillies + 999) / 1000; // convert to seconds
     759        datalen = cmd.data_length = cbSize32;
     760
     761        printf("cmd=%02x, cbSize=%u, cbSize32=%u", *(char *)cmd.cmd_buffer & 0xff, cbSize, cbSize32);
     762
     763        switch (enmTxDir)
     764        {
     765            case PDMBLOCKTXDIR_NONE:
     766                printf(", direction: none");
     767                break;
     768
     769            case PDMBLOCKTXDIR_FROM_DEVICE:
     770                printf(", direction: from");
     771                break;
     772
     773            case PDMBLOCKTXDIR_TO_DEVICE:
     774                printf(", direction: to");
     775                break;
     776
     777            default:
     778                printf(", direction: illegal");
     779                AssertMsgFailed(("enmTxDir invalid!\n"));
     780        }
     781
     782        // copy data to ioctl data buffer
     783        if (enmTxDir == PDMBLOCKTXDIR_TO_DEVICE)
     784            memcpy(data, pBuf, cbSize32);
     785
     786        if (! (rc = DosDevIOCtl((HFILE)RTFileToNative(pThis->hFileDevice),
     787                                IOCTL_CDROMDISK, CDROMDISK_EXECMD,
     788                                &cmd, cmdlen, &cmdlen, data, datalen, &datalen)) )
     789        {
     790            printf(", success, datalen=%lu", datalen);
     791            // copy sense info
     792            memcpy(pabSense, (char *)data + cbSize32, cbSense);
     793
     794            // copy data we got from CDROM driver
     795            if ((enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE) && datalen)
     796            {
     797                printf(", direction: from\n");
     798                memcpy(pBuf, data, datalen);
     799            }
     800            else
     801                printf(", direction: to\n");
     802
     803            pBuf          += datalen;
     804            cbSize        -= datalen;
     805            cbTransferred += datalen;
     806        }
     807        else
     808            printf(", rc=%u\n", rc);
     809
     810        rc = RTErrConvertFromOS2(rc);
     811
     812    } while ((cbSize > 0) && RT_SUCCESS(rc));
     813
     814    RTMemFree(data);
     815
     816    printf("%s: bytes returned=%u\n", __FUNCTION__, cbTransferred);
     817    Log2(("%s: bytes returned=%u\n", __FUNCTION__, cbTransferred));
     818   
    634819#else
    635820# error "Unsupported platform."
    636821#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
  • src/VBox/Devices/Makefile.kmk

     
    179179        Storage/ATAPIPassthrough.cpp \
    180180        Network/DrvNetSniffer.cpp \
    181181        Network/Pcap.cpp
    182  ifn1of ($(KBUILD_TARGET), os2)
     182 #ifn1of ($(KBUILD_TARGET), )
    183183  VBoxDD_SOURCES += Storage/DrvHostBase.cpp
    184  endif
    185  ifn1of ($(KBUILD_TARGET), os2)
     184 #endif
     185 #ifn1of ($(KBUILD_TARGET), )
    186186  VBoxDD_SOURCES += Storage/DrvHostDVD.cpp
    187  endif
    188  ifn1of ($(KBUILD_TARGET), darwin freebsd os2 solaris)
     187 #endif
     188 ifn1of ($(KBUILD_TARGET), darwin freebsd solaris)
    189189  VBoxDD_SOURCES += Storage/DrvHostFloppy.cpp
    190190 endif
    191191
     
    545545   Audio/DrvHostDSound.cpp
    546546 endif
    547547
     548# VBoxDD_LIBS.os2 += poll
     549
    548550 ifeq ($(KBUILD_TARGET),linux)
    549551  VBoxDD_SOURCES += \
    550552        Audio/DrvHostOSSAudio.cpp
     
    707709        Serial/DrvHostSerial.cpp
    708710
    709711 ifeq ($(KBUILD_TARGET),os2)
     712  # VBoxDD_SOURCES += Serial/DrvHostSerial.cpp
     713  # VBoxDD_SOURCES += Parallel/DrvHostParallel.cpp
    710714  VBoxDD_SOURCES.os2 += Network/DrvTAPOs2.cpp
    711  endif
     715 endif # freebsd
    712716
    713717 ifeq ($(KBUILD_TARGET),solaris)
    714718  VBoxDD_SOURCES.solaris += Serial/DrvHostSerial.cpp
  • src/VBox/Devices/build/VBoxDD.cpp

     
    222222    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvVD);
    223223    if (RT_FAILURE(rc))
    224224        return rc;
    225 #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(RT_OS_FREEBSD)
     225#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) || defined(RT_OS_FREEBSD)
    226226    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDVD);
    227227    if (RT_FAILURE(rc))
    228228        return rc;
    229229#endif
    230 #if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
     230#if defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    231231    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostFloppy);
    232232    if (RT_FAILURE(rc))
    233233        return rc;
  • src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp

     
    5959# include <fcntl.h>
    6060# include <unistd.h>
    6161#endif
     62#ifdef RT_OS_OS2
     63# define  INCL_BASE
     64# define  INCL_DOSDEVIOCTL
     65# include <os2.h>
     66# include <stdio.h> // SEEK_END
     67#endif
    6268#ifdef RT_OS_LINUX
    6369# include <sys/utsname.h>
    6470# include <linux/hdreg.h>
     
    11921198            i++;
    11931199            pszPartitions = argv[i];
    11941200        }
    1195 #if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_WINDOWS)
     1201#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    11961202        else if (strcmp(argv[i], "-relative") == 0)
    11971203        {
    11981204            fRelative = true;
     
    12901296            vrc = VINF_SUCCESS;
    12911297        }
    12921298    }
     1299#elif defined(RT_OS_OS2)
     1300    /* parameter packet */
     1301    #pragma pack(1)
     1302    struct {
     1303        unsigned char command;
     1304        unsigned char drive;
     1305    } parm;
     1306    struct {
     1307        unsigned char command;
     1308    } parmphys;
     1309    #pragma pack()
     1310    /* data packet      */
     1311    BIOSPARAMETERBLOCK bpb;
     1312    DEVICEPARAMETERBLOCK dpb;
     1313    ULONG cbSectors;
     1314    ULONG parmlen;
     1315    ULONG datalen;
     1316    LONGLONG xrc;
     1317    APIRET ret;
     1318
     1319    if (hRawFile->type == FILE_TYPE_RAW)
     1320    {
     1321        parmlen = sizeof(parmphys);
     1322        datalen = sizeof(dpb);
     1323
     1324        memset(&dpb, 0, sizeof(dpb));
     1325
     1326        parmphys.command = 1;
     1327
     1328        ret = DosDevIOCtl((HFILE)RTFileToNative(hRawFile), IOCTL_PHYSICALDISK, PDSK_GETPHYSDEVICEPARAMS,
     1329                          &parmphys, parmlen, &parmlen,
     1330                          &dpb, datalen, &datalen);
     1331    }
     1332    else if (hRawFile->type == FILE_TYPE_DASD ||
     1333             hRawFile->type == FILE_TYPE_CD)
     1334    {
     1335        parmlen = sizeof(parm);
     1336        datalen = sizeof(bpb);
     1337
     1338        memset(&bpb, 0, sizeof(bpb));
     1339
     1340        parm.command = 1; // Return the BPB for the media currently in the drive
     1341        parm.drive = 0;   // unused
     1342
     1343        ret = DosDevIOCtl((HFILE)RTFileToNative(hRawFile), IOCTL_DISK, DSK_GETDEVICEPARAMS,
     1344                          &parm, parmlen, &parmlen,
     1345                          &bpb, datalen, &datalen);
     1346    }
     1347    //else if (hRawFile->type == FILE_TYPE_RAWFS)
     1348    //    ret = DosSetFilePtrL(RTFileToNative(hRawFile), 0, FILE_END, &xrc);
     1349
     1350    if (! ret)
     1351    {
     1352        if (hRawFile->type == FILE_TYPE_RAW)
     1353        {
     1354            cbSize = dpb.cCylinders
     1355                   * dpb.cHeads
     1356                   * dpb.cSectorsPerTrack;
     1357            cbSize <<= 9; // multiply by sector size
     1358        }
     1359        else if (bpb.bDeviceType == 5) // fixed disk
     1360        {
     1361            cbSize = bpb.cCylinders
     1362                   * bpb.cHeads
     1363                   * bpb.usSectorsPerTrack;
     1364            cbSize <<= 9; // multiply by sector size
     1365        }
     1366        //else if (hRawFile->type == FILE_TYPE_RAWFS)
     1367        //    cbSize = xrc;
     1368        else
     1369        {
     1370            RTMsgError("File '%s' is no fixed/removable medium device", rawdisk.c_str());
     1371            vrc = VERR_INVALID_PARAMETER;
     1372            goto out;
     1373        }
     1374
     1375        if (fRelative)
     1376        {
     1377            RTMsgError("The -relative parameter is invalid for raw disk %s", rawdisk.c_str());
     1378            vrc = VERR_INVALID_PARAMETER;
     1379            goto out;
     1380        }
     1381    }
     1382    else
     1383    {
     1384        /*
     1385         * Could be raw image, remember error code and try to get the size first
     1386         * before failing.
     1387         */
     1388        vrc = RTErrConvertFromOS2(ret);
     1389        if (RT_FAILURE(RTFileGetSize(hRawFile, &cbSize)))
     1390        {
     1391            RTMsgError("Cannot get the geometry of the raw disk '%s': %Rrc", rawdisk.c_str(), vrc);
     1392            goto out;
     1393        }
     1394        else
     1395        {
     1396            if (fRelative)
     1397            {
     1398                RTMsgError("The -relative parameter is invalid for raw images");
     1399                vrc = VERR_INVALID_PARAMETER;
     1400                goto out;
     1401            }
     1402            vrc = VINF_SUCCESS;
     1403        }
     1404    }
    12931405#elif defined(RT_OS_LINUX)
    12941406    struct stat DevStat;
    12951407    if (!fstat(RTFileToNative(hRawFile), &DevStat))