/[pcsx2_0.9.7]/trunk/plugins/CDVDpeops/Ioctrl.c
ViewVC logotype

Contents of /trunk/plugins/CDVDpeops/Ioctrl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (9 years, 11 months ago) by william
File MIME type: text/plain
File size: 10824 byte(s)
committing r3113 initial commit again...
1 /***************************************************************************
2 ioctrl.c - description
3 -------------------
4 begin : Sun Nov 16 2003
5 copyright : (C) 2003 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. See also the license.txt file for *
15 * additional informations. *
16 * *
17 ***************************************************************************/
18
19 //*************************************************************************//
20 // History of changes:
21 //
22 // 2003/11/16 - Pete
23 // - generic cleanup for the Peops release
24 //
25 //*************************************************************************//
26
27 /////////////////////////////////////////////////////////
28
29 #include "stdafx.h"
30 #define _IN_IOCTL
31 #include "externals.h"
32
33 /////////////////////////////////////////////////////////
34
35 HANDLE hIOCTL=NULL; // global drive file handle
36 DWORD dwIOCTLAttr=0; // open attribute
37 OVERLAPPED ovcIOCTL; // global overlapped struct
38 SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptIOCTL; // global read bufs
39 RAW_READ_INFO rawIOCTL;
40
41 /////////////////////////////////////////////////////////
42 // open drive
43
44 void OpenIOCTLHandle(int iA,int iT,int iL)
45 {
46 char cLetter;
47
48 if(hIOCTL) return;
49
50 cLetter=MapIOCTLDriveLetter(iA,iT,iL); // get drive
51
52 if(!cLetter) return;
53
54 hIOCTL=OpenIOCTLFile(cLetter, // open drive
55 (iUseCaching==2)?TRUE:FALSE); // (caching:2 -> overlapped)
56 }
57
58 /////////////////////////////////////////////////////////
59 // close drive
60
61 void CloseIOCTLHandle(void)
62 {
63 if(hIOCTL) CloseHandle(hIOCTL);
64 hIOCTL=NULL;
65 }
66
67 /////////////////////////////////////////////////////////
68 // get drive letter by a,t,l
69
70 char MapIOCTLDriveLetter(int iA,int iT,int iL)
71 {
72 char cLetter[4];int iDA,iDT,iDL;HANDLE hF;
73
74 strcpy(cLetter,"C:\\");
75
76 for(cLetter[0]='C';cLetter[0]<='Z';cLetter[0]++)
77 {
78 if(GetDriveType(cLetter)==DRIVE_CDROM)
79 {
80 hF=OpenIOCTLFile(cLetter[0],FALSE);
81 GetIOCTLAdapter(hF,&iDA,&iDT,&iDL);
82 CloseHandle(hF);
83 if(iA==iDA && iT==iDT && iL==iDL)
84 return cLetter[0];
85 }
86 }
87 return 0;
88 }
89
90 /////////////////////////////////////////////////////////
91 // get cd drive list, using ioctl, not aspi
92
93 int GetIOCTLCDDrives(char * pDList)
94 {
95 char cLetter[4];int iDA,iDT,iDL;HANDLE hF;
96 int iCnt=0;char * p=pDList;
97
98 strcpy(cLetter,"C:\\");
99
100 for(cLetter[0]='C';cLetter[0]<='Z';cLetter[0]++)
101 {
102 if(GetDriveType(cLetter)==DRIVE_CDROM)
103 {
104 hF=OpenIOCTLFile(cLetter[0],FALSE);
105 GetIOCTLAdapter(hF,&iDA,&iDT,&iDL);
106 CloseHandle(hF);
107 if(iDA!=-1 && iDT!=-1 && iDL!=-1)
108 {
109 wsprintf(p,"[%d:%d:%d] Drive %c:",
110 iDA,iDT,iDL,cLetter[0]);
111 p+=strlen(p)+1;
112 iCnt++;
113 }
114 }
115 }
116
117 return iCnt;
118 }
119
120 /////////////////////////////////////////////////////////
121 // open drive in sync/async mode
122
123 HANDLE OpenIOCTLFile(char cLetter,BOOL bAsync)
124 {
125 HANDLE hF;char szFName[16];
126 OSVERSIONINFO ov;DWORD dwFlags;
127
128 if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED;
129 else dwIOCTLAttr=0;
130
131 memset(&ov,0,sizeof(OSVERSIONINFO));
132 ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
133 GetVersionEx(&ov);
134
135 if((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) &&
136 (ov.dwMajorVersion>4))
137 dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP
138 else dwFlags = GENERIC_READ;
139
140 wsprintf(szFName, "\\\\.\\%c:",cLetter);
141
142 hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive
143 NULL,OPEN_EXISTING,dwIOCTLAttr,NULL);
144
145 if(hF==INVALID_HANDLE_VALUE) // mmm... no success?
146 {
147 dwFlags^=GENERIC_WRITE; // -> try write toggle
148 hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again
149 NULL,OPEN_EXISTING,dwIOCTLAttr,NULL);
150 if(hF==INVALID_HANDLE_VALUE) return NULL;
151 }
152
153 return hF;
154 }
155
156 /////////////////////////////////////////////////////////
157 // get a,t,l
158
159 void GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL)
160 {
161 char szBuf[1024];PSCSI_ADDRESS pSA;DWORD dwRet;
162
163 *iDA=*iDT=*iDL=-1;
164 if(hF==NULL) return;
165
166 memset(szBuf,0,1024);
167
168 pSA=(PSCSI_ADDRESS)szBuf;
169 pSA->Length=sizeof(SCSI_ADDRESS);
170
171 if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL,
172 0,pSA,sizeof(SCSI_ADDRESS),
173 &dwRet,NULL))
174 return;
175
176 *iDA = pSA->PortNumber;
177 *iDT = pSA->TargetId;
178 *iDL = pSA->Lun;
179 }
180
181 /////////////////////////////////////////////////////////
182 // we fake the aspi call in ioctl scsi mode
183
184 DWORD IOCTLSendASPI32Command(LPSRB pSRB)
185 {
186 LPSRB_ExecSCSICmd pSC;DWORD dwRet;BOOL bStat;
187
188 if(!pSRB) return SS_ERR;
189
190 if(hIOCTL==NULL ||
191 pSRB->SRB_Cmd!=SC_EXEC_SCSI_CMD) // we only fake exec aspi scsi commands
192 {
193 pSRB->SRB_Status=SS_ERR;
194 return SS_ERR;
195 }
196
197 pSC=(LPSRB_ExecSCSICmd)pSRB;
198
199 memset(&sptIOCTL,0,sizeof(sptIOCTL));
200
201 sptIOCTL.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
202 sptIOCTL.spt.CdbLength = pSC->SRB_CDBLen;
203 sptIOCTL.spt.DataTransferLength = pSC->SRB_BufLen;
204 sptIOCTL.spt.TimeOutValue = 60;
205 sptIOCTL.spt.DataBuffer = pSC->SRB_BufPointer;
206 sptIOCTL.spt.SenseInfoLength = 14;
207 sptIOCTL.spt.TargetId = pSC->SRB_Target;
208 sptIOCTL.spt.Lun = pSC->SRB_Lun;
209 sptIOCTL.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
210 if(pSC->SRB_Flags&SRB_DIR_IN) sptIOCTL.spt.DataIn = SCSI_IOCTL_DATA_IN;
211 else if(pSC->SRB_Flags&SRB_DIR_OUT) sptIOCTL.spt.DataIn = SCSI_IOCTL_DATA_OUT;
212 else sptIOCTL.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
213 memcpy(sptIOCTL.spt.Cdb,pSC->CDBByte,pSC->SRB_CDBLen);
214
215 if(dwIOCTLAttr==FILE_FLAG_OVERLAPPED) // async?
216 {
217 ovcIOCTL.Internal=0;
218 ovcIOCTL.InternalHigh=0;
219 ovcIOCTL.Offset=0;
220 ovcIOCTL.OffsetHigh=0;
221 ovcIOCTL.hEvent=hEvent;
222 bStat = DeviceIoControl(hIOCTL,
223 IOCTL_SCSI_PASS_THROUGH_DIRECT,
224 &sptIOCTL,
225 sizeof(sptIOCTL),
226 &sptIOCTL,
227 sizeof(sptIOCTL),
228 &dwRet,
229 &ovcIOCTL);
230 }
231 else // sync?
232 {
233 bStat = DeviceIoControl(hIOCTL,
234 IOCTL_SCSI_PASS_THROUGH_DIRECT,
235 &sptIOCTL,
236 sizeof(sptIOCTL),
237 &sptIOCTL,
238 sizeof(sptIOCTL),
239 &dwRet,
240 NULL);
241 }
242
243 if(!bStat) // some err?
244 {
245 DWORD dwErrCode;
246 dwErrCode=GetLastError();
247 if(dwErrCode==ERROR_IO_PENDING) // -> pending?
248 {
249 pSC->SRB_Status=SS_COMP; // --> ok
250 return SS_PENDING;
251 }
252 pSC->SRB_Status=SS_ERR; // -> else error
253 return SS_ERR;
254 }
255
256 pSC->SRB_Status=SS_COMP;
257 return SS_COMP;
258 }
259
260 /////////////////////////////////////////////////////////
261 // special raw mode... works on TEAC532S, for example
262
263 DWORD ReadIOCTL_Raw(BOOL bWait,FRAMEBUF * f)
264 {
265 DWORD dwRet;BOOL bStat;
266
267 if(hIOCTL==NULL) return SS_ERR;
268
269 rawIOCTL.DiskOffset.QuadPart = f->dwFrame*2048; // 2048 is needed here
270 rawIOCTL.SectorCount = f->dwFrameCnt;
271 rawIOCTL.TrackMode = XAForm2;//CDDA;//YellowMode2;//XAForm2;
272
273 if(dwIOCTLAttr==FILE_FLAG_OVERLAPPED) // async?
274 {
275 ovcIOCTL.Internal=0;
276 ovcIOCTL.InternalHigh=0;
277 ovcIOCTL.Offset=0;
278 ovcIOCTL.OffsetHigh=0;
279 ovcIOCTL.hEvent=hEvent;
280 ResetEvent(hEvent);
281 bStat = DeviceIoControl(hIOCTL,
282 IOCTL_CDROM_RAW_READ,
283 &rawIOCTL,sizeof(RAW_READ_INFO),
284 &(f->BufData[0]),f->dwBufLen,//2048,
285 &dwRet, &ovcIOCTL);
286 }
287 else // sync?
288 {
289 bStat = DeviceIoControl(hIOCTL,
290 IOCTL_CDROM_RAW_READ,
291 &rawIOCTL,sizeof(RAW_READ_INFO),
292 &(f->BufData[0]),f->dwBufLen,//2048,
293 &dwRet,NULL);
294 }
295
296 if(!bStat)
297 {
298 DWORD dwErrCode;
299 dwErrCode=GetLastError();
300
301 #ifdef DBGOUT
302 auxprintf("errorcode %d\n", dwErrCode);
303 #endif
304
305 if(dwErrCode==ERROR_IO_PENDING)
306 {
307 // we do a wait here, not later... no real async mode anyway
308 // bDoWaiting=TRUE;
309
310 WaitGenEvent(0xFFFFFFFF);
311 }
312 else
313 {
314 sx.SRB_Status=SS_ERR;
315 return SS_ERR;
316 }
317 }
318
319 sx.SRB_Status=SS_COMP;
320 return SS_COMP;
321 }
322
323 /////////////////////////////////////////////////////////
324 // special raw + special sub... dunno if this really
325 // works on any drive (teac is working, but giving unprecise
326 // subdata)
327
328 DWORD ReadIOCTL_Raw_Sub(BOOL bWait,FRAMEBUF * f)
329 {
330 DWORD dwRet;BOOL bStat;
331 SUB_Q_CHANNEL_DATA qd;unsigned char * p;
332 CDROM_SUB_Q_DATA_FORMAT qf;
333
334 if(hIOCTL==NULL) return SS_ERR;
335
336 rawIOCTL.DiskOffset.QuadPart = f->dwFrame*2048;
337 rawIOCTL.SectorCount = f->dwFrameCnt;
338 rawIOCTL.TrackMode = XAForm2;
339
340 bStat = DeviceIoControl(hIOCTL,
341 IOCTL_CDROM_RAW_READ,
342 &rawIOCTL,sizeof(RAW_READ_INFO),
343 &(f->BufData[0]),f->dwBufLen,
344 &dwRet,NULL);
345
346 if(!bStat) {sx.SRB_Status=SS_ERR;return SS_ERR;}
347
348 qf.Format=IOCTL_CDROM_CURRENT_POSITION;
349 qf.Track=1;
350 bStat = DeviceIoControl(hIOCTL,
351 IOCTL_CDROM_READ_Q_CHANNEL,
352 &qf,sizeof(CDROM_SUB_Q_DATA_FORMAT),
353 &qd,sizeof(SUB_Q_CHANNEL_DATA),
354 &dwRet,NULL);
355
356 p=(unsigned char*)&qd;
357
358 SubCData[12]=(p[5]<<4)|(p[5]>>4);
359 SubCData[13]=p[6];
360 SubCData[14]=p[7];
361 SubCData[15]=p[13];
362 SubCData[16]=p[14];
363 SubCData[17]=p[15];
364 SubCData[18]=0;
365 SubCData[19]=p[9];
366 SubCData[20]=p[10];
367 SubCData[21]=p[11];
368
369 SubCData[15]=itob(SubCData[15]);
370 SubCData[16]=itob(SubCData[16]);
371 SubCData[17]=itob(SubCData[17]);
372
373 SubCData[19]=itob(SubCData[19]);
374 SubCData[20]=itob(SubCData[20]);
375 SubCData[21]=itob(SubCData[21]);
376
377 if(!bStat) {sx.SRB_Status=SS_ERR;return SS_ERR;}
378
379 sx.SRB_Status=SS_COMP;
380 return SS_COMP;
381 }
382
383 /////////////////////////////////////////////////////////

  ViewVC Help
Powered by ViewVC 1.1.22