source: trunk/src/kernel32/oslibcdio.cpp@ 9610

Last change on this file since 9610 was 8929, checked in by sandervl, 23 years ago

Added function to disable os2cdrom.dmd aspi support

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