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

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

IOCTL_CDROM_READ_TOC fix: add lead-out track

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