Ticket #45: host-cdflop-upd.diff
File host-cdflop-upd.diff, 56.4 KB (added by , 8 years ago) |
---|
-
include/iprt/file.h
47 47 # define RTFILE_LINEFEED "\n" 48 48 #endif 49 49 50 #ifdef RT_OS_OS2 51 /* internal file handle structure */ 52 #pragma pack (1) 53 struct 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 50 71 /** Platform specific native standard input "handle". */ 51 72 #ifdef RT_OS_WINDOWS 52 73 # define RTFILE_NATIVE_STDIN ((uint32_t)-10) -
src/VBox/Runtime/r3/posix/fileio-posix.cpp
45 45 #ifdef RT_OS_LINUX 46 46 # include <sys/file.h> 47 47 #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 50 65 #endif 51 66 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) 52 67 # include <sys/disk.h> … … 61 76 #include <iprt/path.h> 62 77 #include <iprt/assert.h> 63 78 #include <iprt/string.h> 79 #include <iprt/mem.h> 64 80 #include <iprt/err.h> 65 81 #include <iprt/log.h> 66 82 #include "internal/file.h" … … 98 114 return fRc; 99 115 } 100 116 117 #ifdef RT_OS_OS2 118 // check if the driveletter is cdrom one 119 static bool rtOs2IsCdRom(const char *pszFilename) 120 { 121 typedef struct _CDROMDeviceMap 122 { 123 USHORT usDriveCount; 124 USHORT usFirstLetter; 125 } CDROMDeviceMap; 101 126 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 154 static 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 317 static 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 462 static 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 684 static 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 102 919 RTR3DECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen) 103 920 { 104 921 /* … … 108 925 *pFile = NIL_RTFILE; 109 926 AssertPtrReturn(pszFilename, VERR_INVALID_POINTER); 110 927 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 111 935 /* 112 936 * Merge forced open flags and validate them. 113 937 */ … … 202 1026 if (RT_FAILURE(rc)) 203 1027 return (rc); 204 1028 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 206 1034 int iErr = errno; 1035 fh = RTFileToNative(*pFile); 207 1036 1037 if (RT_FAILURE(ret) && ret != -1) 1038 return ret; 1039 #else 1040 fh = open(pszNativeFilename, fOpenMode, fMode); 1041 iErr = errno; 1042 #endif 1043 208 1044 #ifdef O_CLOEXEC 209 1045 if ( (fOpenMode & O_CLOEXEC) 210 1046 && s_fHave_O_CLOEXEC == 0) … … 216 1052 iErr = errno; 217 1053 } 218 1054 else if (fh >= 0) 1055 { 219 1056 s_fHave_O_CLOEXEC = fcntl(fh, F_GETFD, 0) > 0 ? 1 : -1; 1057 } 220 1058 } 221 1059 #endif 222 1060 … … 328 1166 */ 329 1167 if (iErr == 0) 330 1168 { 331 *pFile = (RTFILE)(uintptr_t)fh; 332 Assert((intptr_t)*pFile == fh); 1169 RTFileFromNative(pFile, fh); 333 1170 LogFlow(("RTFileOpen(%p:{%RTfile}, %p:{%s}, %#llx): returns %Rrc\n", 334 1171 pFile, *pFile, pszFilename, pszFilename, fOpen, rc)); 335 1172 return VINF_SUCCESS; … … 337 1174 338 1175 close(fh); 339 1176 } 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 340 1182 return RTErrConvertFromErrno(iErr); 341 1183 } 342 1184 … … 355 1197 { 356 1198 if (hFile == NIL_RTFILE) 357 1199 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 358 1234 if (close(RTFileToNative(hFile)) == 0) 1235 { 1236 #ifdef RT_OS_OS2 1237 RTMemFree(hFile); 1238 #endif 359 1239 return VINF_SUCCESS; 1240 } 360 1241 return RTErrConvertFromErrno(errno); 361 1242 } 362 1243 363 1244 364 1245 RTR3DECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative) 365 1246 { 1247 #ifndef RT_OS_OS2 366 1248 AssertCompile(sizeof(uNative) == sizeof(*pFile)); 1249 #endif 367 1250 if (uNative < 0) 368 1251 { 369 1252 AssertMsgFailed(("%p\n", uNative)); 370 1253 *pFile = NIL_RTFILE; 371 1254 return VERR_INVALID_HANDLE; 372 1255 } 1256 #ifdef RT_OS_OS2 1257 (*pFile)->hFile = uNative; 1258 #else 373 1259 *pFile = (RTFILE)uNative; 1260 #endif 374 1261 return VINF_SUCCESS; 375 1262 } 376 1263 … … 378 1265 RTR3DECL(RTHCINTPTR) RTFileToNative(RTFILE hFile) 379 1266 { 380 1267 AssertReturn(hFile != NIL_RTFILE, -1); 1268 #ifdef RT_OS_OS2 1269 return (intptr_t)hFile->hFile; 1270 #else 381 1271 return (intptr_t)hFile; 1272 #endif 382 1273 } 383 1274 384 1275 … … 415 1306 return rc; 416 1307 } 417 1308 418 419 1309 RTR3DECL(int) RTFileSeek(RTFILE hFile, int64_t offSeek, unsigned uMethod, uint64_t *poffActual) 420 1310 { 421 1311 static const unsigned aSeekRecode[] = … … 443 1333 return VERR_NOT_SUPPORTED; 444 1334 } 445 1335 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 447 1346 if (offCurrent != ~0) 448 1347 { 449 1348 if (poffActual) 450 1349 *poffActual = (uint64_t)offCurrent; 451 1350 return VINF_SUCCESS; 452 1351 } 453 return RTErrConvertFromErrno(errno);1352 return ret; 454 1353 } 455 1354 456 457 1355 RTR3DECL(int) RTFileRead(RTFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead) 458 1356 { 459 1357 if (cbToRead <= 0) … … 462 1360 /* 463 1361 * Attempt read. 464 1362 */ 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); 466 1368 if (cbRead >= 0) 1369 #endif 467 1370 { 468 1371 if (pcbRead) 469 1372 /* caller can handle partial read. */ … … 473 1376 /* Caller expects all to be read. */ 474 1377 while ((ssize_t)cbToRead > cbRead) 475 1378 { 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); 477 1391 if (cbReadPart <= 0) 478 1392 { 479 1393 if (cbReadPart == 0) 480 1394 return VERR_EOF; 481 1395 return RTErrConvertFromErrno(errno); 482 1396 } 1397 #endif 483 1398 cbRead += cbReadPart; 484 1399 } 485 1400 } … … 498 1413 /* 499 1414 * Attempt write. 500 1415 */ 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); 502 1421 if (cbWritten >= 0) 1422 #endif 503 1423 { 504 1424 if (pcbWritten) 505 1425 /* caller can handle partial write. */ … … 509 1429 /* Caller expects all to be write. */ 510 1430 while ((ssize_t)cbToWrite > cbWritten) 511 1431 { 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); 513 1440 if (cbWrittenPart <= 0) 514 1441 return RTErrConvertFromErrno(errno); 1442 #endif 515 1443 cbWritten += cbWrittenPart; 516 1444 } 517 1445 } … … 675 1603 676 1604 RTR3DECL(int) RTFileFlush(RTFILE hFile) 677 1605 { 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 678 1611 if (fsync(RTFileToNative(hFile))) 679 1612 return RTErrConvertFromErrno(errno); 680 1613 return VINF_SUCCESS; -
src/VBox/Devices/Storage/DrvHostBase.cpp
96 96 /*IN*/ ULONG Length, 97 97 /*IN*/ FS_INFORMATION_CLASS FileSystemInformationClass ); 98 98 99 #elif defined(RT_OS_OS2) 100 # define OS2EMX_PLAIN_CHAR 101 # define INCL_BASE 102 # define INCL_DOSDEVIOCTL 103 # include <os2.h> 99 104 #elif defined(RT_OS_FREEBSD) 100 105 # include <sys/cdefs.h> 101 106 # include <sys/param.h> … … 1128 1133 } 1129 1134 RTFILE hFileRawDevice; 1130 1135 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); 1131 1143 #else 1132 1144 int rc = drvHostBaseOpen(pThis, &hFileDevice, pThis->fReadOnlyConfig); 1133 1145 #endif … … 2041 2053 pThis->fAttachFailError = fAttachFailError; 2042 2054 2043 2055 /* name to open & watch for */ 2044 #if def RT_OS_WINDOWS2056 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 2045 2057 int iBit = RT_C_TO_UPPER(pThis->pszDevice[0]) - 'A'; 2046 2058 if ( iBit > 'Z' - 'A' 2047 2059 || pThis->pszDevice[1] != ':' … … 2051 2063 return VERR_INVALID_PARAMETER; 2052 2064 } 2053 2065 pThis->fUnitMask = 1 << iBit; 2066 #if defined(RT_OS_WINDOWS) 2054 2067 RTStrAPrintf(&pThis->pszDeviceOpen, "\\\\.\\%s", pThis->pszDevice); 2068 #else 2069 RTStrAPrintf(&pThis->pszDeviceOpen, "%s", pThis->pszDevice); 2070 #endif 2055 2071 2056 2072 #elif defined(RT_OS_SOLARIS) 2057 2073 char *pszBlockDevName = getfullblkname(pThis->pszDevice); … … 2199 2215 } 2200 2216 } 2201 2217 } 2202 #if def RT_OS_WINDOWS2218 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 2203 2219 if (RT_SUCCESS(src)) 2204 2220 DRVHostBaseMediaPresent(pThis); 2205 2221 #endif -
src/VBox/Devices/Storage/DrvHostDVD.cpp
86 86 # undef _interlockedbittestandreset64 87 87 # undef USE_MEDIA_POLLING 88 88 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 89 96 #elif defined(RT_OS_FREEBSD) 90 97 # include <sys/cdefs.h> 91 98 # include <sys/param.h> … … 106 113 #include <iprt/string.h> 107 114 #include <iprt/thread.h> 108 115 #include <iprt/critsect.h> 116 #include <iprt/mem.h> 109 117 #include <VBox/scsi.h> 110 118 111 119 #include "VBoxDD.h" … … 202 210 AssertMsgFailed(("Failed to open '%s' for ejecting this tray.\n", rc)); 203 211 204 212 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); 205 224 #else 206 225 AssertMsgFailed(("Eject is not implemented!\n")); 207 226 rc = VINF_SUCCESS; … … 280 299 /** @todo figure out the return codes for already locked. */ 281 300 rc = RTErrConvertFromWin32(GetLastError()); 282 301 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); 283 324 #else 284 325 AssertMsgFailed(("Lock/Unlock is not implemented!\n")); 285 326 int rc = VINF_SUCCESS; … … 631 672 rc = RTErrConvertFromWin32(GetLastError()); 632 673 Log2(("%s: scsistatus=%d bytes returned=%d tlength=%d\n", __FUNCTION__, Req.spt.ScsiStatus, cbReturned, Req.spt.DataTransferLength)); 633 674 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 634 819 #else 635 820 # error "Unsupported platform." 636 821 #endif -
src/VBox/Devices/Storage/DrvHostFloppy.cpp
28 28 # include <sys/fcntl.h> 29 29 # include <errno.h> 30 30 31 # 31 #elif defined(RT_OS_WINDOWS) 32 32 # include <windows.h> 33 33 # include <dbt.h> 34 34 35 #elif defined(RT_OS_OS2) 36 # define INCL_BASE 37 # define INCL_DOSDEVIOCTL 38 # include <os2.h> 35 39 #elif defined(RT_OS_L4) 36 40 37 41 #else /* !RT_OS_WINDOWS nor RT_OS_LINUX nor RT_OS_L4 */ … … 101 105 } 102 106 #endif /* RT_OS_WINDOWS */ 103 107 108 #ifdef RT_OS_OS2 109 110 /* parameter packet */ 111 #pragma pack(1) 112 struct 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 */ 123 static 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 104 158 #ifdef RT_OS_LINUX 105 159 /** 106 160 * Get media size and do change processing. … … 198 252 /* 199 253 * Override stuff. 200 254 */ 201 #if def RT_OS_WINDOWS255 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 202 256 pThis->Base.pfnGetMediaSize = drvHostFloppyGetMediaSize; 203 257 #endif 204 258 #ifdef RT_OS_LINUX -
src/VBox/Devices/Storage/DrvHostBase.h
129 129 /** The unit mask. */ 130 130 DWORD fUnitMask; 131 131 #endif 132 #ifdef RT_OS_OS2 133 /** The unit mask. */ 134 ULONG fUnitMask; 135 #endif 132 136 133 137 #ifdef RT_OS_LINUX 134 138 /** Double buffer required for ioctl with the Linux kernel as long as we use -
src/VBox/Devices/Makefile.kmk
179 179 Storage/ATAPIPassthrough.cpp \ 180 180 Network/DrvNetSniffer.cpp \ 181 181 Network/Pcap.cpp 182 ifn1of ($(KBUILD_TARGET), os2)182 #ifn1of ($(KBUILD_TARGET), ) 183 183 VBoxDD_SOURCES += Storage/DrvHostBase.cpp 184 endif185 ifn1of ($(KBUILD_TARGET), os2)184 #endif 185 #ifn1of ($(KBUILD_TARGET), ) 186 186 VBoxDD_SOURCES += Storage/DrvHostDVD.cpp 187 endif188 ifn1of ($(KBUILD_TARGET), darwin freebsd os2solaris)187 #endif 188 ifn1of ($(KBUILD_TARGET), darwin freebsd solaris) 189 189 VBoxDD_SOURCES += Storage/DrvHostFloppy.cpp 190 190 endif 191 191 … … 545 545 Audio/DrvHostDSound.cpp 546 546 endif 547 547 548 # VBoxDD_LIBS.os2 += poll 549 548 550 ifeq ($(KBUILD_TARGET),linux) 549 551 VBoxDD_SOURCES += \ 550 552 Audio/DrvHostOSSAudio.cpp … … 707 709 Serial/DrvHostSerial.cpp 708 710 709 711 ifeq ($(KBUILD_TARGET),os2) 712 # VBoxDD_SOURCES += Serial/DrvHostSerial.cpp 713 # VBoxDD_SOURCES += Parallel/DrvHostParallel.cpp 710 714 VBoxDD_SOURCES.os2 += Network/DrvTAPOs2.cpp 711 endif 715 endif # freebsd 712 716 713 717 ifeq ($(KBUILD_TARGET),solaris) 714 718 VBoxDD_SOURCES.solaris += Serial/DrvHostSerial.cpp -
src/VBox/Devices/build/VBoxDD.cpp
222 222 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvVD); 223 223 if (RT_FAILURE(rc)) 224 224 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) 226 226 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDVD); 227 227 if (RT_FAILURE(rc)) 228 228 return rc; 229 229 #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) 231 231 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostFloppy); 232 232 if (RT_FAILURE(rc)) 233 233 return rc; -
src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp
59 59 # include <fcntl.h> 60 60 # include <unistd.h> 61 61 #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 62 68 #ifdef RT_OS_LINUX 63 69 # include <sys/utsname.h> 64 70 # include <linux/hdreg.h> … … 1192 1198 i++; 1193 1199 pszPartitions = argv[i]; 1194 1200 } 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) 1196 1202 else if (strcmp(argv[i], "-relative") == 0) 1197 1203 { 1198 1204 fRelative = true; … … 1290 1296 vrc = VINF_SUCCESS; 1291 1297 } 1292 1298 } 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 } 1293 1405 #elif defined(RT_OS_LINUX) 1294 1406 struct stat DevStat; 1295 1407 if (!fstat(RTFileToNative(hRawFile), &DevStat))