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

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

Export OSLibDosDevIOCtl

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