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

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

minor updates

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