source: trunk/src/kernel32/hmdisk.cpp@ 6977

Last change on this file since 6977 was 6977, checked in by phaller, 24 years ago

added IOCTL_CDROM_EJECT_MEDIA

File size: 27.8 KB
Line 
1/* $Id: hmdisk.cpp,v 1.13 2001-10-10 10:21:31 phaller Exp $ */
2
3/*
4 * Win32 Disk API functions for OS/2
5 *
6 * Copyright 2000 Sander van Leeuwen
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <string.h>
14
15#include <misc.h>
16#include "hmdisk.h"
17#include "mmap.h"
18#include "oslibdos.h"
19#include <win\winioctl.h>
20#include <win\ntddscsi.h>
21#include <win\wnaspi32.h>
22#include <win\aspi.h>
23
24#define DBG_LOCALLOG DBG_hmdisk
25#include "dbglocal.h"
26
27typedef struct
28{
29 HINSTANCE hInstAspi;
30 DWORD (WIN32API *GetASPI32SupportInfo)();
31 DWORD (CDECL *SendASPI32Command)(LPSRB lpSRB);
32 ULONG driveLetter;
33 CHAR signature[8];
34} DRIVE_INFO;
35
36HMDeviceDiskClass::HMDeviceDiskClass(LPCSTR lpDeviceName) : HMDeviceKernelObjectClass(lpDeviceName)
37{
38 HMDeviceRegisterEx("\\\\.\\PHYSICALDRIVE", this, NULL);
39}
40
41/*****************************************************************************
42 * Name : HMDeviceDiskClass::FindDevice
43 * Purpose : Checks if lpDeviceName belongs to this device class
44 * Parameters: LPCSTR lpClassDevName
45 * LPCSTR lpDeviceName
46 * int namelength
47 * Variables :
48 * Result : checks if name is for a drive of physical disk
49 * Remark :
50 * Status :
51 *
52 * Author : SvL
53 *****************************************************************************/
54BOOL HMDeviceDiskClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
55{
56 //\\.\x: -> length 6
57 //\\.\PHYSICALDRIVEn -> length 18
58 if(namelength != 6 && namelength != 18) {
59 return FALSE;
60 }
61
62 //SvL: \\.\x: -> drive x (i.e. \\.\C:)
63 // \\.\PHYSICALDRIVEn -> drive n (n>=0)
64 if((strncmp(lpDeviceName, "\\\\.\\", 4) == 0) &&
65 namelength == 6 && lpDeviceName[5] == ':')
66 {
67 return TRUE;
68 }
69 if((strncmp(lpDeviceName, "\\\\.\\PHYSICALDRIVE", 17) == 0) && namelength == 18) {
70 return TRUE;
71 }
72 return FALSE;
73}
74//******************************************************************************
75//TODO: PHYSICALDRIVEn!!
76//******************************************************************************
77DWORD HMDeviceDiskClass::CreateFile (LPCSTR lpFileName,
78 PHMHANDLEDATA pHMHandleData,
79 PVOID lpSecurityAttributes,
80 PHMHANDLEDATA pHMHandleDataTemplate)
81{
82 HFILE hFile;
83 HFILE hTemplate;
84
85 dprintf2(("KERNEL32: HMDeviceDiskClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
86 lpHMDeviceName,
87 lpFileName,
88 pHMHandleData,
89 lpSecurityAttributes,
90 pHMHandleDataTemplate));
91
92 //TODO: check in NT if CREATE_ALWAYS is allowed!!
93 if(pHMHandleData->dwCreation != OPEN_EXISTING) {
94 dprintf(("Invalid creation flags %x!!", pHMHandleData->dwCreation));
95 return ERROR_INVALID_PARAMETER;
96 }
97 if(strncmp(lpFileName, // "support" for local unc names
98 "\\\\.\\",
99 4) == 0)
100 {
101 lpFileName+=4;
102 }
103
104 //Disable error popus. NT allows an app to open a cdrom/dvd drive without a disk inside
105 //OS/2 fails in that case with error ERROR_NOT_READY
106 OSLibDosDisableHardError(TRUE);
107 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
108 pHMHandleData->dwAccess,
109 pHMHandleData->dwShare,
110 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
111 pHMHandleData->dwCreation,
112 pHMHandleData->dwFlags,
113 hTemplate);
114 OSLibDosDisableHardError(FALSE);
115
116 if (hFile != INVALID_HANDLE_ERROR || GetLastError() == ERROR_NOT_READY)
117 {
118 if(hFile == INVALID_HANDLE_ERROR) {
119 SetLastError(NO_ERROR);
120 pHMHandleData->hHMHandle = 0; //handle lookup fails if this is set to -1
121 }
122 else pHMHandleData->hHMHandle = hFile;
123
124 DRIVE_INFO *drvInfo = (DRIVE_INFO *)malloc(sizeof(DRIVE_INFO));
125 if(drvInfo == NULL) {
126 if(pHMHandleData->hHMHandle) OSLibDosClose(pHMHandleData->hHMHandle);
127 return ERROR_OUTOFMEMORY;
128 }
129 pHMHandleData->dwUserData = (DWORD)drvInfo;
130
131 memset(drvInfo, 0, sizeof(DRIVE_INFO));
132 drvInfo->driveLetter = *lpFileName; //save drive letter
133 if(drvInfo->driveLetter >= 'a') {
134 drvInfo->driveLetter = drvInfo->driveLetter - ((int)'a' - (int)'A');
135 }
136
137 if(GetDriveTypeA(lpFileName) == DRIVE_CDROM) {
138 drvInfo->hInstAspi = LoadLibraryA("WNASPI32.DLL");
139 if(drvInfo->hInstAspi == NULL) {
140 if(pHMHandleData->hHMHandle) OSLibDosClose(pHMHandleData->hHMHandle);
141 free(drvInfo);
142 return ERROR_INVALID_PARAMETER;
143 }
144 *(FARPROC *)&drvInfo->GetASPI32SupportInfo = GetProcAddress(drvInfo->hInstAspi, "GetASPI32SupportInfo");
145 *(FARPROC *)&drvInfo->SendASPI32Command = GetProcAddress(drvInfo->hInstAspi, "SendASPI32Command");
146
147 //get cdrom signature (TODO: why doesn't this work???)
148 DWORD parsize = 4;
149 DWORD datasize = 4;
150 strcpy(drvInfo->signature, "CD01");
151 OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x60, &drvInfo->signature[0], 4, &parsize,
152 &drvInfo->signature[0], 4, &datasize);
153 }
154 return (NO_ERROR);
155 }
156 else {
157 dprintf(("CreateFile failed; error %d", GetLastError()));
158 return(GetLastError());
159 }
160}
161//******************************************************************************
162//******************************************************************************
163BOOL HMDeviceDiskClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
164{
165 BOOL ret = TRUE;
166
167 if(pHMHandleData->hHMHandle) {
168 ret = OSLibDosClose(pHMHandleData->hHMHandle);
169 }
170 if(pHMHandleData->dwUserData) {
171 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
172 if(drvInfo->hInstAspi) FreeLibrary(drvInfo->hInstAspi);
173 free(drvInfo);
174 }
175 return ret;
176}
177//******************************************************************************
178//******************************************************************************
179BOOL HMDeviceDiskClass::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
180 LPVOID lpInBuffer, DWORD nInBufferSize,
181 LPVOID lpOutBuffer, DWORD nOutBufferSize,
182 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
183{
184#ifdef DEBUG
185 char *msg = NULL;
186
187 switch(dwIoControlCode)
188 {
189 case FSCTL_DELETE_REPARSE_POINT:
190 msg = "FSCTL_DELETE_REPARSE_POINT";
191 break;
192 case FSCTL_DISMOUNT_VOLUME:
193 msg = "FSCTL_DISMOUNT_VOLUME";
194 break;
195 case FSCTL_GET_COMPRESSION:
196 msg = "FSCTL_GET_COMPRESSION";
197 break;
198 case FSCTL_GET_REPARSE_POINT:
199 msg = "FSCTL_GET_REPARSE_POINT";
200 break;
201 case FSCTL_LOCK_VOLUME:
202 msg = "FSCTL_LOCK_VOLUME";
203 break;
204 case FSCTL_QUERY_ALLOCATED_RANGES:
205 msg = "FSCTL_QUERY_ALLOCATED_RANGES";
206 break;
207 case FSCTL_SET_COMPRESSION:
208 msg = "FSCTL_SET_COMPRESSION";
209 break;
210 case FSCTL_SET_REPARSE_POINT:
211 msg = "FSCTL_SET_REPARSE_POINT";
212 break;
213 case FSCTL_SET_SPARSE:
214 msg = "FSCTL_SET_SPARSE";
215 break;
216 case FSCTL_SET_ZERO_DATA:
217 msg = "FSCTL_SET_ZERO_DATA";
218 break;
219 case FSCTL_UNLOCK_VOLUME:
220 msg = "FSCTL_UNLOCK_VOLUME";
221 break;
222 case IOCTL_DISK_CHECK_VERIFY:
223 msg = "IOCTL_DISK_CHECK_VERIFY";
224 break;
225 case IOCTL_DISK_EJECT_MEDIA:
226 msg = "IOCTL_DISK_EJECT_MEDIA";
227 break;
228 case IOCTL_DISK_FORMAT_TRACKS:
229 msg = "IOCTL_DISK_FORMAT_TRACKS";
230 break;
231 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
232 msg = "IOCTL_DISK_GET_DRIVE_GEOMETRY";
233 break;
234 case IOCTL_DISK_GET_DRIVE_LAYOUT:
235 msg = "IOCTL_DISK_GET_DRIVE_LAYOUT";
236 break;
237 case IOCTL_DISK_GET_MEDIA_TYPES:
238 msg = "IOCTL_DISK_GET_MEDIA_TYPES";
239 break;
240 case IOCTL_DISK_GET_PARTITION_INFO:
241 msg = "IOCTL_DISK_GET_PARTITION_INFO";
242 break;
243 case IOCTL_DISK_LOAD_MEDIA:
244 msg = "IOCTL_DISK_LOAD_MEDIA";
245 break;
246 case IOCTL_DISK_MEDIA_REMOVAL:
247 msg = "IOCTL_DISK_MEDIA_REMOVAL";
248 break;
249 case IOCTL_DISK_PERFORMANCE:
250 msg = "IOCTL_DISK_PERFORMANCE";
251 break;
252 case IOCTL_DISK_REASSIGN_BLOCKS:
253 msg = "IOCTL_DISK_REASSIGN_BLOCKS";
254 break;
255 case IOCTL_DISK_SET_DRIVE_LAYOUT:
256 msg = "IOCTL_DISK_SET_DRIVE_LAYOUT";
257 break;
258 case IOCTL_DISK_SET_PARTITION_INFO:
259 msg = "IOCTL_DISK_SET_PARTITION_INFO";
260 break;
261 case IOCTL_DISK_VERIFY:
262 msg = "IOCTL_DISK_VERIFY";
263 break;
264 case IOCTL_SERIAL_LSRMST_INSERT:
265 msg = "IOCTL_SERIAL_LSRMST_INSERT";
266 break;
267 case IOCTL_STORAGE_CHECK_VERIFY:
268 msg = "IOCTL_STORAGE_CHECK_VERIFY";
269 break;
270 case IOCTL_STORAGE_EJECT_MEDIA:
271 msg = "IOCTL_STORAGE_EJECT_MEDIA";
272 break;
273 case IOCTL_STORAGE_GET_MEDIA_TYPES:
274 msg = "IOCTL_STORAGE_GET_MEDIA_TYPES";
275 break;
276 case IOCTL_STORAGE_LOAD_MEDIA:
277 msg = "IOCTL_STORAGE_LOAD_MEDIA";
278 break;
279 case IOCTL_STORAGE_MEDIA_REMOVAL:
280 msg = "IOCTL_STORAGE_MEDIA_REMOVAL";
281 break;
282 case IOCTL_SCSI_PASS_THROUGH:
283 msg = "IOCTL_SCSI_PASS_THROUGH";
284 break;
285 case IOCTL_SCSI_MINIPORT:
286 msg = "IOCTL_SCSI_MINIPORT";
287 break;
288 case IOCTL_SCSI_GET_INQUIRY_DATA:
289 msg = "IOCTL_SCSI_GET_INQUIRY_DATA";
290 break;
291 case IOCTL_SCSI_GET_CAPABILITIES:
292 msg = "IOCTL_SCSI_GET_CAPABILITIES";
293 break;
294 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
295 msg = "IOCTL_SCSI_PASS_THROUGH_DIRECT";
296 break;
297 case IOCTL_SCSI_GET_ADDRESS:
298 msg = "IOCTL_SCSI_GET_ADDRESS";
299 break;
300 case IOCTL_SCSI_RESCAN_BUS:
301 msg = "IOCTL_SCSI_RESCAN_BUS";
302 break;
303 case IOCTL_SCSI_GET_DUMP_POINTERS:
304 msg = "IOCTL_SCSI_GET_DUMP_POINTERS";
305 break;
306 case IOCTL_SCSI_FREE_DUMP_POINTERS:
307 msg = "IOCTL_SCSI_FREE_DUMP_POINTERS";
308 break;
309 case IOCTL_IDE_PASS_THROUGH:
310 msg = "IOCTL_IDE_PASS_THROUGH";
311 break;
312 case IOCTL_CDROM_UNLOAD_DRIVER:
313 msg = "IOCTL_CDROM_UNLOAD_DRIVER";
314 break;
315 case IOCTL_CDROM_READ_TOC:
316 msg = "IOCTL_CDROM_READ_TOC";
317 break;
318 case IOCTL_CDROM_GET_CONTROL:
319 msg = "IOCTL_CDROM_GET_CONTROL";
320 break;
321 case IOCTL_CDROM_PLAY_AUDIO_MSF:
322 msg = "IOCTL_CDROM_PLAY_AUDIO_MSF";
323 break;
324 case IOCTL_CDROM_SEEK_AUDIO_MSF:
325 msg = "IOCTL_CDROM_SEEK_AUDIO_MSF";
326 break;
327 case IOCTL_CDROM_STOP_AUDIO:
328 msg = "IOCTL_CDROM_STOP_AUDIO";
329 break;
330 case IOCTL_CDROM_PAUSE_AUDIO:
331 msg = "IOCTL_CDROM_PAUSE_AUDIO";
332 break;
333 case IOCTL_CDROM_RESUME_AUDIO:
334 msg = "IOCTL_CDROM_RESUME_AUDIO";
335 break;
336 case IOCTL_CDROM_GET_VOLUME:
337 msg = "IOCTL_CDROM_GET_VOLUME";
338 break;
339 case IOCTL_CDROM_SET_VOLUME:
340 msg = "IOCTL_CDROM_SET_VOLUME";
341 break;
342 case IOCTL_CDROM_READ_Q_CHANNEL:
343 msg = "IOCTL_CDROM_READ_Q_CHANNEL";
344 break;
345 case IOCTL_CDROM_GET_LAST_SESSION:
346 msg = "IOCTL_CDROM_GET_LAST_SESSION";
347 break;
348 case IOCTL_CDROM_RAW_READ:
349 msg = "IOCTL_CDROM_RAW_READ";
350 break;
351 case IOCTL_CDROM_DISK_TYPE:
352 msg = "IOCTL_CDROM_DISK_TYPE";
353 break;
354 case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
355 msg = "IOCTL_CDROM_GET_DRIVE_GEOMETRY";
356 break;
357 case IOCTL_CDROM_CHECK_VERIFY:
358 msg = "IOCTL_CDROM_CHECK_VERIFY";
359 break;
360 case IOCTL_CDROM_MEDIA_REMOVAL:
361 msg = "IOCTL_CDROM_MEDIA_REMOVAL";
362 break;
363 case IOCTL_CDROM_EJECT_MEDIA:
364 msg = "IOCTL_CDROM_EJECT_MEDIA";
365 break;
366 case IOCTL_CDROM_LOAD_MEDIA:
367 msg = "IOCTL_CDROM_LOAD_MEDIA";
368 break;
369 case IOCTL_CDROM_RESERVE:
370 msg = "IOCTL_CDROM_RESERVE";
371 break;
372 case IOCTL_CDROM_RELEASE:
373 msg = "IOCTL_CDROM_RELEASE";
374 break;
375 case IOCTL_CDROM_FIND_NEW_DEVICES:
376 msg = "IOCTL_CDROM_FIND_NEW_DEVICES";
377 break;
378 }
379 if(msg) {
380 dprintf(("HMDeviceDiskClass::DeviceIoControl %s %x %d %x %d %x %x", msg, lpInBuffer, nInBufferSize,
381 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped));
382 }
383#endif
384
385 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
386 if(drvInfo == NULL) {
387 dprintf(("ERROR: DeviceIoControl: drvInfo == NULL!!!"));
388 DebugInt3();
389 SetLastError(ERROR_INVALID_HANDLE);
390 return FALSE;
391 }
392 switch(dwIoControlCode)
393 {
394 case FSCTL_DELETE_REPARSE_POINT:
395 case FSCTL_DISMOUNT_VOLUME:
396 case FSCTL_GET_COMPRESSION:
397 case FSCTL_GET_REPARSE_POINT:
398 case FSCTL_LOCK_VOLUME:
399 case FSCTL_QUERY_ALLOCATED_RANGES:
400 case FSCTL_SET_COMPRESSION:
401 case FSCTL_SET_REPARSE_POINT:
402 case FSCTL_SET_SPARSE:
403 case FSCTL_SET_ZERO_DATA:
404 case FSCTL_UNLOCK_VOLUME:
405 break;
406
407 case IOCTL_DISK_CHECK_VERIFY:
408 case IOCTL_DISK_EJECT_MEDIA:
409 case IOCTL_DISK_FORMAT_TRACKS:
410 case IOCTL_DISK_GET_DRIVE_LAYOUT:
411 break;
412
413 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
414 case IOCTL_DISK_GET_MEDIA_TYPES:
415 {
416 PDISK_GEOMETRY pGeom = (PDISK_GEOMETRY)lpOutBuffer;
417 if(nOutBufferSize < sizeof(DISK_GEOMETRY) || !pGeom) {
418 SetLastError(ERROR_INSUFFICIENT_BUFFER);
419 return FALSE;
420 }
421 if(lpBytesReturned) {
422 *lpBytesReturned = 0;
423 }
424 if(OSLibDosGetDiskGeometry(pHMHandleData->hHMHandle, drvInfo->driveLetter, pGeom) == FALSE) {
425 return FALSE;
426 }
427 if(lpBytesReturned) {
428 *lpBytesReturned = sizeof(DISK_GEOMETRY);
429 }
430 SetLastError(ERROR_SUCCESS);
431 return TRUE;
432 }
433
434 case IOCTL_DISK_GET_PARTITION_INFO:
435 case IOCTL_DISK_LOAD_MEDIA:
436 case IOCTL_DISK_MEDIA_REMOVAL:
437 case IOCTL_DISK_PERFORMANCE:
438 case IOCTL_DISK_REASSIGN_BLOCKS:
439 case IOCTL_DISK_SET_DRIVE_LAYOUT:
440 case IOCTL_DISK_SET_PARTITION_INFO:
441 case IOCTL_DISK_VERIFY:
442 case IOCTL_SERIAL_LSRMST_INSERT:
443 break;
444
445 case IOCTL_CDROM_UNLOAD_DRIVER:
446 case IOCTL_CDROM_READ_TOC:
447 case IOCTL_CDROM_GET_CONTROL:
448 case IOCTL_CDROM_PLAY_AUDIO_MSF:
449 case IOCTL_CDROM_SEEK_AUDIO_MSF:
450 case IOCTL_CDROM_STOP_AUDIO:
451 case IOCTL_CDROM_PAUSE_AUDIO:
452 case IOCTL_CDROM_RESUME_AUDIO:
453 break;
454
455 case IOCTL_CDROM_GET_VOLUME:
456 {
457 PVOLUME_CONTROL pVol = (PVOLUME_CONTROL)lpOutBuffer;
458 char volbuf[8];
459 DWORD parsize, datasize, ret;
460
461 if(nOutBufferSize < sizeof(VOLUME_CONTROL) || !pVol) {
462 SetLastError(ERROR_INSUFFICIENT_BUFFER);
463 return FALSE;
464 }
465 if(lpBytesReturned) {
466 *lpBytesReturned = 0;
467 }
468 parsize = 4;
469 datasize = 8;
470 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x60, "CD01", 4, &parsize,
471 volbuf, 8, &datasize);
472
473 if(ret) {
474 SetLastError(error2WinError(ret));
475 return FALSE;
476 }
477 if(lpBytesReturned) {
478 *lpBytesReturned = sizeof(VOLUME_CONTROL);
479 }
480 pVol->PortVolume[0] = volbuf[1];
481 pVol->PortVolume[1] = volbuf[3];
482 pVol->PortVolume[2] = volbuf[5];
483 pVol->PortVolume[3] = volbuf[7];
484 SetLastError(ERROR_SUCCESS);
485 return TRUE;
486 }
487
488 case IOCTL_CDROM_SET_VOLUME:
489 {
490 PVOLUME_CONTROL pVol = (PVOLUME_CONTROL)lpInBuffer;
491 char volbuf[8];
492 DWORD parsize, datasize, ret;
493
494 if(nInBufferSize < sizeof(VOLUME_CONTROL) || !pVol) {
495 SetLastError(ERROR_INSUFFICIENT_BUFFER);
496 return FALSE;
497 }
498 if(lpBytesReturned) {
499 *lpBytesReturned = 0;
500 }
501 parsize = 4;
502 datasize = 8;
503 volbuf[0] = 0;
504 volbuf[1] = pVol->PortVolume[0];
505 volbuf[2] = 1;
506 volbuf[3] = pVol->PortVolume[1];
507 volbuf[4] = 2;
508 volbuf[5] = pVol->PortVolume[2];
509 volbuf[6] = 3;
510 volbuf[7] = pVol->PortVolume[3];
511 dprintf(("Set CD volume (%d,%d)(%d,%d)", pVol->PortVolume[0], pVol->PortVolume[1], pVol->PortVolume[2], pVol->PortVolume[3]));
512 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x40, "CD01", 4, &parsize,
513 volbuf, 8, &datasize);
514
515 if(ret) {
516 SetLastError(error2WinError(ret));
517 return FALSE;
518 }
519 SetLastError(ERROR_SUCCESS);
520 return TRUE;
521 }
522 case IOCTL_CDROM_READ_Q_CHANNEL:
523 case IOCTL_CDROM_GET_LAST_SESSION:
524 case IOCTL_CDROM_RAW_READ:
525 case IOCTL_CDROM_DISK_TYPE:
526 case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
527 case IOCTL_CDROM_CHECK_VERIFY:
528 case IOCTL_CDROM_MEDIA_REMOVAL:
529 break;
530
531 case IOCTL_CDROM_EJECT_MEDIA:
532 {
533 DWORD dwParameterSize = 4;
534 DWORD dwDataSize = 0;
535 DWORD ret;
536
537 if(lpBytesReturned)
538 *lpBytesReturned = 0;
539
540 dprintf(("Eject CD media"));
541 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
542 0x80, // IOCTL_CDROM
543 0x44, // CDROMDISK_EJECTDISK
544 "CD01",
545 4,
546 &dwParameterSize,
547 NULL,
548 0,
549 &dwDataSize);
550 if(ret)
551 {
552 SetLastError(error2WinError(ret));
553 return FALSE;
554 }
555 SetLastError(ERROR_SUCCESS);
556 return TRUE;
557 }
558
559 case IOCTL_CDROM_LOAD_MEDIA:
560 case IOCTL_CDROM_RESERVE:
561 case IOCTL_CDROM_RELEASE:
562 case IOCTL_CDROM_FIND_NEW_DEVICES:
563 break;
564
565 case IOCTL_STORAGE_CHECK_VERIFY:
566 if(lpBytesReturned) {
567 *lpBytesReturned = 0;
568 }
569 //TODO: check if disk has been inserted or removed
570 if(pHMHandleData->hHMHandle == 0) {
571 SetLastError(ERROR_NOT_READY);
572 return FALSE;
573 }
574 SetLastError(NO_ERROR);
575 return TRUE;
576
577 case IOCTL_STORAGE_EJECT_MEDIA:
578 break;
579
580 case IOCTL_STORAGE_GET_MEDIA_TYPES:
581 case IOCTL_STORAGE_LOAD_MEDIA:
582 case IOCTL_STORAGE_MEDIA_REMOVAL:
583 break;
584 case IOCTL_SCSI_PASS_THROUGH:
585 case IOCTL_SCSI_MINIPORT:
586 case IOCTL_SCSI_GET_INQUIRY_DATA:
587 case IOCTL_SCSI_GET_CAPABILITIES:
588 break;
589
590 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
591 {
592 PSCSI_PASS_THROUGH_DIRECT pPacket = (PSCSI_PASS_THROUGH_DIRECT)lpOutBuffer;
593 SRB_ExecSCSICmd *psrb;
594
595 if(drvInfo->hInstAspi == NULL) {
596 SetLastError(ERROR_ACCESS_DENIED);
597 return FALSE;
598 }
599
600 if(nOutBufferSize < sizeof(SCSI_PASS_THROUGH_DIRECT) ||
601 !pPacket || pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
602 {
603 SetLastError(ERROR_INSUFFICIENT_BUFFER);
604 return FALSE;
605 }
606 if(lpBytesReturned) {
607 *lpBytesReturned = 0;
608 }
609 psrb = (SRB_ExecSCSICmd *)alloca(sizeof(SRB_ExecSCSICmd)+pPacket->SenseInfoLength);
610 if(psrb == NULL) {
611 dprintf(("not enough memory!!"));
612 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
613 return FALSE;
614 }
615 memset(psrb, 0, sizeof(*psrb));
616 psrb->SRB_Cmd = SC_EXEC_SCSI_CMD;
617 psrb->SRB_Status = pPacket->ScsiStatus;
618 psrb->SRB_HaId = pPacket->PathId;
619 psrb->SRB_Target = pPacket->TargetId;
620 psrb->SRB_Lun = pPacket->Lun;
621 psrb->SRB_BufLen = pPacket->DataTransferLength;
622 psrb->SRB_SenseLen = pPacket->SenseInfoLength;
623 psrb->SRB_CDBLen = pPacket->CdbLength;
624 switch(pPacket->DataIn) {
625 case SCSI_IOCTL_DATA_OUT:
626 psrb->SRB_Flags = 0x2 << 3;
627 break;
628 case SCSI_IOCTL_DATA_IN:
629 psrb->SRB_Flags = 0x1 << 3;
630 break;
631 case SCSI_IOCTL_DATA_UNSPECIFIED:
632 psrb->SRB_Flags = 0x3 << 3;
633 break;
634 }
635 if(pPacket->CdbLength > 16) {
636 SetLastError(ERROR_INVALID_PARAMETER);
637 return FALSE;
638 }
639 psrb->SRB_BufPointer = (BYTE *)pPacket->DataBuffer;
640 memcpy(&psrb->CDBByte[0], &pPacket->Cdb[0], 16);
641 if(psrb->SRB_SenseLen) {
642 memcpy(&psrb->SenseArea[0], (char *)pPacket + pPacket->SenseInfoOffset, psrb->SRB_SenseLen);
643 }
644 //TODO: pPacket->TimeOutValue ignored
645 int rc = drvInfo->SendASPI32Command((LPSRB)psrb);
646 if(rc != SS_COMP) {
647 dprintf(("SendASPI32Command failed with error %d", rc));
648 if(rc == SS_ERR) {
649 SetLastError(ERROR_ADAP_HDW_ERR); //returned by NT4, SP6
650 }
651 else SetLastError(ERROR_GEN_FAILURE);
652 return FALSE;
653 }
654 pPacket->ScsiStatus = rc;
655 if(lpBytesReturned) {
656 *lpBytesReturned = 0;
657 }
658 pPacket->DataTransferLength = psrb->SRB_BufLen;
659 if(psrb->SRB_SenseLen) {
660 memcpy((char *)pPacket + pPacket->SenseInfoOffset, &psrb->SenseArea[0], psrb->SRB_SenseLen);
661 }
662 SetLastError(ERROR_SUCCESS);
663 return TRUE;
664 }
665 case IOCTL_SCSI_GET_ADDRESS:
666 {
667 DWORD numAdapters, rc;
668 SRB srb;
669 int i, j, k;
670
671 if(!lpOutBuffer || nOutBufferSize < 8) {
672 SetLastError(ERROR_INSUFFICIENT_BUFFER); //todo: right error?
673 return(FALSE);
674 }
675 SCSI_ADDRESS *addr = (SCSI_ADDRESS *)lpOutBuffer;
676 addr->Length = sizeof(SCSI_ADDRESS);
677 addr->PortNumber = 0;
678 addr->PathId = 0;
679 numAdapters = drvInfo->GetASPI32SupportInfo();
680 if(LOBYTE(numAdapters) == 0) goto failure;
681
682 memset(&srb, 0, sizeof(srb));
683 srb.common.SRB_Cmd = SC_HA_INQUIRY;
684 rc = drvInfo->SendASPI32Command(&srb);
685
686 char drivename[3];
687 drivename[0] = (char)drvInfo->driveLetter;
688 drivename[1] = ':';
689 drivename[2] = 0;
690
691 for(i=0;i<LOBYTE(numAdapters);i++) {
692 for(j=0;j<8;j++) {
693 for(k=0;k<16;k++) {
694 memset(&srb, 0, sizeof(srb));
695 srb.common.SRB_Cmd = SC_GET_DEV_TYPE;
696 srb.devtype.SRB_HaId = i;
697 srb.devtype.SRB_Target = j;
698 srb.devtype.SRB_Lun = k;
699 rc = drvInfo->SendASPI32Command(&srb);
700 if(rc == SS_COMP) {
701 if(srb.devtype.SRB_DeviceType == SS_DEVTYPE_CDROM &&
702 GetDriveTypeA(drivename) == DRIVE_CDROM)
703 {
704 goto done;
705 }
706 }
707 }
708 }
709 }
710done:
711 if(rc == SS_COMP) {
712 addr->TargetId = j;
713 addr->Lun = k;
714 SetLastError(ERROR_SUCCESS);
715 }
716 else SetLastError(ERROR_FILE_NOT_FOUND); //todo
717 return TRUE;
718failure:
719 SetLastError(ERROR_INVALID_PARAMETER); //todo
720 return FALSE;
721 }
722
723 case IOCTL_SCSI_RESCAN_BUS:
724 case IOCTL_SCSI_GET_DUMP_POINTERS:
725 case IOCTL_SCSI_FREE_DUMP_POINTERS:
726 case IOCTL_IDE_PASS_THROUGH:
727 break;
728
729 }
730 dprintf(("HMDeviceDiskClass::DeviceIoControl: unimplemented dwIoControlCode=%08lx\n", dwIoControlCode));
731 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
732 return FALSE;
733}
734/*****************************************************************************
735 * Name : BOOL HMDeviceDiskClass::ReadFile
736 * Purpose : read data from handle / device
737 * Parameters: PHMHANDLEDATA pHMHandleData,
738 * LPCVOID lpBuffer,
739 * DWORD nNumberOfBytesToRead,
740 * LPDWORD lpNumberOfBytesRead,
741 * LPOVERLAPPED lpOverlapped
742 * Variables :
743 * Result : Boolean
744 * Remark :
745 * Status :
746 *
747 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
748 *****************************************************************************/
749
750BOOL HMDeviceDiskClass::ReadFile(PHMHANDLEDATA pHMHandleData,
751 LPCVOID lpBuffer,
752 DWORD nNumberOfBytesToRead,
753 LPDWORD lpNumberOfBytesRead,
754 LPOVERLAPPED lpOverlapped)
755{
756 LPVOID lpRealBuf;
757 Win32MemMap *map;
758 DWORD offset, bytesread;
759 BOOL bRC;
760
761 dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
762 lpHMDeviceName,
763 pHMHandleData,
764 lpBuffer,
765 nNumberOfBytesToRead,
766 lpNumberOfBytesRead,
767 lpOverlapped));
768
769 //SvL: It's legal for this pointer to be NULL
770 if(lpNumberOfBytesRead)
771 *lpNumberOfBytesRead = 0;
772 else
773 lpNumberOfBytesRead = &bytesread;
774
775 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
776 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
777 SetLastError(ERROR_INVALID_PARAMETER);
778 return FALSE;
779 }
780 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
781 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
782 }
783
784 //SvL: DosRead doesn't like writing to memory addresses returned by
785 // DosAliasMem -> search for original memory mapped pointer and use
786 // that one + commit pages if not already present
787 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
788 if(map) {
789 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
790 DWORD nrpages = nNumberOfBytesToRead/4096;
791 if(offset & 0xfff)
792 nrpages++;
793 if(nNumberOfBytesToRead & 0xfff)
794 nrpages++;
795
796 map->commitPage(offset & ~0xfff, TRUE, nrpages);
797 }
798 else lpRealBuf = (LPVOID)lpBuffer;
799
800 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
801 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
802 }
803// else {
804 bRC = OSLibDosRead(pHMHandleData->hHMHandle,
805 (PVOID)lpRealBuf,
806 nNumberOfBytesToRead,
807 lpNumberOfBytesRead);
808// }
809
810 if(bRC == 0) {
811 dprintf(("KERNEL32: HMDeviceDiskClass::ReadFile returned %08xh %x", bRC, GetLastError()));
812 dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
813 }
814
815 return bRC;
816}
817/*****************************************************************************
818 * Name : DWORD HMDeviceDiskClass::SetFilePointer
819 * Purpose : set file pointer
820 * Parameters: PHMHANDLEDATA pHMHandleData
821 * LONG lDistanceToMove
822 * PLONG lpDistanceToMoveHigh
823 * DWORD dwMoveMethod
824 * Variables :
825 * Result : API returncode
826 * Remark :
827 * Status :
828 *
829 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
830 *****************************************************************************/
831
832DWORD HMDeviceDiskClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
833 LONG lDistanceToMove,
834 PLONG lpDistanceToMoveHigh,
835 DWORD dwMoveMethod)
836{
837 DWORD ret;
838
839 dprintf2(("KERNEL32: HMDeviceDiskClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
840 lpHMDeviceName,
841 pHMHandleData,
842 lDistanceToMove,
843 lpDistanceToMoveHigh,
844 dwMoveMethod));
845
846 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
847 lDistanceToMove,
848 (DWORD *)lpDistanceToMoveHigh,
849 dwMoveMethod);
850
851 if(ret == -1) {
852 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
853 }
854 return ret;
855}
856//******************************************************************************
857//******************************************************************************
Note: See TracBrowser for help on using the repository browser.