| 1 | /* | 
|---|
| 2 | * OS2CDROM.DMD interface for sending SCSI commands | 
|---|
| 3 | * | 
|---|
| 4 | * Based on example code by: | 
|---|
| 5 | *      (c) 2001 S&T Systemtechnik GmbH | 
|---|
| 6 | * | 
|---|
| 7 | *      erzeugt:        15.02.01        R.Ihle | 
|---|
| 8 | * | 
|---|
| 9 | * Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 10 | * | 
|---|
| 11 | */ | 
|---|
| 12 |  | 
|---|
| 13 | #define INCL_NOPMAPI | 
|---|
| 14 | #define INCL_DOSDEVICES | 
|---|
| 15 | #define INCL_DOSDEVIOCTL | 
|---|
| 16 | #define INCL_DOSFILEMGR | 
|---|
| 17 | #define INCL_DOSMISC | 
|---|
| 18 | #include <os2wrap.h> | 
|---|
| 19 |  | 
|---|
| 20 | #include "cdioctl.h" | 
|---|
| 21 |  | 
|---|
| 22 | #include <stdio.h> | 
|---|
| 23 | #include <stdlib.h> | 
|---|
| 24 | #include <string.h> | 
|---|
| 25 | #include <malloc.h> | 
|---|
| 26 |  | 
|---|
| 27 | #include "cdio.h" | 
|---|
| 28 | #include <win32type.h> | 
|---|
| 29 | #include <dbglog.h> | 
|---|
| 30 |  | 
|---|
| 31 |  | 
|---|
| 32 | //needed for high memory support check (kernel32) | 
|---|
| 33 | DWORD SYSTEM OSLibDosDevIOCtl( DWORD hFile, DWORD dwCat, DWORD dwFunc, | 
|---|
| 34 | PVOID pParm, DWORD dwParmMaxLen, DWORD *pdwParmLen, | 
|---|
| 35 | PVOID pData, DWORD dwDataMaxLen, DWORD *pdwDataLen); | 
|---|
| 36 |  | 
|---|
| 37 |  | 
|---|
| 38 | static ULONG ulDriveList            = 0; | 
|---|
| 39 | static ULONG nrCDROMDrives          = 0; | 
|---|
| 40 | static HCDIO hCDHandles[MAX_DRIVES] = {0}; | 
|---|
| 41 | static int   ulCDDriveNr[MAX_DRIVES] = {0}; | 
|---|
| 42 |  | 
|---|
| 43 | //----------------------------------------------------------------------// | 
|---|
| 44 | //      Initialize CD/DVD drive access                                  // | 
|---|
| 45 | //----------------------------------------------------------------------// | 
|---|
| 46 |  | 
|---|
| 47 | BOOL OSLibCdIoInitialize(void) | 
|---|
| 48 | { | 
|---|
| 49 | ULONG ulAction, ulFeatures; | 
|---|
| 50 | int   fResult = 0; | 
|---|
| 51 | HFILE hDev; | 
|---|
| 52 |  | 
|---|
| 53 | if( DosOpen("CD-ROM2$", &hDev, &ulAction, 0, FILE_NORMAL, | 
|---|
| 54 | OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, | 
|---|
| 55 | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | | 
|---|
| 56 | OPEN_FLAGS_FAIL_ON_ERROR, NULL) == 0 ) | 
|---|
| 57 | { | 
|---|
| 58 | fResult = DosDevIOCtl(hDev, IOCTL_CDROMDISK2, CDROMDISK2_FEATURES, | 
|---|
| 59 | NULL, 0, NULL, &ulFeatures, sizeof(ulFeatures), NULL) == 0 && | 
|---|
| 60 | (ulFeatures & FEATURE_EXECMD_SUPPORT); | 
|---|
| 61 |  | 
|---|
| 62 | DosClose(hDev); | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | ulDriveList = OSLibCdIoQueryDriveList(); | 
|---|
| 66 | return fResult; | 
|---|
| 67 | } | 
|---|
| 68 |  | 
|---|
| 69 |  | 
|---|
| 70 | //----------------------------------------------------------------------// | 
|---|
| 71 | //      Unload ASPI manager                                             // | 
|---|
| 72 | //----------------------------------------------------------------------// | 
|---|
| 73 |  | 
|---|
| 74 | BOOL OSLibCdIoTerminate(void) | 
|---|
| 75 | { | 
|---|
| 76 | for(int i=0;i<MAX_DRIVES;i++) { | 
|---|
| 77 | if(hCDHandles[i]) { | 
|---|
| 78 | DosClose(hCDHandles[i]); | 
|---|
| 79 | hCDHandles[i] = 0; | 
|---|
| 80 | } | 
|---|
| 81 | } | 
|---|
| 82 | return 1; | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 |  | 
|---|
| 86 | //----------------------------------------------------------------------// | 
|---|
| 87 | //      Open drive                                                      // | 
|---|
| 88 | //----------------------------------------------------------------------// | 
|---|
| 89 |  | 
|---|
| 90 | BOOL OSLibCdIoIsSupported(HFILE hDisk) | 
|---|
| 91 | { | 
|---|
| 92 | ULONG ulAction, ulCDSig; | 
|---|
| 93 |  | 
|---|
| 94 | ulCDSig = ('C') | ('D' << 8) | ('9' << 16) | ('9' << 24); | 
|---|
| 95 |  | 
|---|
| 96 | if(OSLibCdIoInitialize() == FALSE) { | 
|---|
| 97 | return FALSE; | 
|---|
| 98 | } | 
|---|
| 99 |  | 
|---|
| 100 | if(DosDevIOCtl(hDisk, IOCTL_CDROMDISK, CDROMDISK_GETDRIVER, &ulCDSig, sizeof(ulCDSig), NULL, | 
|---|
| 101 | &ulCDSig, sizeof(ulCDSig), NULL) == 0 && | 
|---|
| 102 | ulCDSig == (('C') | ('D' << 8) | ('0' << 16) | ('1' << 24)) ) | 
|---|
| 103 | { | 
|---|
| 104 | return TRUE; | 
|---|
| 105 | } | 
|---|
| 106 | return FALSE; | 
|---|
| 107 | } | 
|---|
| 108 |  | 
|---|
| 109 | //----------------------------------------------------------------------// | 
|---|
| 110 | //      Return nr of available CDROM or DVD drives | 
|---|
| 111 | //----------------------------------------------------------------------// | 
|---|
| 112 | int OSLibCdIoGetNumDrives() | 
|---|
| 113 | { | 
|---|
| 114 | return min(nrCDROMDrives, MAX_DRIVES); | 
|---|
| 115 | } | 
|---|
| 116 |  | 
|---|
| 117 | //----------------------------------------------------------------------// | 
|---|
| 118 | //      Open cdrom drive | 
|---|
| 119 | //----------------------------------------------------------------------// | 
|---|
| 120 |  | 
|---|
| 121 | HCDIO OSLibCdIoGetDevice(int SRB_HaId, int SRB_Target, int SRB_Lun) | 
|---|
| 122 | { | 
|---|
| 123 | HFILE               hDisk; | 
|---|
| 124 | ULONG               ulAction, ulCDSig; | 
|---|
| 125 | char        pszDisk[4]; | 
|---|
| 126 |  | 
|---|
| 127 | if(SRB_HaId != 0 || SRB_Lun != 0 || SRB_Target > (nrCDROMDrives - 1)) { | 
|---|
| 128 | return (HCDIO) -1; | 
|---|
| 129 | } | 
|---|
| 130 |  | 
|---|
| 131 | if(hCDHandles[SRB_Target]) { | 
|---|
| 132 | return hCDHandles[SRB_Target]; | 
|---|
| 133 | } | 
|---|
| 134 | pszDisk[0] = 'A' + ulCDDriveNr[SRB_Target]; | 
|---|
| 135 | pszDisk[1] = ':'; | 
|---|
| 136 | pszDisk[2] = 0; | 
|---|
| 137 |  | 
|---|
| 138 | //?? readwrite for cd writers? | 
|---|
| 139 | if( DosOpen(pszDisk, &hDisk, | 
|---|
| 140 | &ulAction, 0, FILE_NORMAL, | 
|---|
| 141 | OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, | 
|---|
| 142 | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | | 
|---|
| 143 | OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR, NULL) == 0 ) | 
|---|
| 144 | { | 
|---|
| 145 | ulCDSig = ('C') | ('D' << 8) | ('9' << 16) | ('9' << 24); | 
|---|
| 146 |  | 
|---|
| 147 | if( DosDevIOCtl(hDisk, IOCTL_CDROMDISK, CDROMDISK_GETDRIVER, | 
|---|
| 148 | &ulCDSig, sizeof(ulCDSig), NULL, | 
|---|
| 149 | &ulCDSig, sizeof(ulCDSig), NULL) == 0 && | 
|---|
| 150 | ulCDSig == (('C') | ('D' << 8) | ('0' << 16) | ('1' << 24)) ) | 
|---|
| 151 | { | 
|---|
| 152 | hCDHandles[SRB_Target] = hDisk; | 
|---|
| 153 | return (HCDIO)hDisk; | 
|---|
| 154 | } | 
|---|
| 155 |  | 
|---|
| 156 | DosClose(hDisk); | 
|---|
| 157 | } | 
|---|
| 158 | return (HCDIO)-1; | 
|---|
| 159 | } | 
|---|
| 160 |  | 
|---|
| 161 | //----------------------------------------------------------------------// | 
|---|
| 162 | //      Send command to drive                                           // | 
|---|
| 163 | //----------------------------------------------------------------------// | 
|---|
| 164 |  | 
|---|
| 165 | BOOL OSLibCdIoSendCommand(HCDIO hCdIo, CDIO_CMD_BUFFER *pCmdBuf, void *pData, unsigned cbData) | 
|---|
| 166 | { | 
|---|
| 167 | struct ExecCmd      Param; | 
|---|
| 168 | ULONG                       ulDummy, ParmLen, DataLen; | 
|---|
| 169 |  | 
|---|
| 170 | if( !pData || !cbData ) | 
|---|
| 171 | { | 
|---|
| 172 | ulDummy = 0;  pData = &ulDummy;  cbData = sizeof(ulDummy); | 
|---|
| 173 | } | 
|---|
| 174 |  | 
|---|
| 175 | Param.ID_code     = 'C' | ('D'<<8) | ('0'<<16) | ('1'<<24); | 
|---|
| 176 | Param.data_length = (USHORT)cbData; | 
|---|
| 177 | Param.cmd_length  = pCmdBuf->cbCDB; | 
|---|
| 178 | Param.flags       = (USHORT) | 
|---|
| 179 | (( pCmdBuf->flDirection & 1 ) ? EX_DIRECTION_IN : 0); | 
|---|
| 180 | memcpy(Param.cmd_buffer, pCmdBuf->arCDB, sizeof(Param.cmd_buffer)); | 
|---|
| 181 |  | 
|---|
| 182 |  | 
|---|
| 183 | ParmLen = sizeof(Param); | 
|---|
| 184 | DataLen = cbData; | 
|---|
| 185 | return OSLibDosDevIOCtl((HFILE)hCdIo, IOCTL_CDROMDISK, CDROMDISK_EXECMD, | 
|---|
| 186 | &Param, ParmLen, &ParmLen, pData, cbData, &DataLen) == 0; | 
|---|
| 187 | } | 
|---|
| 188 |  | 
|---|
| 189 |  | 
|---|
| 190 | //----------------------------------------------------------------------// | 
|---|
| 191 | //      Load / Eject disk                                               // | 
|---|
| 192 | //----------------------------------------------------------------------// | 
|---|
| 193 |  | 
|---|
| 194 | BOOL OSLibCdIoLoadEjectDisk(HCDIO hCdIo, int fLoad) | 
|---|
| 195 | { | 
|---|
| 196 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 197 |  | 
|---|
| 198 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 199 | CmdBuf.flDirection = CMDDIR_OUTPUT; | 
|---|
| 200 | CmdBuf.cbCDB       = 6; | 
|---|
| 201 | CmdBuf.arCDB[0]    = 0x1b;          // START STOP UNIT command | 
|---|
| 202 | CmdBuf.arCDB[4]    = (unsigned char)(( fLoad ) ?  0x03 : 0x02); | 
|---|
| 203 | // Bit 1: 0:Start/Stop, 1:Load/Eject | 
|---|
| 204 | // Bit 0: 0:Stop/Eject, 1:Start/Load | 
|---|
| 205 | return OSLibCdIoSendCommand(hCdIo, &CmdBuf, NULL, 0); | 
|---|
| 206 | } | 
|---|
| 207 |  | 
|---|
| 208 |  | 
|---|
| 209 | //----------------------------------------------------------------------// | 
|---|
| 210 | //      Test drive readyness                                            // | 
|---|
| 211 | //----------------------------------------------------------------------// | 
|---|
| 212 |  | 
|---|
| 213 | BOOL OSLibCdIoUnitReady(HCDIO hCdIo) | 
|---|
| 214 | { | 
|---|
| 215 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 216 |  | 
|---|
| 217 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 218 | CmdBuf.flDirection = CMDDIR_OUTPUT; | 
|---|
| 219 | CmdBuf.cbCDB       = 6; | 
|---|
| 220 | //  CmdBuf.arCDB[0]    = 0x00;          // TEST UNIT READY command | 
|---|
| 221 |  | 
|---|
| 222 | return OSLibCdIoSendCommand(hCdIo, &CmdBuf, NULL, 0); | 
|---|
| 223 | } | 
|---|
| 224 |  | 
|---|
| 225 |  | 
|---|
| 226 | //----------------------------------------------------------------------// | 
|---|
| 227 | //      Reset drive                                                     // | 
|---|
| 228 | //----------------------------------------------------------------------// | 
|---|
| 229 |  | 
|---|
| 230 | BOOL OSLibCdIoResetUnit(HCDIO hCdIo) | 
|---|
| 231 | { | 
|---|
| 232 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 233 |  | 
|---|
| 234 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 235 | CmdBuf.flDirection = CMDDIR_OUTPUT; | 
|---|
| 236 | CmdBuf.cbCDB       = 6; | 
|---|
| 237 | CmdBuf.arCDB[0]    = 0x01;          // REZERO command | 
|---|
| 238 |  | 
|---|
| 239 | return OSLibCdIoSendCommand(hCdIo, &CmdBuf, NULL, 0); | 
|---|
| 240 | } | 
|---|
| 241 |  | 
|---|
| 242 |  | 
|---|
| 243 | //----------------------------------------------------------------------// | 
|---|
| 244 | //      Query information about drive                                   // | 
|---|
| 245 | //----------------------------------------------------------------------// | 
|---|
| 246 |  | 
|---|
| 247 | BOOL OSLibCdIoInquiry(HCDIO hCdIo, unsigned uPageCode, void *pData, unsigned cbData) | 
|---|
| 248 | { | 
|---|
| 249 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 250 |  | 
|---|
| 251 | if( cbData > 255 )  cbData = 255; | 
|---|
| 252 |  | 
|---|
| 253 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 254 | CmdBuf.flDirection = CMDDIR_INPUT; | 
|---|
| 255 | CmdBuf.cbCDB       = 6; | 
|---|
| 256 | CmdBuf.arCDB[0]    = 0x12;          // INQUIRY CAPACITY command | 
|---|
| 257 | CmdBuf.arCDB[4]    = (unsigned char)cbData; | 
|---|
| 258 |  | 
|---|
| 259 | if( uPageCode ) | 
|---|
| 260 | { | 
|---|
| 261 | CmdBuf.arCDB[1]  = 1;           // enable vital product data | 
|---|
| 262 | CmdBuf.arCDB[2]  = (unsigned char)uPageCode; | 
|---|
| 263 | } | 
|---|
| 264 |  | 
|---|
| 265 | return OSLibCdIoSendCommand(hCdIo, &CmdBuf, pData, cbData); | 
|---|
| 266 | } | 
|---|
| 267 |  | 
|---|
| 268 |  | 
|---|
| 269 | //----------------------------------------------------------------------// | 
|---|
| 270 | //      Query sense information                                         // | 
|---|
| 271 | //----------------------------------------------------------------------// | 
|---|
| 272 |  | 
|---|
| 273 | BOOL OSLibCdIoRequestSense(HCDIO hCdIo, void *pData, unsigned cbData) | 
|---|
| 274 | { | 
|---|
| 275 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 276 |  | 
|---|
| 277 | if( cbData > 255 )  cbData = 255; | 
|---|
| 278 |  | 
|---|
| 279 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 280 | CmdBuf.flDirection = CMDDIR_INPUT; | 
|---|
| 281 | CmdBuf.cbCDB       = 6; | 
|---|
| 282 | CmdBuf.arCDB[0]    = 0x03;          // REQUEST SENSE command | 
|---|
| 283 | CmdBuf.arCDB[4]    = (unsigned char)cbData; | 
|---|
| 284 |  | 
|---|
| 285 | return OSLibCdIoSendCommand(hCdIo, &CmdBuf, pData, cbData); | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 |  | 
|---|
| 289 | //----------------------------------------------------------------------// | 
|---|
| 290 | //      Query disc capacity                                             // | 
|---|
| 291 | //----------------------------------------------------------------------// | 
|---|
| 292 |  | 
|---|
| 293 | BOOL OSLibCdIoQueryCapacity(HCDIO hCdIo, unsigned *pctBlocks, unsigned *pcbBlock) | 
|---|
| 294 | { | 
|---|
| 295 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 296 | unsigned            arResult[2]; | 
|---|
| 297 |  | 
|---|
| 298 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 299 | CmdBuf.flDirection = CMDDIR_INPUT; | 
|---|
| 300 | CmdBuf.cbCDB       = 10; | 
|---|
| 301 | CmdBuf.arCDB[0]    = 0x25;          // READ CAPACITY command | 
|---|
| 302 |  | 
|---|
| 303 | if( OSLibCdIoSendCommand(hCdIo, &CmdBuf, arResult, sizeof(arResult)) ) | 
|---|
| 304 | { | 
|---|
| 305 | *pctBlocks = (arResult[0] << 24) | | 
|---|
| 306 | ((arResult[0] & 0x0000ff00) << 8) | | 
|---|
| 307 | ((arResult[0] & 0x00ff0000) >> 8) | | 
|---|
| 308 | (arResult[0] >> 24); | 
|---|
| 309 |  | 
|---|
| 310 | *pcbBlock =  (arResult[1] << 24) | | 
|---|
| 311 | ((arResult[1] & 0x0000ff00) << 8) | | 
|---|
| 312 | ((arResult[1] & 0x00ff0000) >> 8) | | 
|---|
| 313 | (arResult[1] >> 24); | 
|---|
| 314 |  | 
|---|
| 315 | return 1; | 
|---|
| 316 | } | 
|---|
| 317 |  | 
|---|
| 318 | return 0; | 
|---|
| 319 | } | 
|---|
| 320 |  | 
|---|
| 321 |  | 
|---|
| 322 | //----------------------------------------------------------------------// | 
|---|
| 323 | //      Read data                                                       // | 
|---|
| 324 | //----------------------------------------------------------------------// | 
|---|
| 325 |  | 
|---|
| 326 | BOOL OSLibCdIoReadBlock(HCDIO hCdIo, unsigned uLBA, void *pData, unsigned cbData) | 
|---|
| 327 | { | 
|---|
| 328 | CDIO_CMD_BUFFER     CmdBuf; | 
|---|
| 329 |  | 
|---|
| 330 | memset(&CmdBuf, 0, sizeof(CmdBuf)); | 
|---|
| 331 | CmdBuf.flDirection = CMDDIR_INPUT; | 
|---|
| 332 | CmdBuf.cbCDB       = 10; | 
|---|
| 333 | //  CmdBuf.arCDB[0]    = 0x3e;          // READ LONG command MODE SELECT ??? | 
|---|
| 334 | //  CmdBuf.arCDB[1]    = 0x02;          // Bit 1: perform ECC | 
|---|
| 335 |  | 
|---|
| 336 | CmdBuf.arCDB[0]    = 0x28;          // READ command | 
|---|
| 337 | CmdBuf.arCDB[2]    = (unsigned char)(uLBA >> 24); | 
|---|
| 338 | CmdBuf.arCDB[3]    = (unsigned char)(uLBA >> 16); | 
|---|
| 339 | CmdBuf.arCDB[4]    = (unsigned char)(uLBA >> 8); | 
|---|
| 340 | CmdBuf.arCDB[5]    = (unsigned char)(uLBA); | 
|---|
| 341 | CmdBuf.arCDB[7]    = 0; | 
|---|
| 342 | CmdBuf.arCDB[8]    = 1; | 
|---|
| 343 |  | 
|---|
| 344 | return ( cbData > 2047 ) ? OSLibCdIoSendCommand(hCdIo, &CmdBuf, pData, cbData) : 0; | 
|---|
| 345 | } | 
|---|
| 346 |  | 
|---|
| 347 |  | 
|---|
| 348 | //----------------------------------------------------------------------// | 
|---|
| 349 | //      Query bit mask of all CD drives                                 // | 
|---|
| 350 | //----------------------------------------------------------------------// | 
|---|
| 351 |  | 
|---|
| 352 | ULONG OSLibCdIoQueryDriveList(void) | 
|---|
| 353 | { | 
|---|
| 354 | BIOSPARAMETERBLOCK    BPB; | 
|---|
| 355 | HFILE                       hDev; | 
|---|
| 356 | struct DrvInfo      CDInfo; | 
|---|
| 357 | ULONG                       ulAction, ulParam, uDriveMap = 0; | 
|---|
| 358 |  | 
|---|
| 359 | if( DosOpen("CD-ROM2$", &hDev, &ulAction, 0, FILE_NORMAL, | 
|---|
| 360 | OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW, | 
|---|
| 361 | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE | | 
|---|
| 362 | OPEN_FLAGS_FAIL_ON_ERROR, NULL) == 0 ) | 
|---|
| 363 | { | 
|---|
| 364 | if( DosDevIOCtl(hDev, IOCTL_CDROMDISK2, CDROMDISK2_DRVINFO, | 
|---|
| 365 | NULL, 0, NULL, &CDInfo, sizeof(CDInfo), NULL) == 0 ) | 
|---|
| 366 | { | 
|---|
| 367 | // Workaround for Warp4/FP14 kernel bug ... | 
|---|
| 368 | ulParam = CDInfo.usFirstDrvNo << 8; | 
|---|
| 369 | while( CDInfo.usFirstDrvNo <= ('Z' - 'A') && | 
|---|
| 370 | DosDevIOCtl((HFILE)-1, IOCTL_DISK, DSK_GETDEVICEPARAMS, | 
|---|
| 371 | &ulParam, 2, NULL, &BPB, sizeof(BPB), NULL) == 0 && | 
|---|
| 372 | BPB.bDeviceType != DEVTYPE_UNKNOWN ) | 
|---|
| 373 | { | 
|---|
| 374 | ulParam = ++CDInfo.usFirstDrvNo; | 
|---|
| 375 | } | 
|---|
| 376 |  | 
|---|
| 377 | if( CDInfo.usFirstDrvNo > ('Z' - 'A') ) CDInfo.usDrvCount = 0; | 
|---|
| 378 |  | 
|---|
| 379 | nrCDROMDrives = CDInfo.usDrvCount; | 
|---|
| 380 |  | 
|---|
| 381 | while( CDInfo.usDrvCount-- ) | 
|---|
| 382 | ulCDDriveNr[CDInfo.usDrvCount] = CDInfo.usFirstDrvNo + CDInfo.usDrvCount; | 
|---|
| 383 | uDriveMap |= 1 << (CDInfo.usFirstDrvNo + CDInfo.usDrvCount); | 
|---|
| 384 | } | 
|---|
| 385 |  | 
|---|
| 386 | DosClose(hDev); | 
|---|
| 387 | } | 
|---|
| 388 |  | 
|---|
| 389 | return uDriveMap; | 
|---|
| 390 | } | 
|---|
| 391 |  | 
|---|
| 392 |  | 
|---|
| 393 | //----------------------------------------------------------------------// | 
|---|
| 394 | //      Query fully qualified path name of a given file                 // | 
|---|
| 395 | //----------------------------------------------------------------------// | 
|---|
| 396 |  | 
|---|
| 397 | BOOL OSLibCdIoQueryFullName(char *pchPartName, char *pchFullName, unsigned cbFullName) | 
|---|
| 398 | { | 
|---|
| 399 | APIRET      rc; | 
|---|
| 400 |  | 
|---|
| 401 | DosError(FERR_DISABLEHARDERR); | 
|---|
| 402 | rc = DosQueryPathInfo(pchPartName, FIL_QUERYFULLNAME, pchFullName, cbFullName); | 
|---|
| 403 | DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION); | 
|---|
| 404 |  | 
|---|
| 405 | return rc == 0; | 
|---|
| 406 | } | 
|---|
| 407 |  | 
|---|
| 408 |  | 
|---|
| 409 | //----------------------------------------------------------------------// | 
|---|
| 410 | //      Read volume label                                               // | 
|---|
| 411 | //----------------------------------------------------------------------// | 
|---|
| 412 | BOOL OSLibCdIoQueryVolumeLabel(char chDrive, char *pchLabel, unsigned cbLabel) | 
|---|
| 413 | { | 
|---|
| 414 | FSINFO      FsInfo; | 
|---|
| 415 |  | 
|---|
| 416 | memset(pchLabel, '\0', cbLabel); | 
|---|
| 417 | if( cbLabel && DosQueryFSInfo((chDrive & 0x5f) - 'A' + 1, | 
|---|
| 418 | FSIL_VOLSER, &FsInfo, sizeof(FsInfo)) == 0 ) | 
|---|
| 419 | { | 
|---|
| 420 | strncpy(pchLabel, FsInfo.vol.szVolLabel, cbLabel); | 
|---|
| 421 | pchLabel[cbLabel-1] = '\0'; | 
|---|
| 422 | return 1; | 
|---|
| 423 | } | 
|---|
| 424 |  | 
|---|
| 425 | return 0; | 
|---|
| 426 | } | 
|---|
| 427 |  | 
|---|
| 428 |  | 
|---|