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

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

bugfix

File size: 40.0 KB
Line 
1/* $Id: hmdisk.cpp,v 1.25 2001-10-29 16:29:33 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 {
873 dprintf(("IOCTL_CDROM(DISK/STORAGE)CHECK_VERIFY %s", drvInfo->signature));
874 if(lpBytesReturned) {
875 *lpBytesReturned = 0;
876 }
877#pragma pack(1)
878 typedef struct
879 {
880 BYTE ucCommandInfo;
881 WORD usDriveUnit;
882 } ParameterBlock;
883#pragma pack()
884
885 DWORD parsize = sizeof(ParameterBlock);
886 DWORD datasize = 2;
887 WORD status = 0;
888 DWORD rc;
889 ParameterBlock parm;
890
891 parm.ucCommandInfo = 0;
892 parm.usDriveUnit = drvInfo->driveLetter - 'A';
893 //IOCTL_DISK (0x08), DSK_GETLOCKSTATUS (0x66)
894// rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x08, 0x66, &parm, sizeof(parm), &parsize,
895 //TODO: this doesn't work for floppies for some reason...
896 rc = OSLibDosDevIOCtl(-1, 0x08, 0x66, &parm, sizeof(parm), &parsize,
897 &status, sizeof(status), &datasize);
898 if(rc != NO_ERROR) {
899 dprintf(("OSLibDosDevIOCtl failed with rc %d datasize %d", rc, datasize));
900 return FALSE;
901 }
902 dprintf(("Disk status 0x%x", status));
903 //if no disk present, return FALSE
904 if(!(status & (BIT_2))) {
905 SetLastError(ERROR_NOT_READY); //NT4, SP6 returns this
906 return FALSE;
907 }
908 SetLastError(NO_ERROR);
909 return TRUE;
910 }
911
912 case IOCTL_DISK_EJECT_MEDIA:
913 case IOCTL_STORAGE_EJECT_MEDIA:
914 {
915 dprintf(("Ejecting storage media"));
916 return ioctlDISKUnlockEject(pHMHandleData,
917 0x02, // EJECT media
918 -1,
919 lpBytesReturned);
920 }
921
922 case IOCTL_STORAGE_GET_MEDIA_TYPES:
923 break;
924
925 case IOCTL_STORAGE_LOAD_MEDIA:
926 // case IOCTL_STORAGE_LOAD_MEDIA2:
927 {
928 dprintf(("Loading storage media"));
929 return ioctlDISKUnlockEject(pHMHandleData,
930 0x03, // LOAD media
931 -1,
932 lpBytesReturned);
933 }
934
935 // case IOCTL_STORAGE_EJECTION_CONTROL:
936 case IOCTL_STORAGE_MEDIA_REMOVAL:
937 break;
938
939
940 // -------------------
941 // SCSI passthru class
942 // -------------------
943
944 case IOCTL_SCSI_PASS_THROUGH:
945 case IOCTL_SCSI_MINIPORT:
946 case IOCTL_SCSI_GET_INQUIRY_DATA:
947 case IOCTL_SCSI_GET_CAPABILITIES:
948 break;
949
950 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
951 {
952 PSCSI_PASS_THROUGH_DIRECT pPacket = (PSCSI_PASS_THROUGH_DIRECT)lpOutBuffer;
953 SRB_ExecSCSICmd *psrb;
954
955 if(drvInfo->hInstAspi == NULL) {
956 SetLastError(ERROR_ACCESS_DENIED);
957 return FALSE;
958 }
959
960 if(nOutBufferSize < sizeof(SCSI_PASS_THROUGH_DIRECT) ||
961 !pPacket || pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
962 {
963 SetLastError(ERROR_INSUFFICIENT_BUFFER);
964 return FALSE;
965 }
966 if(lpBytesReturned) {
967 *lpBytesReturned = 0;
968 }
969 psrb = (SRB_ExecSCSICmd *)alloca(sizeof(SRB_ExecSCSICmd)+pPacket->SenseInfoLength);
970 if(psrb == NULL) {
971 dprintf(("not enough memory!!"));
972 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
973 return FALSE;
974 }
975 memset(psrb, 0, sizeof(*psrb));
976 psrb->SRB_Cmd = SC_EXEC_SCSI_CMD;
977 psrb->SRB_Status = pPacket->ScsiStatus;
978 psrb->SRB_HaId = pPacket->PathId;
979 psrb->SRB_Target = pPacket->TargetId;
980 psrb->SRB_Lun = pPacket->Lun;
981 psrb->SRB_BufLen = pPacket->DataTransferLength;
982 psrb->SRB_SenseLen = pPacket->SenseInfoLength;
983 psrb->SRB_CDBLen = pPacket->CdbLength;
984 switch(pPacket->DataIn) {
985 case SCSI_IOCTL_DATA_OUT:
986 psrb->SRB_Flags = 0x2 << 3;
987 break;
988 case SCSI_IOCTL_DATA_IN:
989 psrb->SRB_Flags = 0x1 << 3;
990 break;
991 case SCSI_IOCTL_DATA_UNSPECIFIED:
992 psrb->SRB_Flags = 0x3 << 3;
993 break;
994 }
995 if(pPacket->CdbLength > 16) {
996 SetLastError(ERROR_INVALID_PARAMETER);
997 return FALSE;
998 }
999 dprintf(("IOCTL_SCSI_PASS_THROUGH_DIRECT %x", pPacket->Cdb[0]));
1000 psrb->SRB_BufPointer = (BYTE *)pPacket->DataBuffer;
1001 memcpy(&psrb->CDBByte[0], &pPacket->Cdb[0], 16);
1002 if(psrb->SRB_SenseLen) {
1003 memcpy(&psrb->SenseArea[0], (char *)pPacket + pPacket->SenseInfoOffset, psrb->SRB_SenseLen);
1004 }
1005 //TODO: pPacket->TimeOutValue ignored
1006 int rc = drvInfo->SendASPI32Command((LPSRB)psrb);
1007 if(rc != SS_COMP) {
1008 dprintf(("SendASPI32Command failed with error %d", rc));
1009 if(rc == SS_ERR) {
1010 SetLastError(ERROR_ADAP_HDW_ERR); //returned by NT4, SP6
1011 }
1012 else SetLastError(ERROR_GEN_FAILURE);
1013 return FALSE;
1014 }
1015 pPacket->ScsiStatus = rc;
1016 if(lpBytesReturned) {
1017 *lpBytesReturned = 0;
1018 }
1019 pPacket->DataTransferLength = psrb->SRB_BufLen;
1020 if(psrb->SRB_SenseLen) {
1021 memcpy((char *)pPacket + pPacket->SenseInfoOffset, &psrb->SenseArea[0], psrb->SRB_SenseLen);
1022 }
1023 SetLastError(ERROR_SUCCESS);
1024 return TRUE;
1025 }
1026 case IOCTL_SCSI_GET_ADDRESS:
1027 {
1028 DWORD numAdapters, rc;
1029 SRB srb;
1030 int i, j, k;
1031
1032 if(!lpOutBuffer || nOutBufferSize < 8) {
1033 SetLastError(ERROR_INSUFFICIENT_BUFFER); //todo: right error?
1034 return(FALSE);
1035 }
1036 SCSI_ADDRESS *addr = (SCSI_ADDRESS *)lpOutBuffer;
1037 addr->Length = sizeof(SCSI_ADDRESS);
1038 addr->PortNumber = 0;
1039 addr->PathId = 0;
1040
1041 if(drvInfo->hInstAspi == NULL) {
1042 SetLastError(ERROR_ACCESS_DENIED);
1043 return FALSE;
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)",
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 else dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile read %x bytes", *lpNumberOfBytesRead));
1181
1182 return bRC;
1183}
1184/*****************************************************************************
1185 * Name : DWORD HMDeviceDiskClass::SetFilePointer
1186 * Purpose : set file pointer
1187 * Parameters: PHMHANDLEDATA pHMHandleData
1188 * LONG lDistanceToMove
1189 * PLONG lpDistanceToMoveHigh
1190 * DWORD dwMoveMethod
1191 * Variables :
1192 * Result : API returncode
1193 * Remark :
1194 * Status :
1195 *
1196 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1197 *****************************************************************************/
1198
1199DWORD HMDeviceDiskClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
1200 LONG lDistanceToMove,
1201 PLONG lpDistanceToMoveHigh,
1202 DWORD dwMoveMethod)
1203{
1204 DWORD ret;
1205
1206 dprintf2(("KERNEL32: HMDeviceDiskClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
1207 lpHMDeviceName,
1208 pHMHandleData,
1209 lDistanceToMove,
1210 lpDistanceToMoveHigh,
1211 dwMoveMethod));
1212
1213 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
1214 lDistanceToMove,
1215 (DWORD *)lpDistanceToMoveHigh,
1216 dwMoveMethod);
1217
1218 if(ret == -1) {
1219 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
1220 }
1221 return ret;
1222}
1223//******************************************************************************
1224//******************************************************************************
Note: See TracBrowser for help on using the repository browser.