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

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

IOCTL_SCSI_GET_ADDRESS: fail if wnaspi32 not loaded

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