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

Last change on this file since 7272 was 7272, checked in by sandervl, 24 years ago

IOCTL_CDROM_READ_TOC bugfix

File size: 43.2 KB
Line 
1/* $Id: hmdisk.cpp,v 1.27 2001-10-30 00:46:17 sandervl 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
27#define BIT_0 (1)
28#define BIT_1 (2)
29#define BIT_2 (4)
30#define BIT_11 (1<<11)
31
32typedef struct
33{
34 HINSTANCE hInstAspi;
35 DWORD (WIN32API *GetASPI32SupportInfo)();
36 DWORD (CDECL *SendASPI32Command)(LPSRB lpSRB);
37 ULONG driveLetter;
38 ULONG driveType;
39 CHAR signature[8];
40 DWORD dwAccess;
41 DWORD dwShare;
42 DWORD dwCreation;
43 DWORD dwFlags;
44 LPSECURITY_ATTRIBUTES lpSecurityAttributes;
45 HFILE hTemplate;
46} DRIVE_INFO;
47
48HMDeviceDiskClass::HMDeviceDiskClass(LPCSTR lpDeviceName) : HMDeviceKernelObjectClass(lpDeviceName)
49{
50 HMDeviceRegisterEx("\\\\.\\PHYSICALDRIVE", this, NULL);
51}
52
53/*****************************************************************************
54 * Name : HMDeviceDiskClass::FindDevice
55 * Purpose : Checks if lpDeviceName belongs to this device class
56 * Parameters: LPCSTR lpClassDevName
57 * LPCSTR lpDeviceName
58 * int namelength
59 * Variables :
60 * Result : checks if name is for a drive of physical disk
61 * Remark :
62 * Status :
63 *
64 * Author : SvL
65 *****************************************************************************/
66BOOL HMDeviceDiskClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
67{
68 //\\.\x: -> length 6
69 //\\.\PHYSICALDRIVEn -> length 18
70 if(namelength != 6 && namelength != 18) {
71 return FALSE;
72 }
73
74 //SvL: \\.\x: -> drive x (i.e. \\.\C:)
75 // \\.\PHYSICALDRIVEn -> drive n (n>=0)
76 if((strncmp(lpDeviceName, "\\\\.\\", 4) == 0) &&
77 namelength == 6 && lpDeviceName[5] == ':')
78 {
79 return TRUE;
80 }
81 if((strncmp(lpDeviceName, "\\\\.\\PHYSICALDRIVE", 17) == 0) && namelength == 18) {
82 return TRUE;
83 }
84 return FALSE;
85}
86//******************************************************************************
87//TODO: PHYSICALDRIVEn!!
88//******************************************************************************
89DWORD HMDeviceDiskClass::CreateFile (LPCSTR lpFileName,
90 PHMHANDLEDATA pHMHandleData,
91 PVOID lpSecurityAttributes,
92 PHMHANDLEDATA pHMHandleDataTemplate)
93{
94 HFILE hFile;
95 HFILE hTemplate;
96
97 dprintf2(("KERNEL32: HMDeviceDiskClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
98 lpHMDeviceName,
99 lpFileName,
100 pHMHandleData,
101 lpSecurityAttributes,
102 pHMHandleDataTemplate));
103
104 //TODO: check in NT if CREATE_ALWAYS is allowed!!
105 if(pHMHandleData->dwCreation != OPEN_EXISTING) {
106 dprintf(("Invalid creation flags %x!!", pHMHandleData->dwCreation));
107 return ERROR_INVALID_PARAMETER;
108 }
109 if(strncmp(lpFileName, // "support" for local unc names
110 "\\\\.\\",
111 4) == 0)
112 {
113 lpFileName+=4;
114 }
115
116 //Disable error popus. NT allows an app to open a cdrom/dvd drive without a disk inside
117 //OS/2 fails in that case with error ERROR_NOT_READY
118 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
119 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
120 pHMHandleData->dwAccess,
121 pHMHandleData->dwShare,
122 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
123 pHMHandleData->dwCreation,
124 pHMHandleData->dwFlags,
125 hTemplate);
126 SetErrorMode(oldmode);
127
128 if (hFile != INVALID_HANDLE_ERROR || GetLastError() == ERROR_NOT_READY)
129 {
130 if(hFile == INVALID_HANDLE_ERROR) {
131 dprintf(("Drive not ready"));
132 SetLastError(NO_ERROR);
133 pHMHandleData->hHMHandle = 0; //handle lookup fails if this is set to -1
134 }
135 else pHMHandleData->hHMHandle = hFile;
136
137 DRIVE_INFO *drvInfo = (DRIVE_INFO *)malloc(sizeof(DRIVE_INFO));
138 if(drvInfo == NULL) {
139 if(pHMHandleData->hHMHandle) OSLibDosClose(pHMHandleData->hHMHandle);
140 return ERROR_OUTOFMEMORY;
141 }
142 pHMHandleData->dwUserData = (DWORD)drvInfo;
143
144 memset(drvInfo, 0, sizeof(DRIVE_INFO));
145 drvInfo->dwAccess = pHMHandleData->dwAccess;
146 drvInfo->dwAccess = pHMHandleData->dwShare;
147 drvInfo->lpSecurityAttributes = (LPSECURITY_ATTRIBUTES)lpSecurityAttributes;
148 drvInfo->dwAccess = pHMHandleData->dwCreation;
149 drvInfo->dwAccess = pHMHandleData->dwFlags;
150 drvInfo->hTemplate = hTemplate;
151
152 drvInfo->driveLetter = *lpFileName; //save drive letter
153 if(drvInfo->driveLetter >= 'a') {
154 drvInfo->driveLetter = drvInfo->driveLetter - ((int)'a' - (int)'A');
155 }
156
157 drvInfo->driveType = GetDriveTypeA(lpFileName);
158 if(drvInfo->driveType == DRIVE_CDROM)
159 {
160 drvInfo->hInstAspi = LoadLibraryA("WNASPI32.DLL");
161 if(drvInfo->hInstAspi == NULL) {
162 if(pHMHandleData->hHMHandle) OSLibDosClose(pHMHandleData->hHMHandle);
163 free(drvInfo);
164 return ERROR_INVALID_PARAMETER;
165 }
166 *(FARPROC *)&drvInfo->GetASPI32SupportInfo = GetProcAddress(drvInfo->hInstAspi, "GetASPI32SupportInfo");
167 *(FARPROC *)&drvInfo->SendASPI32Command = GetProcAddress(drvInfo->hInstAspi, "SendASPI32Command");
168
169 if(drvInfo->GetASPI32SupportInfo() == (SS_FAILED_INIT << 8)) {
170 FreeLibrary(drvInfo->hInstAspi);
171 drvInfo->hInstAspi = 0;
172 }
173
174 //get cdrom signature
175 DWORD parsize = 4;
176 DWORD datasize = 4;
177 strcpy(drvInfo->signature, "CD01");
178 OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x80, 0x61, &drvInfo->signature[0], 4, &parsize,
179 &drvInfo->signature[0], 4, &datasize);
180 }
181
182 return (NO_ERROR);
183 }
184 else {
185 dprintf(("CreateFile failed; error %d", GetLastError()));
186 return(GetLastError());
187 }
188}
189//******************************************************************************
190//******************************************************************************
191DWORD HMDeviceDiskClass::OpenDisk(PVOID pDrvInfo)
192{
193 char filename[3];
194 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pDrvInfo;
195 HFILE hFile;
196
197 filename[0] = 'A' + drvInfo->driveLetter;
198 filename[1] = ':';
199 filename[2] = 0;
200
201 //Disable error popus. NT allows an app to open a cdrom/dvd drive without a disk inside
202 //OS/2 fails in that case with error ERROR_NOT_READY
203 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
204 hFile = OSLibDosCreateFile(filename,
205 drvInfo->dwAccess,
206 drvInfo->dwShare,
207 drvInfo->lpSecurityAttributes,
208 drvInfo->dwCreation,
209 drvInfo->dwFlags,
210 drvInfo->hTemplate);
211 SetErrorMode(oldmode);
212
213 if (hFile != INVALID_HANDLE_ERROR || GetLastError() == ERROR_NOT_READY)
214 {
215 if(hFile == INVALID_HANDLE_ERROR) {
216 dprintf(("Drive not ready"));
217 return 0;
218 }
219 else return hFile;
220 }
221 return 0;
222}
223//******************************************************************************
224//******************************************************************************
225BOOL HMDeviceDiskClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
226{
227 BOOL ret = TRUE;
228
229 if(pHMHandleData->hHMHandle) {
230 ret = OSLibDosClose(pHMHandleData->hHMHandle);
231 }
232 if(pHMHandleData->dwUserData) {
233 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
234 if(drvInfo->hInstAspi) FreeLibrary(drvInfo->hInstAspi);
235 free(drvInfo);
236 }
237 return ret;
238}
239//******************************************************************************
240//******************************************************************************
241
242
243// this helper function just calls the specified
244// ioctl function for the CDROM manager with no
245// parameter packet other than the CD01 signature
246// and no data packet.
247static BOOL ioctlCDROMSimple(PHMHANDLEDATA pHMHandleData,
248 DWORD dwCategory,
249 DWORD dwFunction,
250 LPDWORD lpBytesReturned, DRIVE_INFO *pdrvInfo)
251{
252 DWORD dwParameterSize = 4;
253 DWORD dwDataSize = 0;
254 DWORD ret;
255
256 if(lpBytesReturned)
257 *lpBytesReturned = 0;
258
259 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
260 dwCategory,
261 dwFunction,
262 pdrvInfo->signature,
263 4,
264 &dwParameterSize,
265 NULL,
266 0,
267 &dwDataSize);
268 if(ret)
269 {
270 SetLastError(error2WinError(ret));
271 return FALSE;
272 }
273 SetLastError(ERROR_SUCCESS);
274 return TRUE;
275}
276
277
278// this helper function just calls the specified
279// ioctl function for the DISK manager with the
280// specified function codes
281static BOOL ioctlDISKUnlockEject(PHMHANDLEDATA pHMHandleData,
282 DWORD dwCommand,
283 DWORD dwDiskHandle,
284 LPDWORD lpBytesReturned)
285{
286#pragma pack(1)
287 struct
288 {
289 BYTE ucCommand;
290 BYTE ucHandle;
291 } ParameterBlock;
292#pragma pack()
293
294 DWORD dwParameterSize = sizeof( ParameterBlock );
295 DWORD dwDataSize = 0;
296 DWORD ret;
297
298 ParameterBlock.ucCommand = dwCommand;
299 ParameterBlock.ucHandle = dwDiskHandle;
300
301 if(lpBytesReturned)
302 *lpBytesReturned = 0;
303
304 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
305 0x08, // IOCTL_DISK
306 0x40, // DSK_UNLOCKEJECTMEDIA
307 &ParameterBlock,
308 sizeof( ParameterBlock ),
309 &dwParameterSize,
310 NULL,
311 0,
312 &dwDataSize);
313 if(ret)
314 {
315 SetLastError(error2WinError(ret));
316 return FALSE;
317 }
318 SetLastError(ERROR_SUCCESS);
319 return TRUE;
320}
321
322
323
324BOOL HMDeviceDiskClass::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
325 LPVOID lpInBuffer, DWORD nInBufferSize,
326 LPVOID lpOutBuffer, DWORD nOutBufferSize,
327 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
328{
329#ifdef DEBUG
330 char *msg = NULL;
331
332 switch(dwIoControlCode)
333 {
334 case FSCTL_DELETE_REPARSE_POINT:
335 msg = "FSCTL_DELETE_REPARSE_POINT";
336 break;
337 case FSCTL_DISMOUNT_VOLUME:
338 msg = "FSCTL_DISMOUNT_VOLUME";
339 break;
340 case FSCTL_GET_COMPRESSION:
341 msg = "FSCTL_GET_COMPRESSION";
342 break;
343 case FSCTL_GET_REPARSE_POINT:
344 msg = "FSCTL_GET_REPARSE_POINT";
345 break;
346 case FSCTL_LOCK_VOLUME:
347 msg = "FSCTL_LOCK_VOLUME";
348 break;
349 case FSCTL_QUERY_ALLOCATED_RANGES:
350 msg = "FSCTL_QUERY_ALLOCATED_RANGES";
351 break;
352 case FSCTL_SET_COMPRESSION:
353 msg = "FSCTL_SET_COMPRESSION";
354 break;
355 case FSCTL_SET_REPARSE_POINT:
356 msg = "FSCTL_SET_REPARSE_POINT";
357 break;
358 case FSCTL_SET_SPARSE:
359 msg = "FSCTL_SET_SPARSE";
360 break;
361 case FSCTL_SET_ZERO_DATA:
362 msg = "FSCTL_SET_ZERO_DATA";
363 break;
364 case FSCTL_UNLOCK_VOLUME:
365 msg = "FSCTL_UNLOCK_VOLUME";
366 break;
367 case IOCTL_DISK_CHECK_VERIFY:
368 msg = "IOCTL_DISK_CHECK_VERIFY";
369 break;
370 case IOCTL_DISK_EJECT_MEDIA:
371 msg = "IOCTL_DISK_EJECT_MEDIA";
372 break;
373 case IOCTL_DISK_FORMAT_TRACKS:
374 msg = "IOCTL_DISK_FORMAT_TRACKS";
375 break;
376 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
377 msg = "IOCTL_DISK_GET_DRIVE_GEOMETRY";
378 break;
379 case IOCTL_DISK_GET_DRIVE_LAYOUT:
380 msg = "IOCTL_DISK_GET_DRIVE_LAYOUT";
381 break;
382 case IOCTL_DISK_GET_MEDIA_TYPES:
383 msg = "IOCTL_DISK_GET_MEDIA_TYPES";
384 break;
385 case IOCTL_DISK_GET_PARTITION_INFO:
386 msg = "IOCTL_DISK_GET_PARTITION_INFO";
387 break;
388 case IOCTL_DISK_LOAD_MEDIA:
389 msg = "IOCTL_DISK_LOAD_MEDIA";
390 break;
391 case IOCTL_DISK_MEDIA_REMOVAL:
392 msg = "IOCTL_DISK_MEDIA_REMOVAL";
393 break;
394 case IOCTL_DISK_PERFORMANCE:
395 msg = "IOCTL_DISK_PERFORMANCE";
396 break;
397 case IOCTL_DISK_REASSIGN_BLOCKS:
398 msg = "IOCTL_DISK_REASSIGN_BLOCKS";
399 break;
400 case IOCTL_DISK_SET_DRIVE_LAYOUT:
401 msg = "IOCTL_DISK_SET_DRIVE_LAYOUT";
402 break;
403 case IOCTL_DISK_SET_PARTITION_INFO:
404 msg = "IOCTL_DISK_SET_PARTITION_INFO";
405 break;
406 case IOCTL_DISK_VERIFY:
407 msg = "IOCTL_DISK_VERIFY";
408 break;
409 case IOCTL_SERIAL_LSRMST_INSERT:
410 msg = "IOCTL_SERIAL_LSRMST_INSERT";
411 break;
412 case IOCTL_STORAGE_CHECK_VERIFY:
413 msg = "IOCTL_STORAGE_CHECK_VERIFY";
414 break;
415 case IOCTL_STORAGE_EJECT_MEDIA:
416 msg = "IOCTL_STORAGE_EJECT_MEDIA";
417 break;
418 case IOCTL_STORAGE_GET_MEDIA_TYPES:
419 msg = "IOCTL_STORAGE_GET_MEDIA_TYPES";
420 break;
421 case IOCTL_STORAGE_LOAD_MEDIA:
422 msg = "IOCTL_STORAGE_LOAD_MEDIA";
423 break;
424 case IOCTL_STORAGE_MEDIA_REMOVAL:
425 msg = "IOCTL_STORAGE_MEDIA_REMOVAL";
426 break;
427 case IOCTL_SCSI_PASS_THROUGH:
428 msg = "IOCTL_SCSI_PASS_THROUGH";
429 break;
430 case IOCTL_SCSI_MINIPORT:
431 msg = "IOCTL_SCSI_MINIPORT";
432 break;
433 case IOCTL_SCSI_GET_INQUIRY_DATA:
434 msg = "IOCTL_SCSI_GET_INQUIRY_DATA";
435 break;
436 case IOCTL_SCSI_GET_CAPABILITIES:
437 msg = "IOCTL_SCSI_GET_CAPABILITIES";
438 break;
439 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
440 msg = "IOCTL_SCSI_PASS_THROUGH_DIRECT";
441 break;
442 case IOCTL_SCSI_GET_ADDRESS:
443 msg = "IOCTL_SCSI_GET_ADDRESS";
444 break;
445 case IOCTL_SCSI_RESCAN_BUS:
446 msg = "IOCTL_SCSI_RESCAN_BUS";
447 break;
448 case IOCTL_SCSI_GET_DUMP_POINTERS:
449 msg = "IOCTL_SCSI_GET_DUMP_POINTERS";
450 break;
451 case IOCTL_SCSI_FREE_DUMP_POINTERS:
452 msg = "IOCTL_SCSI_FREE_DUMP_POINTERS";
453 break;
454 case IOCTL_IDE_PASS_THROUGH:
455 msg = "IOCTL_IDE_PASS_THROUGH";
456 break;
457 case IOCTL_CDROM_UNLOAD_DRIVER:
458 msg = "IOCTL_CDROM_UNLOAD_DRIVER";
459 break;
460 case IOCTL_CDROM_READ_TOC:
461 msg = "IOCTL_CDROM_READ_TOC";
462 break;
463 case IOCTL_CDROM_GET_CONTROL:
464 msg = "IOCTL_CDROM_GET_CONTROL";
465 break;
466 case IOCTL_CDROM_PLAY_AUDIO_MSF:
467 msg = "IOCTL_CDROM_PLAY_AUDIO_MSF";
468 break;
469 case IOCTL_CDROM_SEEK_AUDIO_MSF:
470 msg = "IOCTL_CDROM_SEEK_AUDIO_MSF";
471 break;
472 case IOCTL_CDROM_STOP_AUDIO:
473 msg = "IOCTL_CDROM_STOP_AUDIO";
474 break;
475 case IOCTL_CDROM_PAUSE_AUDIO:
476 msg = "IOCTL_CDROM_PAUSE_AUDIO";
477 break;
478 case IOCTL_CDROM_RESUME_AUDIO:
479 msg = "IOCTL_CDROM_RESUME_AUDIO";
480 break;
481 case IOCTL_CDROM_GET_VOLUME:
482 msg = "IOCTL_CDROM_GET_VOLUME";
483 break;
484 case IOCTL_CDROM_SET_VOLUME:
485 msg = "IOCTL_CDROM_SET_VOLUME";
486 break;
487 case IOCTL_CDROM_READ_Q_CHANNEL:
488 msg = "IOCTL_CDROM_READ_Q_CHANNEL";
489 break;
490 case IOCTL_CDROM_GET_LAST_SESSION:
491 msg = "IOCTL_CDROM_GET_LAST_SESSION";
492 break;
493 case IOCTL_CDROM_RAW_READ:
494 msg = "IOCTL_CDROM_RAW_READ";
495 break;
496 case IOCTL_CDROM_DISK_TYPE:
497 msg = "IOCTL_CDROM_DISK_TYPE";
498 break;
499 case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
500 msg = "IOCTL_CDROM_GET_DRIVE_GEOMETRY";
501 break;
502 case IOCTL_CDROM_CHECK_VERIFY:
503 msg = "IOCTL_CDROM_CHECK_VERIFY";
504 break;
505 case IOCTL_CDROM_MEDIA_REMOVAL:
506 msg = "IOCTL_CDROM_MEDIA_REMOVAL";
507 break;
508 case IOCTL_CDROM_EJECT_MEDIA:
509 msg = "IOCTL_CDROM_EJECT_MEDIA";
510 break;
511 case IOCTL_CDROM_LOAD_MEDIA:
512 msg = "IOCTL_CDROM_LOAD_MEDIA";
513 break;
514 case IOCTL_CDROM_RESERVE:
515 msg = "IOCTL_CDROM_RESERVE";
516 break;
517 case IOCTL_CDROM_RELEASE:
518 msg = "IOCTL_CDROM_RELEASE";
519 break;
520 case IOCTL_CDROM_FIND_NEW_DEVICES:
521 msg = "IOCTL_CDROM_FIND_NEW_DEVICES";
522 break;
523 }
524 if(msg) {
525 dprintf(("HMDeviceDiskClass::DeviceIoControl %s %x %d %x %d %x %x", msg, lpInBuffer, nInBufferSize,
526 lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped));
527 }
528#endif
529
530 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
531 if(drvInfo == NULL) {
532 dprintf(("ERROR: DeviceIoControl: drvInfo == NULL!!!"));
533 DebugInt3();
534 SetLastError(ERROR_INVALID_HANDLE);
535 return FALSE;
536 }
537 switch(dwIoControlCode)
538 {
539 case FSCTL_DELETE_REPARSE_POINT:
540 case FSCTL_DISMOUNT_VOLUME:
541 case FSCTL_GET_COMPRESSION:
542 case FSCTL_GET_REPARSE_POINT:
543 case FSCTL_LOCK_VOLUME:
544 case FSCTL_QUERY_ALLOCATED_RANGES:
545 case FSCTL_SET_COMPRESSION:
546 case FSCTL_SET_REPARSE_POINT:
547 case FSCTL_SET_SPARSE:
548 case FSCTL_SET_ZERO_DATA:
549 case FSCTL_UNLOCK_VOLUME:
550 break;
551
552 case IOCTL_DISK_FORMAT_TRACKS:
553 case IOCTL_DISK_GET_DRIVE_LAYOUT:
554 break;
555
556 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
557 case IOCTL_DISK_GET_MEDIA_TYPES:
558 {
559 PDISK_GEOMETRY pGeom = (PDISK_GEOMETRY)lpOutBuffer;
560 if(nOutBufferSize < sizeof(DISK_GEOMETRY) || !pGeom) {
561 SetLastError(ERROR_INSUFFICIENT_BUFFER);
562 return FALSE;
563 }
564 if(lpBytesReturned) {
565 *lpBytesReturned = 0;
566 }
567
568 char temp;
569 ULONG bytesread, oldmode;
570 APIRET rc;
571
572 if(!pHMHandleData->hHMHandle) {
573 pHMHandleData->hHMHandle = OpenDisk(drvInfo);
574 if(!pHMHandleData->hHMHandle) {
575 dprintf(("No disk inserted; aborting"));
576 SetLastError(ERROR_NOT_READY);
577 return FALSE;
578 }
579 }
580
581 //Applications can use this IOCTL to check if the floppy has been changed
582 //OSLibDosGetDiskGeometry won't fail when that happens so we read one
583 //byte from the disk and return ERROR_MEDIA_CHANGED if it fails with
584 //ERROR_WRONG_DISK
585 oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
586 rc = OSLibDosRead(pHMHandleData->hHMHandle, (PVOID)&temp,
587 1, &bytesread);
588 SetErrorMode(oldmode);
589 if(rc == FALSE) {
590 dprintf(("IOCTL_DISK_GET_DRIVE_GEOMETRY: DosRead failed with rc %d", GetLastError()));
591 if(GetLastError() == ERROR_WRONG_DISK) {
592 SetLastError(ERROR_MEDIA_CHANGED);
593 return FALSE;
594 }
595 }
596 else OSLibDosSetFilePtr(pHMHandleData->hHMHandle, -1, OSLIB_SETPTR_FILE_CURRENT);
597
598 if(OSLibDosGetDiskGeometry(pHMHandleData->hHMHandle, drvInfo->driveLetter, pGeom) == FALSE) {
599 return FALSE;
600 }
601 if(lpBytesReturned) {
602 *lpBytesReturned = sizeof(DISK_GEOMETRY);
603 }
604 SetLastError(ERROR_SUCCESS);
605 return TRUE;
606 }
607
608 case IOCTL_DISK_GET_PARTITION_INFO:
609 case IOCTL_DISK_LOAD_MEDIA:
610 case IOCTL_DISK_MEDIA_REMOVAL:
611 case IOCTL_DISK_PERFORMANCE:
612 case IOCTL_DISK_REASSIGN_BLOCKS:
613 case IOCTL_DISK_SET_DRIVE_LAYOUT:
614 case IOCTL_DISK_SET_PARTITION_INFO:
615 case IOCTL_DISK_VERIFY:
616 case IOCTL_SERIAL_LSRMST_INSERT:
617 break;
618
619
620 // -----------
621 // CDROM class
622 // -----------
623 case IOCTL_CDROM_READ_TOC:
624 {
625#pragma pack(1)
626 typedef struct
627 {
628 BYTE ucFirstTrack;
629 BYTE ucLastTrack;
630 DWORD ulLeadOutAddr;
631 } AudioDiskInfo;
632 typedef struct
633 {
634 DWORD ulTrackAddr;
635 BYTE ucTrackControl;
636 } AudioTrackInfo;
637 typedef struct
638 {
639 BYTE signature[4];
640 BYTE ucTrack;
641 } ParameterBlock;
642#pragma pack()
643
644 PCDROM_TOC pTOC = (PCDROM_TOC)lpOutBuffer;
645 DWORD rc, numtracks;
646 DWORD parsize = 4;
647 DWORD datasize;
648 AudioDiskInfo diskinfo;
649 AudioTrackInfo trackinfo;
650 ParameterBlock parm;
651
652 if(lpBytesReturned)
653 *lpBytesReturned = 0;
654
655 if(!pTOC) {
656 SetLastError(ERROR_INVALID_PARAMETER);
657 return FALSE;
658 }
659 if(nOutBufferSize < sizeof(CDROM_TOC)) {
660 SetLastError(ERROR_INSUFFICIENT_BUFFER);
661 return FALSE;
662 }
663 memset(pTOC, 0, nOutBufferSize);
664 //IOCTL_CDROMAUDIO (0x81), CDROMAUDIO_GETAUDIODISK (0x61)
665 datasize = sizeof(diskinfo);
666 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x61, &drvInfo->signature[0], 4, &parsize,
667 &diskinfo, sizeof(diskinfo), &datasize);
668 if(rc != NO_ERROR) {
669 dprintf(("OSLibDosDevIOCtl failed with rc %d", rc));
670 return FALSE;
671 }
672 pTOC->FirstTrack = diskinfo.ucFirstTrack;
673 pTOC->LastTrack = diskinfo.ucLastTrack;
674 numtracks = pTOC->LastTrack - pTOC->FirstTrack + 1;
675 dprintf(("first %d, last %d, num %d", pTOC->FirstTrack, pTOC->LastTrack, numtracks));
676
677 //numtracks+1, because we have to add a track at the end
678 int length = 4 + (numtracks+1)*sizeof(TRACK_DATA);
679 //big endian format
680 pTOC->Length[0] = HIBYTE((length-2)); //minus length itself;
681 pTOC->Length[1] = LOBYTE((length-2)); //minus length itself;
682
683 if(nOutBufferSize < length) {
684 SetLastError(ERROR_INSUFFICIENT_BUFFER);
685 return FALSE;
686 }
687
688 for(int i=0;i<numtracks;i++)
689 {
690 parsize = sizeof(parm);
691 memcpy(parm.signature, drvInfo->signature, 4);
692 parm.ucTrack = i;
693
694 datasize = sizeof(trackinfo);
695
696 //IOCTL_CDROMAUDIO (0x81), CDROMAUDIO_GETAUDIOTRACK (0x62)
697 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x62, &parm, sizeof(parm), &parsize,
698 &trackinfo, sizeof(trackinfo), &datasize);
699 if(rc != NO_ERROR) {
700 dprintf(("OSLibDosDevIOCtl failed with rc %d", rc));
701 return FALSE;
702 }
703 pTOC->TrackData[i].TrackNumber = pTOC->FirstTrack + i;
704 pTOC->TrackData[i].Reserved = 0;
705 pTOC->TrackData[i].Control = trackinfo.ucTrackControl >> 4;
706 pTOC->TrackData[i].Adr = trackinfo.ucTrackControl & 0xF;
707 pTOC->TrackData[i].Reserved1 = 0;
708 //big endian format
709 pTOC->TrackData[i].Address[0] = HIBYTE(HIWORD(trackinfo.ulTrackAddr));
710 pTOC->TrackData[i].Address[1] = LOBYTE(HIWORD(trackinfo.ulTrackAddr));
711 pTOC->TrackData[i].Address[2] = HIBYTE(LOWORD(trackinfo.ulTrackAddr));
712 pTOC->TrackData[i].Address[3] = LOBYTE(LOWORD(trackinfo.ulTrackAddr));
713 }
714
715 //Add a track at the end (presumably so the app can determine the size of the 1st track)
716 //That is what NT4, SP6 does anyway
717 pTOC->TrackData[numtracks].TrackNumber = 0xAA;
718 pTOC->TrackData[numtracks].Reserved = 0;
719 pTOC->TrackData[numtracks].Control = pTOC->TrackData[numtracks-1].Control;
720 pTOC->TrackData[numtracks].Adr = pTOC->TrackData[numtracks-1].Adr;
721 pTOC->TrackData[numtracks].Reserved1 = 0;
722 //big endian format
723 //Address of pseudo track is the address of the lead-out track
724 pTOC->TrackData[numtracks].Address[0] = HIBYTE(HIWORD(diskinfo.ulLeadOutAddr));
725 pTOC->TrackData[numtracks].Address[1] = LOBYTE(HIWORD(diskinfo.ulLeadOutAddr));
726 pTOC->TrackData[numtracks].Address[2] = HIBYTE(LOWORD(diskinfo.ulLeadOutAddr));
727 pTOC->TrackData[numtracks].Address[3] = LOBYTE(LOWORD(diskinfo.ulLeadOutAddr));
728
729 if(lpBytesReturned)
730 *lpBytesReturned = length;
731
732 SetLastError(ERROR_SUCCESS);
733 return TRUE;
734 }
735
736 case IOCTL_CDROM_UNLOAD_DRIVER:
737 case IOCTL_CDROM_GET_CONTROL:
738 break;
739
740 case IOCTL_CDROM_PLAY_AUDIO_MSF:
741 {
742 dprintf(("Play CDROM audio playback"));
743
744#pragma pack(1)
745 struct
746 {
747 DWORD ucSignature;
748 BYTE ucAddressingMode;
749 DWORD ulStartingMSF;
750 DWORD ulEndingMSF;
751 } ParameterBlock;
752#pragma pack()
753
754 PCDROM_PLAY_AUDIO_MSF pPlay = (PCDROM_PLAY_AUDIO_MSF)lpInBuffer;
755
756 // setup the parameter block
757
758 memcpy(&ParameterBlock.ucSignature, drvInfo->signature, 4);
759 ParameterBlock.ucAddressingMode = 1; // MSF format
760
761 // @@@PH unknown if this kind of MSF conversion is correct!
762 ParameterBlock.ulStartingMSF = pPlay->StartingM << 16 |
763 pPlay->StartingS << 8 |
764 pPlay->StartingF;
765 ParameterBlock.ulEndingMSF = pPlay->EndingM << 16 |
766 pPlay->EndingS << 8 |
767 pPlay->EndingF;
768
769 DWORD dwParameterSize = sizeof( ParameterBlock );
770 DWORD dwDataSize = 0;
771 DWORD ret;
772
773 if(lpBytesReturned)
774 *lpBytesReturned = 0;
775
776 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
777 0x81, // IOCTL_CDROMAUDIO
778 0x50, // CDROMAUDIO_PLAYAUDIO
779 &ParameterBlock,
780 sizeof( ParameterBlock ),
781 &dwParameterSize,
782 NULL,
783 0,
784 &dwDataSize);
785 if(ret)
786 {
787 SetLastError(error2WinError(ret));
788 return FALSE;
789 }
790 SetLastError(ERROR_SUCCESS);
791 return TRUE;
792 }
793
794 case IOCTL_CDROM_SEEK_AUDIO_MSF:
795 break;
796
797 case IOCTL_CDROM_PAUSE_AUDIO:
798 // NO BREAK CASE
799 // Note: for OS/2, pause and stop seems to be the same!
800
801 case IOCTL_CDROM_STOP_AUDIO:
802 {
803 dprintf(("Stop / pause CDROM audio playback"));
804 return ioctlCDROMSimple(pHMHandleData,
805 0x81, // IOCTL_CDROMAUDIO
806 0x51, // CDROMAUDIO_STOPAUDIO
807 lpBytesReturned, drvInfo);
808 }
809
810 case IOCTL_CDROM_RESUME_AUDIO:
811 {
812 dprintf(("Resume CDROM audio playback"));
813 return ioctlCDROMSimple(pHMHandleData,
814 0x81, // IOCTL_CDROMAUDIO
815 0x52, // CDROMAUDIO_RESUMEAUDIO
816 lpBytesReturned, drvInfo);
817 }
818
819 case IOCTL_CDROM_GET_VOLUME:
820 {
821 PVOLUME_CONTROL pVol = (PVOLUME_CONTROL)lpOutBuffer;
822 char volbuf[8];
823 DWORD parsize, datasize, ret;
824
825 if(nOutBufferSize < sizeof(VOLUME_CONTROL) || !pVol) {
826 SetLastError(ERROR_INSUFFICIENT_BUFFER);
827 return FALSE;
828 }
829 if(lpBytesReturned) {
830 *lpBytesReturned = 0;
831 }
832 parsize = 4;
833 datasize = 8;
834 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x60, drvInfo->signature, 4, &parsize,
835 volbuf, 8, &datasize);
836
837 if(ret) {
838 SetLastError(error2WinError(ret));
839 return FALSE;
840 }
841 if(lpBytesReturned) {
842 *lpBytesReturned = sizeof(VOLUME_CONTROL);
843 }
844 pVol->PortVolume[0] = volbuf[1];
845 pVol->PortVolume[1] = volbuf[3];
846 pVol->PortVolume[2] = volbuf[5];
847 pVol->PortVolume[3] = volbuf[7];
848 SetLastError(ERROR_SUCCESS);
849 return TRUE;
850 }
851
852 case IOCTL_CDROM_SET_VOLUME:
853 {
854 PVOLUME_CONTROL pVol = (PVOLUME_CONTROL)lpInBuffer;
855 char volbuf[8];
856 DWORD parsize, datasize, ret;
857
858 if(nInBufferSize < sizeof(VOLUME_CONTROL) || !pVol) {
859 SetLastError(ERROR_INSUFFICIENT_BUFFER);
860 return FALSE;
861 }
862 if(lpBytesReturned) {
863 *lpBytesReturned = 0;
864 }
865 parsize = 4;
866 datasize = 8;
867 volbuf[0] = 0;
868 volbuf[1] = pVol->PortVolume[0];
869 volbuf[2] = 1;
870 volbuf[3] = pVol->PortVolume[1];
871 volbuf[4] = 2;
872 volbuf[5] = pVol->PortVolume[2];
873 volbuf[6] = 3;
874 volbuf[7] = pVol->PortVolume[3];
875 dprintf(("Set CD volume (%d,%d)(%d,%d)", pVol->PortVolume[0], pVol->PortVolume[1], pVol->PortVolume[2], pVol->PortVolume[3]));
876 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x40, drvInfo->signature, 4, &parsize,
877 volbuf, 8, &datasize);
878
879 if(ret) {
880 SetLastError(error2WinError(ret));
881 return FALSE;
882 }
883 SetLastError(ERROR_SUCCESS);
884 return TRUE;
885 }
886 case IOCTL_CDROM_READ_Q_CHANNEL:
887 case IOCTL_CDROM_GET_LAST_SESSION:
888 case IOCTL_CDROM_RAW_READ:
889 case IOCTL_CDROM_DISK_TYPE:
890 case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
891 case IOCTL_CDROM_MEDIA_REMOVAL:
892 break;
893
894 case IOCTL_CDROM_EJECT_MEDIA:
895 {
896 dprintf(("Eject CDROM media"));
897 return ioctlCDROMSimple(pHMHandleData,
898 0x80, // IOCTL_CDROM
899 0x44, // CDROMDISK_EJECTDISK
900 lpBytesReturned, drvInfo);
901 }
902
903 case IOCTL_CDROM_LOAD_MEDIA:
904 {
905 dprintf(("Loading CDROM media"));
906 return ioctlCDROMSimple(pHMHandleData,
907 0x80, // IOCTL_CDROM
908 0x45, // CDROMDISK_CLOSETRAY
909 lpBytesReturned, drvInfo);
910 }
911
912 case IOCTL_CDROM_RESERVE:
913 case IOCTL_CDROM_RELEASE:
914 case IOCTL_CDROM_FIND_NEW_DEVICES:
915 break;
916
917
918 // -------------
919 // STORAGE class
920 // -------------
921
922 case IOCTL_CDROM_CHECK_VERIFY:
923 if(drvInfo->driveType != DRIVE_CDROM) {
924 SetLastError(ERROR_GEN_FAILURE); //TODO: right error?
925 return FALSE;
926 }
927 //no break;
928 case IOCTL_DISK_CHECK_VERIFY:
929 case IOCTL_STORAGE_CHECK_VERIFY:
930 {
931 dprintf(("IOCTL_CDROM(DISK/STORAGE)CHECK_VERIFY %s", drvInfo->signature));
932 if(lpBytesReturned) {
933 *lpBytesReturned = 0;
934 }
935
936 if(!pHMHandleData->hHMHandle) {
937 pHMHandleData->hHMHandle = OpenDisk(drvInfo);
938 if(!pHMHandleData->hHMHandle) {
939 dprintf(("No disk inserted; aborting"));
940 SetLastError(ERROR_NOT_READY);
941 return FALSE;
942 }
943 }
944
945#pragma pack(1)
946 typedef struct
947 {
948 BYTE ucCommandInfo;
949 WORD usDriveUnit;
950 } ParameterBlock;
951#pragma pack()
952
953 DWORD parsize = sizeof(ParameterBlock);
954 DWORD datasize = 2;
955 WORD status = 0;
956 DWORD rc;
957 ParameterBlock parm;
958
959 parm.ucCommandInfo = 0;
960 parm.usDriveUnit = drvInfo->driveLetter - 'A';
961 //IOCTL_DISK (0x08), DSK_GETLOCKSTATUS (0x66)
962// rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x08, 0x66, &parm, sizeof(parm), &parsize,
963 //TODO: this doesn't work for floppies for some reason...
964 rc = OSLibDosDevIOCtl(-1, 0x08, 0x66, &parm, sizeof(parm), &parsize,
965 &status, sizeof(status), &datasize);
966 if(rc != NO_ERROR) {
967 dprintf(("OSLibDosDevIOCtl failed with rc %d datasize %d", rc, datasize));
968 return FALSE;
969 }
970 dprintf(("Disk status 0x%x", status));
971 //if no disk present, return FALSE
972 if(!(status & (BIT_2))) {
973 SetLastError(ERROR_NOT_READY); //NT4, SP6 returns this
974 return FALSE;
975 }
976 SetLastError(NO_ERROR);
977 return TRUE;
978 }
979
980 case IOCTL_DISK_EJECT_MEDIA:
981 case IOCTL_STORAGE_EJECT_MEDIA:
982 {
983 dprintf(("Ejecting storage media"));
984 return ioctlDISKUnlockEject(pHMHandleData,
985 0x02, // EJECT media
986 -1,
987 lpBytesReturned);
988 }
989
990 case IOCTL_STORAGE_GET_MEDIA_TYPES:
991 break;
992
993 case IOCTL_STORAGE_LOAD_MEDIA:
994 // case IOCTL_STORAGE_LOAD_MEDIA2:
995 {
996 dprintf(("Loading storage media"));
997 return ioctlDISKUnlockEject(pHMHandleData,
998 0x03, // LOAD media
999 -1,
1000 lpBytesReturned);
1001 }
1002
1003 // case IOCTL_STORAGE_EJECTION_CONTROL:
1004 case IOCTL_STORAGE_MEDIA_REMOVAL:
1005 break;
1006
1007
1008 // -------------------
1009 // SCSI passthru class
1010 // -------------------
1011
1012 case IOCTL_SCSI_PASS_THROUGH:
1013 case IOCTL_SCSI_MINIPORT:
1014 case IOCTL_SCSI_GET_INQUIRY_DATA:
1015 case IOCTL_SCSI_GET_CAPABILITIES:
1016 break;
1017
1018 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
1019 {
1020 PSCSI_PASS_THROUGH_DIRECT pPacket = (PSCSI_PASS_THROUGH_DIRECT)lpOutBuffer;
1021 SRB_ExecSCSICmd *psrb;
1022
1023 if(drvInfo->hInstAspi == NULL)
1024 {
1025 SetLastError(ERROR_ACCESS_DENIED);
1026 return FALSE;
1027 }
1028
1029 if(nOutBufferSize < sizeof(SCSI_PASS_THROUGH_DIRECT) ||
1030 !pPacket || pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
1031 {
1032 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1033 return FALSE;
1034 }
1035 if(lpBytesReturned) {
1036 *lpBytesReturned = 0;
1037 }
1038
1039 psrb = (SRB_ExecSCSICmd *)alloca(sizeof(SRB_ExecSCSICmd)+pPacket->SenseInfoLength);
1040 if(psrb == NULL) {
1041 dprintf(("not enough memory!!"));
1042 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1043 return FALSE;
1044 }
1045 memset(psrb, 0, sizeof(*psrb));
1046 psrb->SRB_Cmd = SC_EXEC_SCSI_CMD;
1047 psrb->SRB_Status = pPacket->ScsiStatus;
1048 psrb->SRB_HaId = pPacket->PathId;
1049 psrb->SRB_Target = pPacket->TargetId;
1050 psrb->SRB_Lun = pPacket->Lun;
1051 psrb->SRB_BufLen = pPacket->DataTransferLength;
1052 psrb->SRB_SenseLen = pPacket->SenseInfoLength;
1053 psrb->SRB_CDBLen = pPacket->CdbLength;
1054 switch(pPacket->DataIn) {
1055 case SCSI_IOCTL_DATA_OUT:
1056 psrb->SRB_Flags = 0x2 << 3;
1057 break;
1058 case SCSI_IOCTL_DATA_IN:
1059 psrb->SRB_Flags = 0x1 << 3;
1060 break;
1061 case SCSI_IOCTL_DATA_UNSPECIFIED:
1062 psrb->SRB_Flags = 0x3 << 3;
1063 break;
1064 }
1065 if(pPacket->CdbLength > 16) {
1066 SetLastError(ERROR_INVALID_PARAMETER);
1067 return FALSE;
1068 }
1069 dprintf(("IOCTL_SCSI_PASS_THROUGH_DIRECT %x len %x, %x%02x%02x%02x %x%02x", pPacket->Cdb[0], pPacket->DataTransferLength, pPacket->Cdb[2], pPacket->Cdb[3], pPacket->Cdb[4], pPacket->Cdb[5], pPacket->Cdb[7], pPacket->Cdb[8]));
1070 psrb->SRB_BufPointer = (BYTE *)pPacket->DataBuffer;
1071 memcpy(&psrb->CDBByte[0], &pPacket->Cdb[0], 16);
1072 if(psrb->SRB_SenseLen) {
1073 memcpy(&psrb->SenseArea[0], (char *)pPacket + pPacket->SenseInfoOffset, psrb->SRB_SenseLen);
1074 }
1075 //TODO: pPacket->TimeOutValue ignored
1076 int rc = drvInfo->SendASPI32Command((LPSRB)psrb);
1077 if(rc != SS_COMP) {
1078 dprintf(("SendASPI32Command failed with error %d", rc));
1079 if(rc == SS_ERR) {
1080 SetLastError(ERROR_ADAP_HDW_ERR); //returned by NT4, SP6
1081 }
1082 else SetLastError(ERROR_GEN_FAILURE);
1083 return FALSE;
1084 }
1085 pPacket->ScsiStatus = rc;
1086 if(lpBytesReturned) {
1087 *lpBytesReturned = 0;
1088 }
1089 pPacket->DataTransferLength = psrb->SRB_BufLen;
1090 if(psrb->SRB_SenseLen) {
1091 memcpy((char *)pPacket + pPacket->SenseInfoOffset, &psrb->SenseArea[0], psrb->SRB_SenseLen);
1092 }
1093 SetLastError(ERROR_SUCCESS);
1094 return TRUE;
1095 }
1096 case IOCTL_SCSI_GET_ADDRESS:
1097 {
1098 DWORD numAdapters, rc;
1099 SRB srb;
1100 int i, j, k;
1101
1102 if(!lpOutBuffer || nOutBufferSize < 8) {
1103 SetLastError(ERROR_INSUFFICIENT_BUFFER); //todo: right error?
1104 return(FALSE);
1105 }
1106 SCSI_ADDRESS *addr = (SCSI_ADDRESS *)lpOutBuffer;
1107 addr->Length = sizeof(SCSI_ADDRESS);
1108 addr->PortNumber = 0;
1109 addr->PathId = 0;
1110
1111 if(drvInfo->hInstAspi == NULL) {
1112 SetLastError(ERROR_ACCESS_DENIED);
1113 return FALSE;
1114 }
1115
1116 numAdapters = drvInfo->GetASPI32SupportInfo();
1117
1118 memset(&srb, 0, sizeof(srb));
1119 srb.common.SRB_Cmd = SC_HA_INQUIRY;
1120 rc = drvInfo->SendASPI32Command(&srb);
1121
1122 char drivename[3];
1123 drivename[0] = (char)drvInfo->driveLetter;
1124 drivename[1] = ':';
1125 drivename[2] = 0;
1126
1127 for(i=0;i<LOBYTE(numAdapters);i++) {
1128 for(j=0;j<8;j++) {
1129 for(k=0;k<16;k++) {
1130 memset(&srb, 0, sizeof(srb));
1131 srb.common.SRB_Cmd = SC_GET_DEV_TYPE;
1132 srb.devtype.SRB_HaId = i;
1133 srb.devtype.SRB_Target = j;
1134 srb.devtype.SRB_Lun = k;
1135 rc = drvInfo->SendASPI32Command(&srb);
1136 if(rc == SS_COMP) {
1137 if(srb.devtype.SRB_DeviceType == SS_DEVTYPE_CDROM &&
1138 GetDriveTypeA(drivename) == DRIVE_CDROM)
1139 {
1140 goto done;
1141 }
1142 }
1143 }
1144 }
1145 }
1146done:
1147 if(rc == SS_COMP) {
1148 addr->TargetId = j;
1149 addr->Lun = k;
1150 SetLastError(ERROR_SUCCESS);
1151 }
1152 else SetLastError(ERROR_FILE_NOT_FOUND); //todo
1153 return TRUE;
1154failure:
1155 SetLastError(ERROR_INVALID_PARAMETER); //todo
1156 return FALSE;
1157 }
1158
1159 case IOCTL_SCSI_RESCAN_BUS:
1160 case IOCTL_SCSI_GET_DUMP_POINTERS:
1161 case IOCTL_SCSI_FREE_DUMP_POINTERS:
1162 case IOCTL_IDE_PASS_THROUGH:
1163 break;
1164
1165 }
1166 dprintf(("HMDeviceDiskClass::DeviceIoControl: unimplemented dwIoControlCode=%08lx\n", dwIoControlCode));
1167 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1168 return FALSE;
1169}
1170/*****************************************************************************
1171 * Name : BOOL HMDeviceDiskClass::ReadFile
1172 * Purpose : read data from handle / device
1173 * Parameters: PHMHANDLEDATA pHMHandleData,
1174 * LPCVOID lpBuffer,
1175 * DWORD nNumberOfBytesToRead,
1176 * LPDWORD lpNumberOfBytesRead,
1177 * LPOVERLAPPED lpOverlapped
1178 * Variables :
1179 * Result : Boolean
1180 * Remark :
1181 * Status :
1182 *
1183 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1184 *****************************************************************************/
1185
1186BOOL HMDeviceDiskClass::ReadFile(PHMHANDLEDATA pHMHandleData,
1187 LPCVOID lpBuffer,
1188 DWORD nNumberOfBytesToRead,
1189 LPDWORD lpNumberOfBytesRead,
1190 LPOVERLAPPED lpOverlapped)
1191{
1192 LPVOID lpRealBuf;
1193 Win32MemMap *map;
1194 DWORD offset, bytesread;
1195 BOOL bRC;
1196
1197 dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
1198 lpHMDeviceName,
1199 pHMHandleData,
1200 lpBuffer,
1201 nNumberOfBytesToRead,
1202 lpNumberOfBytesRead,
1203 lpOverlapped));
1204
1205 //SvL: It's legal for this pointer to be NULL
1206 if(lpNumberOfBytesRead)
1207 *lpNumberOfBytesRead = 0;
1208 else
1209 lpNumberOfBytesRead = &bytesread;
1210
1211 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
1212 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
1213 SetLastError(ERROR_INVALID_PARAMETER);
1214 return FALSE;
1215 }
1216
1217 if(!pHMHandleData->hHMHandle) {
1218 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
1219 pHMHandleData->hHMHandle = OpenDisk(drvInfo);
1220 if(!pHMHandleData->hHMHandle) {
1221 dprintf(("No disk inserted; aborting"));
1222 SetLastError(ERROR_NOT_READY);
1223 return -1;
1224 }
1225 }
1226
1227 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
1228 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
1229 }
1230
1231 //SvL: DosRead doesn't like writing to memory addresses returned by
1232 // DosAliasMem -> search for original memory mapped pointer and use
1233 // that one + commit pages if not already present
1234 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
1235 if(map) {
1236 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
1237 DWORD nrpages = nNumberOfBytesToRead/4096;
1238 if(offset & 0xfff)
1239 nrpages++;
1240 if(nNumberOfBytesToRead & 0xfff)
1241 nrpages++;
1242
1243 map->commitPage(offset & ~0xfff, TRUE, nrpages);
1244 }
1245 else lpRealBuf = (LPVOID)lpBuffer;
1246
1247 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
1248 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
1249 }
1250// else {
1251 bRC = OSLibDosRead(pHMHandleData->hHMHandle,
1252 (PVOID)lpRealBuf,
1253 nNumberOfBytesToRead,
1254 lpNumberOfBytesRead);
1255// }
1256
1257 if(bRC == 0) {
1258 dprintf(("KERNEL32: HMDeviceDiskClass::ReadFile returned %08xh %x", bRC, GetLastError()));
1259 dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
1260 }
1261 else dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile read %x bytes pos %x", *lpNumberOfBytesRead, SetFilePointer(pHMHandleData, 0, NULL, FILE_CURRENT)));
1262
1263 return bRC;
1264}
1265/*****************************************************************************
1266 * Name : DWORD HMDeviceDiskClass::SetFilePointer
1267 * Purpose : set file pointer
1268 * Parameters: PHMHANDLEDATA pHMHandleData
1269 * LONG lDistanceToMove
1270 * PLONG lpDistanceToMoveHigh
1271 * DWORD dwMoveMethod
1272 * Variables :
1273 * Result : API returncode
1274 * Remark :
1275 * Status :
1276 *
1277 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1278 *****************************************************************************/
1279
1280DWORD HMDeviceDiskClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
1281 LONG lDistanceToMove,
1282 PLONG lpDistanceToMoveHigh,
1283 DWORD dwMoveMethod)
1284{
1285 DWORD ret;
1286
1287 dprintf2(("KERNEL32: HMDeviceDiskClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
1288 lpHMDeviceName,
1289 pHMHandleData,
1290 lDistanceToMove,
1291 lpDistanceToMoveHigh,
1292 dwMoveMethod));
1293
1294 if(!pHMHandleData->hHMHandle) {
1295 DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
1296 pHMHandleData->hHMHandle = OpenDisk(drvInfo);
1297 if(!pHMHandleData->hHMHandle) {
1298 dprintf(("No disk inserted; aborting"));
1299 SetLastError(ERROR_NOT_READY);
1300 return -1;
1301 }
1302 }
1303
1304 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
1305 lDistanceToMove,
1306 (DWORD *)lpDistanceToMoveHigh,
1307 dwMoveMethod);
1308
1309 if(ret == -1) {
1310 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
1311 }
1312 return ret;
1313}
1314//******************************************************************************
1315//******************************************************************************
Note: See TracBrowser for help on using the repository browser.