Ignore:
Timestamp:
May 10, 2002, 4:55:13 PM (23 years ago)
Author:
sandervl
Message:

hard disk access updates & fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/hmdisk.cpp

    r8397 r8401  
    1 /* $Id: hmdisk.cpp,v 1.43 2002-05-09 13:55:33 sandervl Exp $ */
     1/* $Id: hmdisk.cpp,v 1.44 2002-05-10 14:55:11 sandervl Exp $ */
    22
    33/*
    44 * Win32 Disk API functions for OS/2
    55 *
    6  * Copyright 2000 Sander van Leeuwen
     6 * Copyright 2000-2002 Sander van Leeuwen
    77 *
    88 *
     
    1212#include <os2win.h>
    1313#include <string.h>
     14#include <stdio.h>
    1415#include <versionos2.h>
    1516
     
    2324#include "oslibdos.h"
    2425#include "osliblvm.h"
     26#include "asmutil.h"
    2527
    2628#define DBG_LOCALLOG    DBG_hmdisk
     
    3537{
    3638    HINSTANCE hInstAspi;
    37     DWORD (WIN32API *GetASPI32SupportInfo)();
    38     DWORD (CDECL *SendASPI32Command)(LPSRB lpSRB);
     39    DWORD     (WIN32API *GetASPI32SupportInfo)();
     40    DWORD     (CDECL *SendASPI32Command)(LPSRB lpSRB);
    3941    ULONG     driveLetter;
    4042    ULONG     driveType;
     
    4749    LPSECURITY_ATTRIBUTES lpSecurityAttributes;
    4850    HFILE     hTemplate;
     51    BOOL      fPhysicalDisk;
     52    LARGE_INTEGER StartingOffset;
     53    LARGE_INTEGER PartitionSize;
     54    LARGE_INTEGER CurrentFilePointer;
     55    CHAR      szVolumeName[256];
    4956} DRIVE_INFO;
    5057
     
    7077BOOL HMDeviceDiskClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
    7178{
    72   // check for "x:"
    73   if (namelength == 2)
    74   {
    75     if (lpDeviceName[1] != ':')
    76       return FALSE;
    77 
    78     if ( (lpDeviceName[0] < 'A') ||
    79          (lpDeviceName[0] > 'Z') )
    80       return FALSE;
    81 
    82     return TRUE;
    83   }
     79    // check for "x:"
     80    if (namelength == 2)
     81    {
     82        if (lpDeviceName[1] != ':')
     83            return FALSE;
     84
     85        if (!( ((lpDeviceName[0] >= 'A') &&
     86                (lpDeviceName[0] <= 'Z')) ||
     87               ((lpDeviceName[0] >= 'a') &&
     88                (lpDeviceName[0] <= 'z')) ))
     89            return FALSE;
     90
     91        return TRUE;
     92    }
    8493
    8594    //\\.\x:                -> length 6
     
    94103    }
    95104
    96     //SvL: \\.\x:             -> drive x (i.e. \\.\C:)
    97     //     \\.\PHYSICALDRIVEn -> drive n (n>=0)
     105    // \\.\x:             -> drive x (i.e. \\.\C:)
     106    // \\.\PHYSICALDRIVEn -> drive n (n>=0)
    98107    if((strncmp(lpDeviceName, "\\\\.\\", 4) == 0) &&
    99108        namelength == 6 && lpDeviceName[5] == ':')
     
    107116}
    108117//******************************************************************************
    109 //TODO: PHYSICALDRIVEn!!
    110118//******************************************************************************
    111119DWORD HMDeviceDiskClass::CreateFile (LPCSTR        lpFileName,
     
    114122                                     PHMHANDLEDATA pHMHandleDataTemplate)
    115123{
    116     HFILE hFile;
    117     HFILE hTemplate;
    118     DWORD dwDriveType;
     124    HFILE               hFile;
     125    HFILE               hTemplate;
     126    DWORD               dwDriveType;
     127    CHAR                szDiskName[256];
     128    CHAR                szVolumeName[256] = "";
     129    VOLUME_DISK_EXTENTS volext = {0};
     130    BOOL                fPhysicalDisk = FALSE;
    119131
    120132    dprintf2(("KERNEL32: HMDeviceDiskClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
    121              lpHMDeviceName,
    122              lpFileName,
    123              pHMHandleData,
    124              lpSecurityAttributes,
    125              pHMHandleDataTemplate));
     133             lpHMDeviceName, lpFileName, pHMHandleData, lpSecurityAttributes, pHMHandleDataTemplate));
    126134
    127135    //TODO: check in NT if CREATE_ALWAYS is allowed!!
     
    136144
    137145    //if volume name, query
    138     if(VERSION_IS_WIN2000_OR_HIGHER() && !strncmp(lpFileName, VOLUME_NAME_PREFIX, sizeof(VOLUME_NAME_PREFIX)-1)) {
    139         char *pszVolume;
    140         int   length;
    141 
    142         //strip volume name prefix (\\\\?\\Volume\\)
    143         length = strlen(lpFileName);
    144         pszVolume = (char *)alloca(length);
    145 
    146         strcpy(pszVolume, &lpFileName[sizeof(VOLUME_NAME_PREFIX)-1+1]);  //-zero term + starting '{'
    147         length -= sizeof(VOLUME_NAME_PREFIX)-1+1;
    148         if(pszVolume[length-2] == '}') {
    149             pszVolume[length-2] = 0;
    150             szDrive[0] = OSLibLVMQueryDriveFromVolumeName(pszVolume);
     146    if(!strncmp(lpFileName, VOLUME_NAME_PREFIX, sizeof(VOLUME_NAME_PREFIX)-1))
     147    {
     148        int length;
     149
     150        if(!VERSION_IS_WIN2000_OR_HIGHER()) {
     151            return ERROR_FILE_NOT_FOUND;    //not allowed
     152        }
     153        if(OSLibLVMStripVolumeName(lpFileName, szVolumeName, sizeof(szVolumeName)))
     154        {
     155            BOOL fLVMVolume;
     156
     157            dwDriveType = GetDriveTypeA(lpFileName);
     158
     159            szDrive[0] = OSLibLVMQueryDriveFromVolumeName(szVolumeName);
     160            if(szDrive[0] == -1) {
     161                return ERROR_FILE_NOT_FOUND;    //not found
     162            }
     163            if((dwDriveType == DRIVE_FIXED) && OSLibLVMGetVolumeExtents(szDrive[0], szVolumeName, &volext, &fLVMVolume) == FALSE) {
     164                return ERROR_FILE_NOT_FOUND;    //not found
     165            }
     166            if(szDrive[0] == 0)
     167            {
     168                //volume isn't mounted
     169               
     170                //Note: this only works on Warp 4.5 and up
     171                sprintf(szDiskName, "\\\\.\\Physical_Disk%d", volext.Extents[0].DiskNumber);
     172                fPhysicalDisk = TRUE;
     173
     174                if(fLVMVolume && (pHMHandleData->dwAccess & GENERIC_WRITE)) {
     175                    //no write access allowed for LVM volumes
     176                    dprintf(("CreateFile: WARNING: Write access to LVM volume denied!!"));
     177                    pHMHandleData->dwAccess &= ~GENERIC_WRITE;
     178                }
     179            }
     180            else {
     181                //mounted drive, make sure access requested is readonly, else fail
     182                if(pHMHandleData->dwAccess & GENERIC_WRITE) {
     183                    //no write access allowed for mounted partitions
     184                    dprintf(("CreateFile: WARNING: Write access to mounted partition denied!!"));
     185                    pHMHandleData->dwAccess &= ~GENERIC_WRITE;
     186                }
     187                strcpy(szDiskName, szDrive);
     188            }
    151189        }
    152190        else return ERROR_FILE_NOT_FOUND;
    153 
     191    }
     192    else
     193    if(strncmp(lpFileName, "\\\\.\\PHYSICALDRIVE", 17) == 0)
     194    {
     195        //Note: this only works on Warp 4.5 and up
     196        sprintf(szDiskName, "\\\\.\\Physical_Disk%c", lpFileName[17]);
     197        fPhysicalDisk = TRUE;
     198
     199        //TODO: could be removable in theory
     200        dwDriveType = DRIVE_FIXED;
     201
     202        if(pHMHandleData->dwAccess & GENERIC_WRITE) {
     203            //no write access allowed for whole disks
     204            dprintf(("CreateFile: WARNING: Write access to whole disk denied!!"));
     205            pHMHandleData->dwAccess &= ~GENERIC_WRITE;
     206        }
    154207    }
    155208    else {
     209        strcpy(szDiskName, lpFileName);
    156210        szDrive[0] = *lpFileName;
    157     }
    158     dwDriveType = GetDriveTypeA(szDrive);
     211        dwDriveType = GetDriveTypeA(szDrive);
     212    }
    159213
    160214    //Disable error popus. NT allows an app to open a cdrom/dvd drive without a disk inside
    161215    //OS/2 fails in that case with error ERROR_NOT_READY
    162216    ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS);
    163     hFile = OSLibDosCreateFile((LPSTR)lpFileName,
     217    hFile = OSLibDosCreateFile(szDiskName,
    164218                               pHMHandleData->dwAccess,
    165219                               pHMHandleData->dwShare,
     
    177231    {
    178232        pHMHandleData->dwAccess &= ~GENERIC_WRITE;
    179         hFile = OSLibDosCreateFile((LPSTR)lpFileName,
     233        hFile = OSLibDosCreateFile((LPSTR)szDiskName,
    180234                                   pHMHandleData->dwAccess,
    181235                                   pHMHandleData->dwShare,
     
    211265        drvInfo->dwAccess  = pHMHandleData->dwFlags;
    212266        drvInfo->hTemplate = hTemplate;
     267
     268        //save volume start & length if volume must be accessed through the physical disk
     269        //(no other choice for unmounted volumes)
     270        drvInfo->fPhysicalDisk  = fPhysicalDisk;
     271        drvInfo->StartingOffset = volext.Extents[0].StartingOffset;
     272        drvInfo->PartitionSize  = volext.Extents[0].ExtentLength;
     273
     274        //save volume name for later (IOCtls)
     275        strncpy(drvInfo->szVolumeName, szVolumeName, sizeof(drvInfo->szVolumeName)-1);
    213276
    214277        drvInfo->driveLetter = *lpFileName; //save drive letter
     
    242305        }
    243306
    244         if(hFile) {
     307        if(hFile && drvInfo->driveType != DRIVE_FIXED) {
    245308            OSLibDosQueryVolumeSerialAndName(1 + drvInfo->driveLetter - 'A', &drvInfo->dwVolumelabel, NULL, 0);
    246309        }
    247310
     311        //for an unmounted partition we open the physical disk that contains it, so we
     312        //must set the file pointer to the correct beginning
     313        if(drvInfo->fPhysicalDisk && (drvInfo->StartingOffset.HighPart != 0 ||
     314           drvInfo->StartingOffset.LowPart != 0))
     315        {
     316            SetFilePointer(pHMHandleData, 0, NULL, FILE_BEGIN);
     317        }
    248318        return (NO_ERROR);
    249319    }
     
    618688    {
    619689        APIRET rc;
    620         DWORD ret;
     690            DWORD ret;
    621691        ULONG  ulBytesRead    = 0;      /* Number of bytes read by DosRead */
    622692        ULONG  ulWrote        = 0;      /* Number of bytes written by DosWrite */
     
    638708            return FALSE;
    639709        }
     710        else
     711        if(drvInfo->driveType == DRIVE_FIXED) {
     712            SetLastError(ERROR_SUCCESS);
     713            return TRUE;
     714        }
    640715
    641716        OSLibDosDevIOCtl(pHMHandleData->hHMHandle,IOCTL_DISK,DSK_LOCKDRIVE,0,0,0,0,0,0);
     
    720795        //label has changed
    721796        //TODO: Find better way to determine if floppy was removed or switched
    722         rc = OSLibDosQueryVolumeSerialAndName(1 + drvInfo->driveLetter - 'A', &volumelabel, NULL, 0);
    723         if(rc) {
    724             dprintf(("IOCTL_DISK_GET_DRIVE_GEOMETRY: OSLibDosQueryVolumeSerialAndName failed with rc %d", GetLastError()));
    725             if(pHMHandleData->hHMHandle) OSLibDosClose(pHMHandleData->hHMHandle);
    726             pHMHandleData->hHMHandle = 0;
    727             SetLastError(ERROR_MEDIA_CHANGED);
    728             return FALSE;
    729         }
    730         if(volumelabel != drvInfo->dwVolumelabel) {
    731             dprintf(("IOCTL_DISK_GET_DRIVE_GEOMETRY: volume changed %x -> %x", drvInfo->dwVolumelabel, volumelabel));
    732             SetLastError(ERROR_MEDIA_CHANGED);
    733             return FALSE;
     797        if(drvInfo->driveType != DRIVE_FIXED)
     798        {
     799            rc = OSLibDosQueryVolumeSerialAndName(1 + drvInfo->driveLetter - 'A', &volumelabel, NULL, 0);
     800            if(rc) {
     801                dprintf(("IOCTL_DISK_GET_DRIVE_GEOMETRY: OSLibDosQueryVolumeSerialAndName failed with rc %d", GetLastError()));
     802                if(pHMHandleData->hHMHandle) OSLibDosClose(pHMHandleData->hHMHandle);
     803                pHMHandleData->hHMHandle = 0;
     804                SetLastError(ERROR_MEDIA_CHANGED);
     805                return FALSE;
     806            }
     807            if(volumelabel != drvInfo->dwVolumelabel) {
     808                dprintf(("IOCTL_DISK_GET_DRIVE_GEOMETRY: volume changed %x -> %x", drvInfo->dwVolumelabel, volumelabel));
     809                SetLastError(ERROR_MEDIA_CHANGED);
     810                return FALSE;
     811            }
    734812        }
    735813
     
    754832            *lpBytesReturned = sizeof(PARTITION_INFORMATION);
    755833        }
    756         if(OSLibLVMGetPartitionInfo(drvInfo->driveLetter, pPartition)) {
     834        if(OSLibLVMGetPartitionInfo(drvInfo->driveLetter, drvInfo->szVolumeName, pPartition) == FALSE) {
    757835            SetLastError(ERROR_NOT_ENOUGH_MEMORY); //wrong error, but who cares
    758836            return FALSE;
     
    781859            return FALSE;
    782860        }
    783         if(OSLibLVMGetVolumeExtents(drvInfo->driveLetter, pVolExtent)) {
     861        if(OSLibLVMGetVolumeExtents(drvInfo->driveLetter, drvInfo->szVolumeName, pVolExtent) == FALSE) {
    784862            SetLastError(ERROR_NOT_ENOUGH_MEMORY); //wrong error, but who cares
    785863            return FALSE;
     
    816894        } ParameterBlock;
    817895#pragma pack()
    818 
    819896        PCDROM_TOC pTOC = (PCDROM_TOC)lpOutBuffer;
    820897        DWORD rc, numtracks;
     
    915992    case IOCTL_CDROM_PLAY_AUDIO_MSF:
    916993    {
    917       dprintf(("Play CDROM audio playback"));
    918 
    919994#pragma pack(1)
    920995      struct
     
    9261001      } ParameterBlock;
    9271002#pragma pack()
     1003      dprintf(("Play CDROM audio playback"));
    9281004
    9291005      PCDROM_PLAY_AUDIO_MSF pPlay = (PCDROM_PLAY_AUDIO_MSF)lpInBuffer;
     
    10961172    case IOCTL_STORAGE_CHECK_VERIFY:
    10971173    {
     1174#pragma pack(1)
     1175      typedef struct
     1176      {
     1177        BYTE  ucCommandInfo;
     1178        WORD  usDriveUnit;
     1179      } ParameterBlock;
     1180#pragma pack()
     1181
    10981182        dprintf(("IOCTL_CDROM(DISK/STORAGE)CHECK_VERIFY %s", drvInfo->signature));
    10991183        if(lpBytesReturned) {
     
    11091193            }
    11101194        }
    1111 
    1112 #pragma pack(1)
    1113       typedef struct
    1114       {
    1115         BYTE  ucCommandInfo;
    1116         WORD  usDriveUnit;
    1117       } ParameterBlock;
    1118 #pragma pack()
    11191195
    11201196        DWORD parsize = sizeof(ParameterBlock);
     
    13541430                                 LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    13551431{
    1356   LPVOID       lpRealBuf;
    1357   Win32MemMap *map;
    1358   DWORD        offset, bytesread;
    1359   BOOL         bRC;
    1360 
    1361   dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
    1362            lpHMDeviceName,
    1363            pHMHandleData,
    1364            lpBuffer,
    1365            nNumberOfBytesToRead,
    1366            lpNumberOfBytesRead,
    1367            lpOverlapped));
    1368 
    1369   //SvL: It's legal for this pointer to be NULL
    1370   if(lpNumberOfBytesRead)
    1371     *lpNumberOfBytesRead = 0;
    1372   else
    1373     lpNumberOfBytesRead = &bytesread;
    1374 
    1375   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
    1376     dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
    1377     SetLastError(ERROR_INVALID_PARAMETER);
    1378     return FALSE;
    1379   }
    1380 
    1381   if(lpCompletionRoutine) {
    1382       dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
    1383   }
    1384 
    1385   //If we didn't get an OS/2 handle for the disk before, get one now
    1386   if(!pHMHandleData->hHMHandle) {
    1387       DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
    1388       pHMHandleData->hHMHandle = OpenDisk(drvInfo);
    1389       if(!pHMHandleData->hHMHandle) {
    1390           dprintf(("No disk inserted; aborting"));
    1391           SetLastError(ERROR_NOT_READY);
    1392           return FALSE;
    1393       }
    1394   }
    1395 
    1396   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
    1397     dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
    1398   }
    1399 
    1400   //SvL: DosRead doesn't like writing to memory addresses returned by
    1401   //     DosAliasMem -> search for original memory mapped pointer and use
    1402   //     that one + commit pages if not already present
    1403   map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
    1404   if(map) {
    1405     lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
    1406     DWORD nrpages = nNumberOfBytesToRead/4096;
    1407     if(offset & 0xfff)
    1408         nrpages++;
    1409     if(nNumberOfBytesToRead & 0xfff)
    1410         nrpages++;
    1411 
    1412     map->commitPage(offset & ~0xfff, TRUE, nrpages);
    1413   }
    1414   else  lpRealBuf = (LPVOID)lpBuffer;
    1415 
    1416   if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
    1417     dprintf(("ERROR: Overlapped IO not yet implememented!!"));
    1418   }
    1419 //  else {
     1432    LPVOID       lpRealBuf;
     1433    Win32MemMap *map;
     1434    DWORD        offset, bytesread;
     1435    BOOL         bRC;
     1436
     1437    dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
     1438               lpHMDeviceName, pHMHandleData, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped));
     1439
     1440    //It's legal for this pointer to be NULL
     1441    if(lpNumberOfBytesRead)
     1442        *lpNumberOfBytesRead = 0;
     1443    else
     1444        lpNumberOfBytesRead = &bytesread;
     1445
     1446    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
     1447        dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
     1448        SetLastError(ERROR_INVALID_PARAMETER);
     1449        return FALSE;
     1450    }
     1451
     1452    if(lpCompletionRoutine) {
     1453        dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
     1454    }
     1455
     1456    //If we didn't get an OS/2 handle for the disk before, get one now
     1457    if(!pHMHandleData->hHMHandle) {
     1458        DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
     1459        pHMHandleData->hHMHandle = OpenDisk(drvInfo);
     1460        if(!pHMHandleData->hHMHandle) {
     1461            dprintf(("No disk inserted; aborting"));
     1462            SetLastError(ERROR_NOT_READY);
     1463            return FALSE;
     1464        }
     1465    }
     1466
     1467    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
     1468        dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
     1469    }
     1470
     1471    //SvL: DosRead doesn't like writing to memory addresses returned by
     1472    //     DosAliasMem -> search for original memory mapped pointer and use
     1473    //     that one + commit pages if not already present
     1474    map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_WRITE);
     1475    if(map) {
     1476        lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
     1477        DWORD nrpages = nNumberOfBytesToRead/4096;
     1478        if(offset & 0xfff)
     1479            nrpages++;
     1480        if(nNumberOfBytesToRead & 0xfff)
     1481            nrpages++;
     1482   
     1483        map->commitPage(offset & ~0xfff, TRUE, nrpages);
     1484    }
     1485    else  lpRealBuf = (LPVOID)lpBuffer;
     1486
     1487    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
     1488        dprintf(("ERROR: Overlapped IO not yet implememented!!"));
     1489    }
     1490    //  else {
    14201491    bRC = OSLibDosRead(pHMHandleData->hHMHandle,
    14211492                           (PVOID)lpRealBuf,
     
    14241495//  }
    14251496
    1426   if(bRC == 0) {
    1427       dprintf(("KERNEL32: HMDeviceDiskClass::ReadFile returned %08xh %x", bRC, GetLastError()));
    1428       dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
    1429   }
    1430   else dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile read %x bytes pos %x", *lpNumberOfBytesRead, SetFilePointer(pHMHandleData, 0, NULL, FILE_CURRENT)));
    1431 
    1432   return bRC;
     1497    if(bRC == 0) {
     1498        dprintf(("KERNEL32: HMDeviceDiskClass::ReadFile returned %08xh %x", bRC, GetLastError()));
     1499        dprintf(("%x -> %d", lpBuffer, IsBadWritePtr((LPVOID)lpBuffer, nNumberOfBytesToRead)));
     1500    }
     1501    else dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile read %x bytes pos %x", *lpNumberOfBytesRead, SetFilePointer(pHMHandleData, 0, NULL, FILE_CURRENT)));
     1502
     1503    return bRC;
    14331504}
    14341505/*****************************************************************************
     
    14461517 * Author    : Patrick Haller [Wed, 1999/06/17 20:44]
    14471518 *****************************************************************************/
    1448 
    14491519DWORD HMDeviceDiskClass::SetFilePointer(PHMHANDLEDATA pHMHandleData,
    14501520                                        LONG          lDistanceToMove,
     
    14521522                                        DWORD         dwMoveMethod)
    14531523{
    1454   DWORD ret;
    1455 
    1456   dprintf2(("KERNEL32: HMDeviceDiskClass::SetFilePointer %s(%08xh,%08xh,%08xh,%08xh)\n",
    1457            lpHMDeviceName,
    1458            pHMHandleData,
    1459            lDistanceToMove,
    1460            lpDistanceToMoveHigh,
    1461            dwMoveMethod));
    1462 
    1463   if(!pHMHandleData->hHMHandle) {
    1464       DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
    1465       pHMHandleData->hHMHandle = OpenDisk(drvInfo);
    1466       if(!pHMHandleData->hHMHandle) {
    1467           dprintf(("No disk inserted; aborting"));
    1468           SetLastError(ERROR_NOT_READY);
    1469           return -1;
    1470       }
    1471   }
    1472 
    1473   ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
    1474                                lDistanceToMove,
    1475                                (DWORD *)lpDistanceToMoveHigh,
    1476                                dwMoveMethod);
    1477 
    1478   if(ret == -1) {
    1479       dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
    1480   }
    1481   return ret;
     1524    DWORD ret;
     1525
     1526    if(lpDistanceToMoveHigh) {
     1527        dprintf(("KERNEL32: HMDeviceDiskClass::SetFilePointer %s %08x%08x %d",
     1528                 lpHMDeviceName, *lpDistanceToMoveHigh, lDistanceToMove, dwMoveMethod));
     1529    }
     1530
     1531    DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
     1532    if(drvInfo == NULL) {
     1533        dprintf(("ERROR: SetFilePointer: drvInfo == NULL!!!"));
     1534        DebugInt3();
     1535        SetLastError(ERROR_INVALID_HANDLE);
     1536        return FALSE;
     1537    }
     1538
     1539    if(!pHMHandleData->hHMHandle) {
     1540        DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
     1541        pHMHandleData->hHMHandle = OpenDisk(drvInfo);
     1542        if(!pHMHandleData->hHMHandle) {
     1543            dprintf(("No disk inserted; aborting"));
     1544            SetLastError(ERROR_NOT_READY);
     1545            return -1;
     1546        }
     1547    }
     1548
     1549    //if unmounted volume, add starting offset to position as we're accessing the entire physical drive
     1550    //instead of just the volume
     1551    if(drvInfo->fPhysicalDisk && (drvInfo->StartingOffset.HighPart != 0 ||
     1552       drvInfo->StartingOffset.LowPart != 0))
     1553    {
     1554        LARGE_INTEGER distance, result, endpos;
     1555        LARGE_INTEGER position;
     1556
     1557        if(lpDistanceToMoveHigh) {
     1558            distance.HighPart =  *lpDistanceToMoveHigh;
     1559        }
     1560        else {
     1561            if(lDistanceToMove < 0) {
     1562                 distance.HighPart = -1;
     1563            }
     1564            else distance.HighPart = 0;
     1565        }
     1566        distance.LowPart = lDistanceToMove;
     1567
     1568        //calculate end position in partition
     1569        Add64(&drvInfo->StartingOffset, &drvInfo->PartitionSize, &endpos);
     1570        result.HighPart = 0;
     1571        result.LowPart  = 1;
     1572        Sub64(&endpos, &result, &endpos);
     1573
     1574        switch(dwMoveMethod) {
     1575        case FILE_BEGIN:
     1576            Add64(&distance, &drvInfo->StartingOffset, &result);
     1577            break;
     1578        case FILE_CURRENT:
     1579            Add64(&distance, &drvInfo->CurrentFilePointer, &result);
     1580            break;
     1581        case FILE_END:
     1582            Add64(&distance, &endpos, &result);
     1583            break;
     1584        }
     1585        //check upper boundary
     1586        if(result.HighPart > endpos.HighPart ||
     1587           (result.HighPart == endpos.HighPart && result.LowPart > endpos.LowPart) )
     1588        {
     1589            SetLastError(ERROR_INVALID_PARAMETER);
     1590            return -1;
     1591        }
     1592        //check lower boundary
     1593        if(result.HighPart < drvInfo->StartingOffset.HighPart ||
     1594           (result.HighPart == drvInfo->StartingOffset.HighPart && result.LowPart < drvInfo->StartingOffset.LowPart))
     1595        {
     1596            SetLastError(ERROR_NEGATIVE_SEEK);
     1597            return -1;
     1598        }
     1599
     1600        dprintf(("SetFilePointer (unmounted partition) %08x%08x -> %08x%08x", distance.HighPart, distance.LowPart, result.HighPart, result.LowPart));
     1601        ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
     1602                                     result.LowPart,
     1603                                     (DWORD *)&result.HighPart,
     1604                                     FILE_BEGIN);
     1605
     1606        Sub64(&result, &drvInfo->StartingOffset, &drvInfo->CurrentFilePointer);
     1607        ret = drvInfo->CurrentFilePointer.LowPart;
     1608        if(lpDistanceToMoveHigh) {
     1609            *lpDistanceToMoveHigh = drvInfo->CurrentFilePointer.HighPart;
     1610        }
     1611    }
     1612    else {
     1613        ret = OSLibDosSetFilePointer(pHMHandleData->hHMHandle,
     1614                                     lDistanceToMove,
     1615                                     (DWORD *)lpDistanceToMoveHigh,
     1616                                     dwMoveMethod);
     1617    }
     1618
     1619    if(ret == -1) {
     1620        dprintf(("SetFilePointer failed (error = %d)", GetLastError()));
     1621    }
     1622    return ret;
    14821623}
    14831624
     
    14991640
    15001641BOOL HMDeviceDiskClass::WriteFile(PHMHANDLEDATA pHMHandleData,
    1501                                     LPCVOID       lpBuffer,
    1502                                     DWORD         nNumberOfBytesToWrite,
    1503                                     LPDWORD       lpNumberOfBytesWritten,
    1504                                     LPOVERLAPPED  lpOverlapped,
    1505                                     LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
     1642                                  LPCVOID       lpBuffer,
     1643                                  DWORD         nNumberOfBytesToWrite,
     1644                                  LPDWORD       lpNumberOfBytesWritten,
     1645                                  LPOVERLAPPED  lpOverlapped,
     1646                                  LPOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine)
    15061647{
    1507   LPVOID       lpRealBuf;
    1508   Win32MemMap *map;
    1509   DWORD        offset, byteswritten;
    1510   BOOL         bRC;
    1511 
    1512    dprintf2(("KERNEL32: HMDeviceDiskClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
    1513            lpHMDeviceName,
    1514            pHMHandleData,
    1515            lpBuffer,
    1516            nNumberOfBytesToWrite,
    1517            lpNumberOfBytesWritten,
    1518            lpOverlapped));
    1519 
    1520   DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
    1521   if(drvInfo == NULL) {
    1522       dprintf(("ERROR: DeviceIoControl: drvInfo == NULL!!!"));
    1523       DebugInt3();
    1524       SetLastError(ERROR_INVALID_HANDLE);
    1525       return FALSE;
    1526   }
    1527 
    1528   //SvL: It's legal for this pointer to be NULL
    1529   if(lpNumberOfBytesWritten)
    1530     *lpNumberOfBytesWritten = 0;
    1531   else
    1532     lpNumberOfBytesWritten = &byteswritten;
    1533 
    1534   if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
    1535     dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
    1536     SetLastError(ERROR_INVALID_PARAMETER);
    1537     return FALSE;
    1538   }
    1539   if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
    1540       dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
    1541   }
    1542   if(lpCompletionRoutine) {
    1543       dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
    1544   }
    1545 
    1546   //If we didn't get an OS/2 handle for the disk before, get one now
    1547   if(!pHMHandleData->hHMHandle) {
    1548       DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
    1549       pHMHandleData->hHMHandle = OpenDisk(drvInfo);
    1550       if(!pHMHandleData->hHMHandle) {
    1551           dprintf(("No disk inserted; aborting"));
    1552           SetLastError(ERROR_NOT_READY);
    1553           return FALSE;
    1554       }
    1555   }
    1556   //NOTE: For now only allow an application to write to drive A
    1557   //      Might want to extend this to all removable media, but it's
    1558   //      too dangerous to allow win32 apps to write to the harddisk directly
    1559   if(drvInfo->driveLetter != 'A') {
    1560       SetLastError(ERROR_ACCESS_DENIED);
    1561       return FALSE;
    1562   }
    1563 
    1564 
    1565   //SvL: DosWrite doesn't like reading from memory addresses returned by
    1566   //     DosAliasMem -> search for original memory mapped pointer and use
    1567   //     that one + commit pages if not already present
    1568   map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);
    1569   if(map) {
    1570     lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
    1571     DWORD nrpages = nNumberOfBytesToWrite/4096;
    1572     if(offset & 0xfff)
    1573         nrpages++;
    1574     if(nNumberOfBytesToWrite & 0xfff)
    1575         nrpages++;
    1576 
    1577     map->commitPage(offset & ~0xfff, TRUE, nrpages);
    1578   }
    1579   else  lpRealBuf = (LPVOID)lpBuffer;
    1580 
    1581   OSLibDosDevIOCtl(pHMHandleData->hHMHandle,IOCTL_DISK,DSK_LOCKDRIVE,0,0,0,0,0,0);
    1582 
    1583   if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
    1584     dprintf(("ERROR: Overlapped IO not yet implememented!!"));
    1585   }
     1648    LPVOID       lpRealBuf;
     1649    Win32MemMap *map;
     1650    DWORD        offset, byteswritten;
     1651    BOOL         bRC;
     1652
     1653    dprintf2(("KERNEL32: HMDeviceDiskClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x) - stub?\n",
     1654              lpHMDeviceName, pHMHandleData, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten,
     1655              lpOverlapped));
     1656
     1657    DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
     1658    if(drvInfo == NULL) {
     1659        dprintf(("ERROR: WriteFile: drvInfo == NULL!!!"));
     1660        DebugInt3();
     1661        SetLastError(ERROR_INVALID_HANDLE);
     1662        return FALSE;
     1663    }
     1664    if(!(drvInfo->dwAccess & GENERIC_WRITE)) {
     1665        dprintf(("ERROR: WriteFile: write access denied!"));
     1666        SetLastError(ERROR_ACCESS_DENIED);
     1667        return FALSE;
     1668    }
     1669    //It's legal for this pointer to be NULL
     1670    if(lpNumberOfBytesWritten)
     1671        *lpNumberOfBytesWritten = 0;
     1672    else
     1673        lpNumberOfBytesWritten = &byteswritten;
     1674
     1675    if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) {
     1676        dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!"));
     1677        SetLastError(ERROR_INVALID_PARAMETER);
     1678        return FALSE;
     1679    }
     1680    if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) {
     1681        dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation"));
     1682    }
     1683    if(lpCompletionRoutine) {
     1684        dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO"));
     1685    }
     1686
     1687    //If we didn't get an OS/2 handle for the disk before, get one now
     1688    if(!pHMHandleData->hHMHandle) {
     1689        DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
     1690        pHMHandleData->hHMHandle = OpenDisk(drvInfo);
     1691        if(!pHMHandleData->hHMHandle) {
     1692            dprintf(("No disk inserted; aborting"));
     1693            SetLastError(ERROR_NOT_READY);
     1694            return FALSE;
     1695        }
     1696    }
     1697
     1698    //SvL: DosWrite doesn't like reading from memory addresses returned by
     1699    //     DosAliasMem -> search for original memory mapped pointer and use
     1700    //     that one + commit pages if not already present
     1701    map = Win32MemMapView::findMapByView((ULONG)lpBuffer, &offset, MEMMAP_ACCESS_READ);
     1702    if(map) {
     1703        lpRealBuf = (LPVOID)((ULONG)map->getMappingAddr() + offset);
     1704        DWORD nrpages = nNumberOfBytesToWrite/4096;
     1705        if(offset & 0xfff)
     1706            nrpages++;
     1707        if(nNumberOfBytesToWrite & 0xfff)
     1708            nrpages++;
     1709   
     1710        map->commitPage(offset & ~0xfff, TRUE, nrpages);
     1711    }
     1712    else  lpRealBuf = (LPVOID)lpBuffer;
     1713
     1714    OSLibDosDevIOCtl(pHMHandleData->hHMHandle,IOCTL_DISK,DSK_LOCKDRIVE,0,0,0,0,0,0);
     1715
     1716    if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
     1717        dprintf(("ERROR: Overlapped IO not yet implememented!!"));
     1718    }
    15861719//  else {
    15871720    bRC = OSLibDosWrite(pHMHandleData->hHMHandle,
     
    15911724//  }
    15921725
    1593   OSLibDosDevIOCtl(pHMHandleData->hHMHandle,IOCTL_DISK,DSK_UNLOCKDRIVE,0,0,0,0,0,0);
    1594   dprintf2(("KERNEL32: HMDeviceDiskClass::WriteFile returned %08xh\n",
    1595            bRC));
    1596 
    1597   return bRC;
     1726    OSLibDosDevIOCtl(pHMHandleData->hHMHandle,IOCTL_DISK,DSK_UNLOCKDRIVE,0,0,0,0,0,0);
     1727    dprintf2(("KERNEL32: HMDeviceDiskClass::WriteFile returned %08xh\n",
     1728               bRC));
     1729
     1730    return bRC;
    15981731}
    15991732
     1733/*****************************************************************************
     1734 * Name      : DWORD HMDeviceDiskClass::GetFileSize
     1735 * Purpose   : set file time
     1736 * Parameters: PHMHANDLEDATA pHMHandleData
     1737 *             PDWORD        pSize
     1738 * Variables :
     1739 * Result    : API returncode
     1740 * Remark    :
     1741 * Status    :
     1742 *
     1743 * Author    : Patrick Haller [Wed, 1999/06/17 20:44]
     1744 *****************************************************************************/
     1745
     1746DWORD HMDeviceDiskClass::GetFileSize(PHMHANDLEDATA pHMHandleData,
     1747                                     PDWORD        lpdwFileSizeHigh)
     1748{
     1749    DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
     1750    if(drvInfo == NULL) {
     1751        dprintf(("ERROR: GetFileSize: drvInfo == NULL!!!"));
     1752        DebugInt3();
     1753        SetLastError(ERROR_INVALID_HANDLE);
     1754        return -1; //INVALID_SET_FILE_POINTER
     1755    }
     1756
     1757    dprintf2(("KERNEL32: HMDeviceDiskClass::GetFileSize %s(%08xh,%08xh)\n",
     1758              lpHMDeviceName, pHMHandleData, lpdwFileSizeHigh));
     1759
     1760    //If we didn't get an OS/2 handle for the disk before, get one now
     1761    if(!pHMHandleData->hHMHandle) {
     1762        pHMHandleData->hHMHandle = OpenDisk(drvInfo);
     1763        if(!pHMHandleData->hHMHandle) {
     1764            dprintf(("No disk inserted; aborting"));
     1765            SetLastError(ERROR_NOT_READY);
     1766            return -1; //INVALID_SET_FILE_POINTER
     1767        }
     1768    }
     1769
     1770    if(drvInfo->PartitionSize.HighPart || drvInfo->PartitionSize.LowPart) {
     1771        if(lpdwFileSizeHigh)
     1772            *lpdwFileSizeHigh = drvInfo->PartitionSize.HighPart;
     1773
     1774        return drvInfo->PartitionSize.LowPart;
     1775    }
     1776    else {
     1777        LARGE_INTEGER position, size;
     1778
     1779        //get current position
     1780        position.HighPart = 0;
     1781        position.LowPart  = SetFilePointer(pHMHandleData, 0, (PLONG)&position.HighPart, FILE_CURRENT);
     1782        SetFilePointer(pHMHandleData, 0, NULL, FILE_BEGIN);
     1783        size.HighPart     = 0;
     1784        size.LowPart      = SetFilePointer(pHMHandleData, 0, (PLONG)&size.HighPart, FILE_END);
     1785
     1786        //restore old position
     1787        SetFilePointer(pHMHandleData, position.LowPart, (PLONG)&position.HighPart, FILE_BEGIN);
     1788
     1789        if(lpdwFileSizeHigh)
     1790            *lpdwFileSizeHigh = size.HighPart;
     1791
     1792        return size.LowPart;
     1793    }
     1794}
    16001795
    16011796/*****************************************************************************
     
    16131808DWORD HMDeviceDiskClass::GetFileType(PHMHANDLEDATA pHMHandleData)
    16141809{
    1615   dprintf2(("KERNEL32: HMDeviceDiskClass::GetFileType %s(%08x)\n",
    1616              lpHMDeviceName,
    1617              pHMHandleData));
    1618 
    1619   return FILE_TYPE_DISK;
     1810    dprintf2(("KERNEL32: HMDeviceDiskClass::GetFileType %s(%08x)\n",
     1811               lpHMDeviceName, pHMHandleData));
     1812
     1813    return FILE_TYPE_DISK;
    16201814}
    16211815//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.