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

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

implemented several cdrom ioctls

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