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

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

read toc ioctl fixes

File size: 38.8 KB
Line 
1/* $Id: hmdisk.cpp,v 1.20 2001-10-26 14:48:37 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(!pTOC) {
592 SetLastError(ERROR_INVALID_PARAMETER);
593 return FALSE;
594 }
595 if(nOutBufferSize < sizeof(CDROM_TOC)) {
596 SetLastError(ERROR_INSUFFICIENT_BUFFER);
597 return FALSE;
598 }
599
600 //IOCTL_CDROMAUDIO (0x81), CDROMAUDIO_GETAUDIODISK (0x61)
601 datasize = sizeof(diskinfo);
602 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x61, &drvInfo->signature[0], 4, &parsize,
603 &diskinfo, sizeof(diskinfo), &datasize);
604 if(rc != NO_ERROR) {
605 dprintf(("OSLibDosDevIOCtl failed with rc %d", rc));
606 return FALSE;
607 }
608 pTOC->FirstTrack = diskinfo.ucFirstTrack;
609 pTOC->LastTrack = diskinfo.ucLastTrack;
610 numtracks = pTOC->LastTrack - pTOC->FirstTrack + 1;
611 dprintf(("first %d, last %d, num %d", pTOC->FirstTrack, pTOC->LastTrack, numtracks));
612
613 int len = 4 + numtracks*sizeof(TRACK_DATA) - 2; //minus length itself;
614 //big endian format
615 pTOC->Length[0] = HIBYTE(len);
616 pTOC->Length[1] = LOBYTE(len);
617
618 if(nOutBufferSize < 4+numtracks*sizeof(TRACK_DATA)) {
619 SetLastError(ERROR_INSUFFICIENT_BUFFER);
620 return FALSE;
621 }
622
623 for(int i=0;i<numtracks;i++)
624 {
625 parsize = sizeof(parm);
626 memcpy(parm.signature, drvInfo->signature, 4);
627 parm.ucTrack = i;
628
629 datasize = sizeof(trackinfo);
630
631 //IOCTL_CDROMAUDIO (0x81), CDROMAUDIO_GETAUDIOTRACK (0x62)
632 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x62, &parm, sizeof(parm), &parsize,
633 &trackinfo, sizeof(trackinfo), &datasize);
634 if(rc != NO_ERROR) {
635 dprintf(("OSLibDosDevIOCtl failed with rc %d", rc));
636 return FALSE;
637 }
638 pTOC->TrackData[i].TrackNumber = pTOC->FirstTrack + i;
639 pTOC->TrackData[i].Reserved = 0;
640 pTOC->TrackData[i].Control = trackinfo.ucTrackControl >> 4;
641 pTOC->TrackData[i].Adr = trackinfo.ucTrackControl & 0xF;
642 pTOC->TrackData[i].Reserved1 = 0;
643 //big endian format
644 pTOC->TrackData[i].Address[0] = HIWORD(HIBYTE(trackinfo.ulTrackAddr));
645 pTOC->TrackData[i].Address[1] = HIWORD(LOBYTE(trackinfo.ulTrackAddr));
646 pTOC->TrackData[i].Address[2] = LOWORD(HIBYTE(trackinfo.ulTrackAddr));
647 pTOC->TrackData[i].Address[3] = LOWORD(LOBYTE(trackinfo.ulTrackAddr));
648 }
649 if(lpBytesReturned)
650 *lpBytesReturned = 4 + numtracks*sizeof(TRACK_DATA);
651
652 SetLastError(ERROR_SUCCESS);
653 return TRUE;
654 }
655
656 case IOCTL_CDROM_UNLOAD_DRIVER:
657 case IOCTL_CDROM_GET_CONTROL:
658 break;
659
660 case IOCTL_CDROM_PLAY_AUDIO_MSF:
661 {
662 dprintf(("Play CDROM audio playback"));
663
664#pragma pack(1)
665 struct
666 {
667 DWORD ucSignature;
668 BYTE ucAddressingMode;
669 DWORD ulStartingMSF;
670 DWORD ulEndingMSF;
671 } ParameterBlock;
672#pragma pack()
673
674 PCDROM_PLAY_AUDIO_MSF pPlay = (PCDROM_PLAY_AUDIO_MSF)lpInBuffer;
675
676 // setup the parameter block
677
678 memcpy(&ParameterBlock.ucSignature, drvInfo->signature, 4);
679 ParameterBlock.ucAddressingMode = 1; // MSF format
680
681 // @@@PH unknown if this kind of MSF conversion is correct!
682 ParameterBlock.ulStartingMSF = pPlay->StartingM << 16 |
683 pPlay->StartingS << 8 |
684 pPlay->StartingF;
685 ParameterBlock.ulEndingMSF = pPlay->EndingM << 16 |
686 pPlay->EndingS << 8 |
687 pPlay->EndingF;
688
689 DWORD dwParameterSize = sizeof( ParameterBlock );
690 DWORD dwDataSize = 0;
691 DWORD ret;
692
693 if(lpBytesReturned)
694 *lpBytesReturned = 0;
695
696 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle,
697 0x81, // IOCTL_CDROMAUDIO
698 0x50, // CDROMAUDIO_PLAYAUDIO
699 &ParameterBlock,
700 sizeof( ParameterBlock ),
701 &dwParameterSize,
702 NULL,
703 0,
704 &dwDataSize);
705 if(ret)
706 {
707 SetLastError(error2WinError(ret));
708 return FALSE;
709 }
710 SetLastError(ERROR_SUCCESS);
711 return TRUE;
712 }
713
714 case IOCTL_CDROM_SEEK_AUDIO_MSF:
715 break;
716
717 case IOCTL_CDROM_PAUSE_AUDIO:
718 // NO BREAK CASE
719 // Note: for OS/2, pause and stop seems to be the same!
720
721 case IOCTL_CDROM_STOP_AUDIO:
722 {
723 dprintf(("Stop / pause CDROM audio playback"));
724 return ioctlCDROMSimple(pHMHandleData,
725 0x81, // IOCTL_CDROMAUDIO
726 0x51, // CDROMAUDIO_STOPAUDIO
727 lpBytesReturned, drvInfo);
728 }
729
730 case IOCTL_CDROM_RESUME_AUDIO:
731 {
732 dprintf(("Resume CDROM audio playback"));
733 return ioctlCDROMSimple(pHMHandleData,
734 0x81, // IOCTL_CDROMAUDIO
735 0x52, // CDROMAUDIO_RESUMEAUDIO
736 lpBytesReturned, drvInfo);
737 }
738
739 case IOCTL_CDROM_GET_VOLUME:
740 {
741 PVOLUME_CONTROL pVol = (PVOLUME_CONTROL)lpOutBuffer;
742 char volbuf[8];
743 DWORD parsize, datasize, ret;
744
745 if(nOutBufferSize < sizeof(VOLUME_CONTROL) || !pVol) {
746 SetLastError(ERROR_INSUFFICIENT_BUFFER);
747 return FALSE;
748 }
749 if(lpBytesReturned) {
750 *lpBytesReturned = 0;
751 }
752 parsize = 4;
753 datasize = 8;
754 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x60, drvInfo->signature, 4, &parsize,
755 volbuf, 8, &datasize);
756
757 if(ret) {
758 SetLastError(error2WinError(ret));
759 return FALSE;
760 }
761 if(lpBytesReturned) {
762 *lpBytesReturned = sizeof(VOLUME_CONTROL);
763 }
764 pVol->PortVolume[0] = volbuf[1];
765 pVol->PortVolume[1] = volbuf[3];
766 pVol->PortVolume[2] = volbuf[5];
767 pVol->PortVolume[3] = volbuf[7];
768 SetLastError(ERROR_SUCCESS);
769 return TRUE;
770 }
771
772 case IOCTL_CDROM_SET_VOLUME:
773 {
774 PVOLUME_CONTROL pVol = (PVOLUME_CONTROL)lpInBuffer;
775 char volbuf[8];
776 DWORD parsize, datasize, ret;
777
778 if(nInBufferSize < sizeof(VOLUME_CONTROL) || !pVol) {
779 SetLastError(ERROR_INSUFFICIENT_BUFFER);
780 return FALSE;
781 }
782 if(lpBytesReturned) {
783 *lpBytesReturned = 0;
784 }
785 parsize = 4;
786 datasize = 8;
787 volbuf[0] = 0;
788 volbuf[1] = pVol->PortVolume[0];
789 volbuf[2] = 1;
790 volbuf[3] = pVol->PortVolume[1];
791 volbuf[4] = 2;
792 volbuf[5] = pVol->PortVolume[2];
793 volbuf[6] = 3;
794 volbuf[7] = pVol->PortVolume[3];
795 dprintf(("Set CD volume (%d,%d)(%d,%d)", pVol->PortVolume[0], pVol->PortVolume[1], pVol->PortVolume[2], pVol->PortVolume[3]));
796 ret = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x81, 0x40, drvInfo->signature, 4, &parsize,
797 volbuf, 8, &datasize);
798
799 if(ret) {
800 SetLastError(error2WinError(ret));
801 return FALSE;
802 }
803 SetLastError(ERROR_SUCCESS);
804 return TRUE;
805 }
806 case IOCTL_CDROM_READ_Q_CHANNEL:
807 case IOCTL_CDROM_GET_LAST_SESSION:
808 case IOCTL_CDROM_RAW_READ:
809 case IOCTL_CDROM_DISK_TYPE:
810 case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
811 case IOCTL_CDROM_MEDIA_REMOVAL:
812 break;
813
814 case IOCTL_CDROM_EJECT_MEDIA:
815 {
816 dprintf(("Eject CDROM media"));
817 return ioctlCDROMSimple(pHMHandleData,
818 0x80, // IOCTL_CDROM
819 0x44, // CDROMDISK_EJECTDISK
820 lpBytesReturned, drvInfo);
821 }
822
823 case IOCTL_CDROM_LOAD_MEDIA:
824 {
825 dprintf(("Loading CDROM media"));
826 return ioctlCDROMSimple(pHMHandleData,
827 0x80, // IOCTL_CDROM
828 0x45, // CDROMDISK_CLOSETRAY
829 lpBytesReturned, drvInfo);
830 }
831
832 case IOCTL_CDROM_RESERVE:
833 case IOCTL_CDROM_RELEASE:
834 case IOCTL_CDROM_FIND_NEW_DEVICES:
835 break;
836
837
838 // -------------
839 // STORAGE class
840 // -------------
841
842 case IOCTL_CDROM_CHECK_VERIFY:
843 if(drvInfo->driveType != DRIVE_CDROM) {
844 SetLastError(ERROR_GEN_FAILURE); //TODO: right error?
845 return FALSE;
846 }
847 //no break;
848 case IOCTL_DISK_CHECK_VERIFY:
849 case IOCTL_STORAGE_CHECK_VERIFY:
850 dprintf(("IOCTL_CDROM(DISK/STORAGE)CHECK_VERIFY %s", drvInfo->signature));
851 if(lpBytesReturned) {
852 *lpBytesReturned = 0;
853 }
854 //TODO: check if disk has been inserted or removed
855 if(pHMHandleData->hHMHandle == 0) {
856 SetLastError(NO_ERROR); //TODO: correct???
857// SetLastError(ERROR_NOT_READY);
858 return FALSE;
859 }
860
861 if(drvInfo->driveType == DRIVE_CDROM)
862 {
863 DWORD parsize = 4;
864 DWORD datasize = 4;
865 DWORD status = 0;
866 DWORD rc;
867
868 //IOCTL_CDROM (0x80), CDROMDISK_DEVICESTATUS (0x60)
869 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 0x80, 0x60, &drvInfo->signature[0], 4, &parsize,
870 &status, sizeof(status), &datasize);
871 if(rc != NO_ERROR) {
872 dprintf(("OSLibDosDevIOCtl failed with rc %d", rc));
873 return FALSE;
874 }
875 dprintf(("CDROM status 0x%x", status));
876 //if door open or no disk present, return FALSE
877 if(status & (BIT_0|BIT_11)) {
878 rc = FALSE;
879 }
880 else rc = TRUE;
881 SetLastError(NO_ERROR);
882 return rc;
883 }
884 else {
885 dprintf(("IOCTL_STORAGE_CHECK_VERIFY incompletely implemented"));
886 }
887 SetLastError(NO_ERROR);
888 return TRUE;
889
890 case IOCTL_DISK_EJECT_MEDIA:
891 case IOCTL_STORAGE_EJECT_MEDIA:
892 {
893 dprintf(("Ejecting storage media"));
894 return ioctlDISKUnlockEject(pHMHandleData,
895 0x02, // EJECT media
896 -1,
897 lpBytesReturned);
898 }
899
900 case IOCTL_STORAGE_GET_MEDIA_TYPES:
901 break;
902
903 case IOCTL_STORAGE_LOAD_MEDIA:
904 // case IOCTL_STORAGE_LOAD_MEDIA2:
905 {
906 dprintf(("Loading storage media"));
907 return ioctlDISKUnlockEject(pHMHandleData,
908 0x03, // LOAD media
909 -1,
910 lpBytesReturned);
911 }
912
913 // case IOCTL_STORAGE_EJECTION_CONTROL:
914 case IOCTL_STORAGE_MEDIA_REMOVAL:
915 break;
916
917
918 // -------------------
919 // SCSI passthru class
920 // -------------------
921
922 case IOCTL_SCSI_PASS_THROUGH:
923 case IOCTL_SCSI_MINIPORT:
924 case IOCTL_SCSI_GET_INQUIRY_DATA:
925 case IOCTL_SCSI_GET_CAPABILITIES:
926 break;
927
928 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
929 {
930 PSCSI_PASS_THROUGH_DIRECT pPacket = (PSCSI_PASS_THROUGH_DIRECT)lpOutBuffer;
931 SRB_ExecSCSICmd *psrb;
932
933 if(drvInfo->hInstAspi == NULL) {
934 SetLastError(ERROR_ACCESS_DENIED);
935 return FALSE;
936 }
937
938 if(nOutBufferSize < sizeof(SCSI_PASS_THROUGH_DIRECT) ||
939 !pPacket || pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
940 {
941 SetLastError(ERROR_INSUFFICIENT_BUFFER);
942 return FALSE;
943 }
944 if(lpBytesReturned) {
945 *lpBytesReturned = 0;
946 }
947 psrb = (SRB_ExecSCSICmd *)alloca(sizeof(SRB_ExecSCSICmd)+pPacket->SenseInfoLength);
948 if(psrb == NULL) {
949 dprintf(("not enough memory!!"));
950 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
951 return FALSE;
952 }
953 memset(psrb, 0, sizeof(*psrb));
954 psrb->SRB_Cmd = SC_EXEC_SCSI_CMD;
955 psrb->SRB_Status = pPacket->ScsiStatus;
956 psrb->SRB_HaId = pPacket->PathId;
957 psrb->SRB_Target = pPacket->TargetId;
958 psrb->SRB_Lun = pPacket->Lun;
959 psrb->SRB_BufLen = pPacket->DataTransferLength;
960 psrb->SRB_SenseLen = pPacket->SenseInfoLength;
961 psrb->SRB_CDBLen = pPacket->CdbLength;
962 switch(pPacket->DataIn) {
963 case SCSI_IOCTL_DATA_OUT:
964 psrb->SRB_Flags = 0x2 << 3;
965 break;
966 case SCSI_IOCTL_DATA_IN:
967 psrb->SRB_Flags = 0x1 << 3;
968 break;
969 case SCSI_IOCTL_DATA_UNSPECIFIED:
970 psrb->SRB_Flags = 0x3 << 3;
971 break;
972 }
973 if(pPacket->CdbLength > 16) {
974 SetLastError(ERROR_INVALID_PARAMETER);
975 return FALSE;
976 }
977 dprintf(("IOCTL_SCSI_PASS_THROUGH_DIRECT %x", pPacket->Cdb[0]));
978 psrb->SRB_BufPointer = (BYTE *)pPacket->DataBuffer;
979 memcpy(&psrb->CDBByte[0], &pPacket->Cdb[0], 16);
980 if(psrb->SRB_SenseLen) {
981 memcpy(&psrb->SenseArea[0], (char *)pPacket + pPacket->SenseInfoOffset, psrb->SRB_SenseLen);
982 }
983 //TODO: pPacket->TimeOutValue ignored
984 int rc = drvInfo->SendASPI32Command((LPSRB)psrb);
985 if(rc != SS_COMP) {
986 dprintf(("SendASPI32Command failed with error %d", rc));
987 if(rc == SS_ERR) {
988 SetLastError(ERROR_ADAP_HDW_ERR); //returned by NT4, SP6
989 }
990 else SetLastError(ERROR_GEN_FAILURE);
991 return FALSE;
992 }
993 pPacket->ScsiStatus = rc;
994 if(lpBytesReturned) {
995 *lpBytesReturned = 0;
996 }
997 pPacket->DataTransferLength = psrb->SRB_BufLen;
998 if(psrb->SRB_SenseLen) {
999 memcpy((char *)pPacket + pPacket->SenseInfoOffset, &psrb->SenseArea[0], psrb->SRB_SenseLen);
1000 }
1001 SetLastError(ERROR_SUCCESS);
1002 return TRUE;
1003 }
1004 case IOCTL_SCSI_GET_ADDRESS:
1005 {
1006 DWORD numAdapters, rc;
1007 SRB srb;
1008 int i, j, k;
1009
1010 if(!lpOutBuffer || nOutBufferSize < 8) {
1011 SetLastError(ERROR_INSUFFICIENT_BUFFER); //todo: right error?
1012 return(FALSE);
1013 }
1014 SCSI_ADDRESS *addr = (SCSI_ADDRESS *)lpOutBuffer;
1015 addr->Length = sizeof(SCSI_ADDRESS);
1016 addr->PortNumber = 0;
1017 addr->PathId = 0;
1018 numAdapters = drvInfo->GetASPI32SupportInfo();
1019
1020 if(LOBYTE(numAdapters) == 0) {
1021 //testestest
1022 i=j=k=0;
1023 goto done; //failure;
1024 }
1025
1026 memset(&srb, 0, sizeof(srb));
1027 srb.common.SRB_Cmd = SC_HA_INQUIRY;
1028 rc = drvInfo->SendASPI32Command(&srb);
1029
1030 char drivename[3];
1031 drivename[0] = (char)drvInfo->driveLetter;
1032 drivename[1] = ':';
1033 drivename[2] = 0;
1034
1035 for(i=0;i<LOBYTE(numAdapters);i++) {
1036 for(j=0;j<8;j++) {
1037 for(k=0;k<16;k++) {
1038 memset(&srb, 0, sizeof(srb));
1039 srb.common.SRB_Cmd = SC_GET_DEV_TYPE;
1040 srb.devtype.SRB_HaId = i;
1041 srb.devtype.SRB_Target = j;
1042 srb.devtype.SRB_Lun = k;
1043 rc = drvInfo->SendASPI32Command(&srb);
1044 if(rc == SS_COMP) {
1045 if(srb.devtype.SRB_DeviceType == SS_DEVTYPE_CDROM &&
1046 GetDriveTypeA(drivename) == DRIVE_CDROM)
1047 {
1048 goto done;
1049 }
1050 }
1051 }
1052 }
1053 }
1054done:
1055 if(rc == SS_COMP) {
1056 addr->TargetId = j;
1057 addr->Lun = k;
1058 SetLastError(ERROR_SUCCESS);
1059 }
1060 else SetLastError(ERROR_FILE_NOT_FOUND); //todo
1061 return TRUE;
1062failure:
1063 SetLastError(ERROR_INVALID_PARAMETER); //todo
1064 return FALSE;
1065 }
1066
1067 case IOCTL_SCSI_RESCAN_BUS:
1068 case IOCTL_SCSI_GET_DUMP_POINTERS:
1069 case IOCTL_SCSI_FREE_DUMP_POINTERS:
1070 case IOCTL_IDE_PASS_THROUGH:
1071 break;
1072
1073 }
1074 dprintf(("HMDeviceDiskClass::DeviceIoControl: unimplemented dwIoControlCode=%08lx\n", dwIoControlCode));
1075 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1076 return FALSE;
1077}
1078/*****************************************************************************
1079 * Name : BOOL HMDeviceDiskClass::ReadFile
1080 * Purpose : read data from handle / device
1081 * Parameters: PHMHANDLEDATA pHMHandleData,
1082 * LPCVOID lpBuffer,
1083 * DWORD nNumberOfBytesToRead,
1084 * LPDWORD lpNumberOfBytesRead,
1085 * LPOVERLAPPED lpOverlapped
1086 * Variables :
1087 * Result : Boolean
1088 * Remark :
1089 * Status :
1090 *
1091 * Author : Patrick Haller [Wed, 1998/02/11 20:44]
1092 *****************************************************************************/
1093
1094BOOL HMDeviceDiskClass::ReadFile(PHMHANDLEDATA pHMHandleData,
1095 LPCVOID lpBuffer,
1096 DWORD nNumberOfBytesToRead,
1097 LPDWORD lpNumberOfBytesRead,
1098 LPOVERLAPPED lpOverlapped)
1099{
1100 LPVOID lpRealBuf;
1101 Win32MemMap *map;
1102 DWORD offset, bytesread;
1103 BOOL bRC;
1104
1105 dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
1106 lpHMDeviceName,
1107 pHMHandleData,
1108 lpBuffer,
1109 nNumberOfBytesToRead,
1110 lpNumberOfBytesRead,
1111 lpOverlapped));
1112
1113 //SvL: It's legal for this pointer to be NULL
1114 if(lpNumberOfBytesRead)
1115 *lpNumberOfBytesRead = 0;
1116 else
1117 lpNumberOfBytesRead = &bytesread;
1118
1119 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
1120 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
1121 SetLastError(ERROR_INVALID_PARAMETER);
1122 return FALSE;
1123 }
1124 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
1125 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
1126 }
1127
1128 //SvL: DosRead doesn't like writing to memory addresses returned by
1129 // DosAliasMem -> search for original memory mapped pointer and use
1130 // that one + commit pages if not already present
1131 map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
1132 if(map) {
1133 lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
1134 DWORD nrpages = nNumberOfBytesToRead/4096;
1135 if(offset & 0xfff)
1136 nrpages++;
1137 if(nNumberOfBytesToRead & 0xfff)
1138 nrpages++;
1139
1140 map->commitPage(offset & ~0xfff, TRUE, nrpages);
1141 }
1142 else lpRealBuf = (LPVOID)lpBuffer;
1143
1144 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
1145 dprintf(("ERROR: Overlapped IO not yet implememented!!"));
1146 }
1147// else {
1148 bRC = OSLibDosRead(pHMHandleData->hHMHandle,
1149 (PVOID)lpRealBuf,
1150 nNumberOfBytesToRead,
1151 lpNumberOfBytesRead);
1152// }
1153
1154 if(bRC == 0) {
1155 dprintf(("KERNEL32: HMDeviceDiskClass::ReadFile returned %08xh %x", bRC, GetLastError()));
1156 dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
1157 }
1158
1159 return bRC;
1160}
1161/*****************************************************************************
1162 * Name : DWORD HMDeviceDiskClass::SetFilePointer
1163 * Purpose : set file pointer
1164 * Parameters: PHMHANDLEDATA pHMHandleData
1165 * LONG lDistanceToMove
1166 * PLONG lpDistanceToMoveHigh
1167 * DWORD dwMoveMethod
1168 * Variables :
1169 * Result : API returncode
1170 * Remark :
1171 * Status :
1172 *
1173 * Author : Patrick Haller [Wed, 1999/06/17 20:44]
1174 *****************************************************************************/
1175
1176DWORD HMDeviceDiskClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
1177 LONG lDistanceToMove,
1178 PLONG lpDistanceToMoveHigh,
1179 DWORD dwMoveMethod)
1180{
1181 DWORD ret;
1182
1183 dprintf2(("KERNEL32: HMDeviceDiskClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
1184 lpHMDeviceName,
1185 pHMHandleData,
1186 lDistanceToMove,
1187 lpDistanceToMoveHigh,
1188 dwMoveMethod));
1189
1190 ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
1191 lDistanceToMove,
1192 (DWORD *)lpDistanceToMoveHigh,
1193 dwMoveMethod);
1194
1195 if(ret == -1) {
1196 dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
1197 }
1198 return ret;
1199}
1200//******************************************************************************
1201//******************************************************************************
Note: See TracBrowser for help on using the repository browser.