Index: trunk/src/kernel32/disk.cpp
===================================================================
--- trunk/src/kernel32/disk.cpp	(revision 9297)
+++ trunk/src/kernel32/disk.cpp	(revision 9298)
@@ -1,3 +1,3 @@
-/* $Id: disk.cpp,v 1.37 2002-05-14 09:28:19 sandervl Exp $ */
+/* $Id: disk.cpp,v 1.38 2002-09-26 16:06:06 sandervl Exp $ */
 
 /*
@@ -570,9 +570,4 @@
     char     szVolume[256];
 
-    //tetsetsetetsetsetset
-    SetLastError(ERROR_NO_MORE_FILES);
-    return FALSE;
-    //tetsetsetetsetsetset
-
     if(!VERSION_IS_WIN2000_OR_HIGHER()) {
         SetLastError(ERROR_NOT_SUPPORTED);
@@ -654,9 +649,9 @@
     if(!VERSION_IS_WIN2000_OR_HIGHER()) {
         SetLastError(ERROR_NOT_SUPPORTED);
-        return FALSE;
+        return INVALID_HANDLE_VALUE;
     }
     
     SetLastError(ERROR_NO_MORE_FILES);
-    return 0;
+    return INVALID_HANDLE_VALUE;
 }
 //******************************************************************************
@@ -672,5 +667,5 @@
     if(!VERSION_IS_WIN2000_OR_HIGHER()) {
         SetLastError(ERROR_NOT_SUPPORTED);
-        return FALSE;
+        return INVALID_HANDLE_VALUE;
     }
 
Index: trunk/src/kernel32/hmdisk.cpp
===================================================================
--- trunk/src/kernel32/hmdisk.cpp	(revision 9297)
+++ trunk/src/kernel32/hmdisk.cpp	(revision 9298)
@@ -1,3 +1,3 @@
-/* $Id: hmdisk.cpp,v 1.52 2002-08-09 13:17:22 sandervl Exp $ */
+/* $Id: hmdisk.cpp,v 1.53 2002-09-26 16:06:06 sandervl Exp $ */
 
 /*
@@ -52,4 +52,5 @@
     HFILE     hTemplate;
     BOOL      fPhysicalDisk;
+    DWORD     dwPhysicalDiskNr;
     BOOL      fCDPlaying;
     BOOL      fShareViolation;
@@ -134,4 +135,5 @@
     VOLUME_DISK_EXTENTS volext = {0};
     BOOL                fPhysicalDisk = FALSE;
+    DWORD               dwPhysicalDiskNr = 0;
 
     dprintf2(("KERNEL32: HMDeviceDiskClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
@@ -174,6 +176,7 @@
                 
                 //Note: this only works on Warp 4.5 and up
-                sprintf(szDiskName, "\\\\.\\Physical_Disk%d", volext.Extents[0].DiskNumber); 
-                fPhysicalDisk = TRUE;
+                sprintf(szDiskName, "\\\\.\\Physical_Disk%d", volext.Extents[0].DiskNumber+1); 
+                fPhysicalDisk    = TRUE;
+                dwPhysicalDiskNr = volext.Extents[0].DiskNumber + 1;
 
                 if(fLVMVolume && (pHMHandleData->dwAccess & GENERIC_WRITE)) {
@@ -199,6 +202,7 @@
     {
         //Note: this only works on Warp 4.5 and up
-        sprintf(szDiskName, "\\\\.\\Physical_Disk%c", lpFileName[17]);
-        fPhysicalDisk = TRUE;
+        sprintf(szDiskName, "\\\\.\\Physical_Disk%c", lpFileName[17]+1);
+        fPhysicalDisk    = TRUE;
+        dwPhysicalDiskNr = (DWORD)(lpFileName[17] - '0')+1;
 
         //TODO: could be removable in theory
@@ -285,7 +289,8 @@
         //save volume start & length if volume must be accessed through the physical disk 
         //(no other choice for unmounted volumes)
-        drvInfo->fPhysicalDisk  = fPhysicalDisk;
-        drvInfo->StartingOffset = volext.Extents[0].StartingOffset;
-        drvInfo->PartitionSize  = volext.Extents[0].ExtentLength;
+        drvInfo->fPhysicalDisk    = fPhysicalDisk;
+        drvInfo->dwPhysicalDiskNr = dwPhysicalDiskNr;
+        drvInfo->StartingOffset   = volext.Extents[0].StartingOffset;
+        drvInfo->PartitionSize    = volext.Extents[0].ExtentLength;
 
         //save volume name for later (IOCtls)
@@ -891,7 +896,15 @@
         }
 
-        if(OSLibDosGetDiskGeometry(pHMHandleData->hHMHandle, drvInfo->driveLetter, pGeom) == FALSE) {
-            dprintf(("!ERROR!: IOCTL_DISK_GET_DRIVE_GEOMETRY: OSLibDosGetDiskGeometry failed!!"));
-            return FALSE;
+        if(drvInfo->fPhysicalDisk) {
+            if(OSLibLVMGetDiskGeometry(drvInfo->dwPhysicalDiskNr, pGeom) == FALSE) {
+                dprintf(("!ERROR!: IOCTL_DISK_GET_DRIVE_GEOMETRY: OSLibDosGetDiskGeometry failed!!"));
+                return FALSE;
+            }
+        }
+        else {
+            if(OSLibDosGetDiskGeometry(pHMHandleData->hHMHandle, drvInfo->driveLetter, pGeom) == FALSE) {
+                dprintf(("!ERROR!: IOCTL_DISK_GET_DRIVE_GEOMETRY: OSLibDosGetDiskGeometry failed!!"));
+                return FALSE;
+            }
         }
         dprintf(("Cylinders         %d", pGeom->Cylinders));
@@ -1649,4 +1662,5 @@
     DWORD        offset, bytesread;
     BOOL         bRC;
+    DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
 
     dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)",
@@ -1671,5 +1685,4 @@
     //If we didn't get an OS/2 handle for the disk before, get one now
     if(!pHMHandleData->hHMHandle) {
-        DRIVE_INFO *drvInfo = (DRIVE_INFO*)pHMHandleData->dwUserData;
         pHMHandleData->hHMHandle = OpenDisk(drvInfo);
         if(!pHMHandleData->hHMHandle) {
@@ -1700,4 +1713,29 @@
     else  lpRealBuf = (LPVOID)lpBuffer;
 
+    //if unmounted volume, check upper boundary as we're accessing the entire physical drive
+    //instead of just the volume
+    if(drvInfo->fPhysicalDisk && (drvInfo->StartingOffset.HighPart != 0 ||
+       drvInfo->StartingOffset.LowPart != 0))
+    {
+        LARGE_INTEGER distance, result, endpos;
+
+        //calculate end position in partition
+        Add64(&drvInfo->StartingOffset, &drvInfo->PartitionSize, &endpos);
+
+        distance.HighPart = 0;
+        distance.LowPart  = nNumberOfBytesToRead;
+        Add64(&distance, &drvInfo->CurrentFilePointer, &result);
+
+        //check upper boundary
+        if(result.HighPart > endpos.HighPart ||
+           (result.HighPart == endpos.HighPart && result.LowPart > endpos.LowPart) )
+        {
+            Sub64(&endpos, &drvInfo->CurrentFilePointer, &result);
+            nNumberOfBytesToRead = result.LowPart;
+            dprintf(("Read past end of volume; nNumberOfBytesToRead reduced to %d", nNumberOfBytesToRead));
+            DebugInt3();
+        }
+    }
+
     if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
         dprintf(("ERROR: Overlapped IO not yet implememented!!"));
@@ -1715,4 +1753,19 @@
     }
     else dprintf2(("KERNEL32: HMDeviceDiskClass::ReadFile read %x bytes pos %x", *lpNumberOfBytesRead, SetFilePointer(pHMHandleData, 0, NULL, FILE_CURRENT)));
+
+    //if unmounted volume, add starting offset to position as we're accessing the entire physical drive
+    //instead of just the volume
+    if(drvInfo->fPhysicalDisk && (drvInfo->StartingOffset.HighPart != 0 ||
+       drvInfo->StartingOffset.LowPart != 0) && bRC == TRUE)
+    {
+        LARGE_INTEGER distance, result;
+
+        distance.HighPart = 0;
+        distance.LowPart  = *lpNumberOfBytesRead;
+        Add64(&distance, &drvInfo->CurrentFilePointer, &result);
+        drvInfo->CurrentFilePointer = result;
+
+        dprintf(("New unmounted volume current file pointer %08x%08x", drvInfo->CurrentFilePointer.HighPart, drvInfo->CurrentFilePointer.LowPart));
+    }
 
     return bRC;
@@ -1927,4 +1980,29 @@
     else  lpRealBuf = (LPVOID)lpBuffer;
 
+    //if unmounted volume, check upper boundary as we're accessing the entire physical drive
+    //instead of just the volume
+    if(drvInfo->fPhysicalDisk && (drvInfo->StartingOffset.HighPart != 0 ||
+       drvInfo->StartingOffset.LowPart != 0))
+    {
+        LARGE_INTEGER distance, result, endpos;
+
+        //calculate end position in partition
+        Add64(&drvInfo->StartingOffset, &drvInfo->PartitionSize, &endpos);
+
+        distance.HighPart = 0;
+        distance.LowPart  = nNumberOfBytesToWrite;
+        Add64(&distance, &drvInfo->CurrentFilePointer, &result);
+
+        //check upper boundary
+        if(result.HighPart > endpos.HighPart ||
+           (result.HighPart == endpos.HighPart && result.LowPart > endpos.LowPart) )
+        {
+            Sub64(&endpos, &drvInfo->CurrentFilePointer, &result);
+            nNumberOfBytesToWrite = result.LowPart;
+            dprintf(("Write past end of volume; nNumberOfBytesToWrite reduced to %d", nNumberOfBytesToWrite));
+            DebugInt3();
+        }
+    }
+
     if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) {
         dprintf(("ERROR: Overlapped IO not yet implememented!!"));
@@ -1936,4 +2014,19 @@
                             lpNumberOfBytesWritten);
 //  }
+
+    //if unmounted volume, add starting offset to position as we're accessing the entire physical drive
+    //instead of just the volume
+    if(drvInfo->fPhysicalDisk && (drvInfo->StartingOffset.HighPart != 0 ||
+       drvInfo->StartingOffset.LowPart != 0) && bRC == TRUE)
+    {
+        LARGE_INTEGER distance, result;
+
+        distance.HighPart = 0;
+        distance.LowPart  = *lpNumberOfBytesWritten;
+        Add64(&distance, &drvInfo->CurrentFilePointer, &result);
+        drvInfo->CurrentFilePointer = result;
+
+        dprintf(("New unmounted volume current file pointer %08x%08x", drvInfo->CurrentFilePointer.HighPart, drvInfo->CurrentFilePointer.LowPart));
+    }
 
     dprintf2(("KERNEL32: HMDeviceDiskClass::WriteFile returned %08xh\n",
Index: trunk/src/kernel32/oslibdos.cpp
===================================================================
--- trunk/src/kernel32/oslibdos.cpp	(revision 9297)
+++ trunk/src/kernel32/oslibdos.cpp	(revision 9298)
@@ -1,3 +1,3 @@
-/* $Id: oslibdos.cpp,v 1.108 2002-08-22 14:21:26 sandervl Exp $ */
+/* $Id: oslibdos.cpp,v 1.109 2002-09-26 16:06:07 sandervl Exp $ */
 /*
  * Wrappers for OS/2 Dos* API
@@ -996,5 +996,5 @@
       // @@@AH 2001-06-02 Win2k SP2 returns error 2 in this case
       int winError = error2WinError(rc);
-      if (winError == ERROR_OPEN_FAILED_W)
+      if (winError == ERROR_OPEN_FAILED_W || winError == ERROR_PATH_NOT_FOUND_W)
         winError = ERROR_FILE_NOT_FOUND_W;
       SetLastError(winError);
@@ -2473,5 +2473,5 @@
 //******************************************************************************
 //******************************************************************************
-BOOL  OSLibDosGetDiskGeometry(HANDLE hDisk, DWORD cDisk, PVOID pdiskgeom)
+BOOL OSLibDosGetDiskGeometry(HANDLE hDisk, DWORD cDisk, PVOID pdiskgeom)
 {
    PDISK_GEOMETRY pGeom = (PDISK_GEOMETRY)pdiskgeom;
@@ -2487,41 +2487,41 @@
    if(rc == 0)
    {
-        pGeom->SectorsPerTrack   = bpb.usSectorsPerTrack;
-        pGeom->BytesPerSector    = bpb.usBytesPerSector;
-        pGeom->TracksPerCylinder = 80;  //TODO:!!!!!
-        pGeom->Cylinders.u.LowPart  = bpb.cCylinders;
-        pGeom->Cylinders.u.HighPart = 0;
-        switch(bpb.bDeviceType) {
-        case DEVTYPE_48TPI:
-            pGeom->MediaType = F5_360_512;  //?????
-            break;
-        case DEVTYPE_96TPI:
-            pGeom->MediaType = F5_1Pt2_512; //?????
-            break;
-        case DEVTYPE_35:
-            pGeom->MediaType = F3_720_512;
-            break;
-        case DEVTYPE_8SD:
-        case DEVTYPE_8DD:
-            pGeom->MediaType = RemovableMedia;
-            break;
-        case DEVTYPE_FIXED:
-            pGeom->MediaType = FixedMedia;
-            break;
-        case DEVTYPE_TAPE:
-            pGeom->MediaType = RemovableMedia;
-            break;
-        case DEVTYPE_UNKNOWN: //others, include 1.44 3.5 inch disk drive
-            pGeom->MediaType = F3_1Pt44_512;
-            break;
-        case 8: //RW optical disk
-            pGeom->MediaType = RemovableMedia;
-            break;
-        case 9: //2.88 3.5 inch disk
-            pGeom->MediaType = F3_2Pt88_512;
-            break;
-        }
-        SetLastError(ERROR_SUCCESS_W);
-        return TRUE;
+            pGeom->SectorsPerTrack   = bpb.usSectorsPerTrack;
+            pGeom->BytesPerSector    = bpb.usBytesPerSector;
+            pGeom->TracksPerCylinder = 80;  //TODO:!!!!!
+            pGeom->Cylinders.u.LowPart  = bpb.cCylinders;
+            pGeom->Cylinders.u.HighPart = 0;
+            switch(bpb.bDeviceType) {
+            case DEVTYPE_48TPI:
+                pGeom->MediaType = F5_360_512;  //?????
+                break;
+            case DEVTYPE_96TPI:
+                pGeom->MediaType = F5_1Pt2_512; //?????
+                break;
+            case DEVTYPE_35:
+                pGeom->MediaType = F3_720_512;
+                break;
+            case DEVTYPE_8SD:
+            case DEVTYPE_8DD:
+                pGeom->MediaType = RemovableMedia;
+                break;
+            case DEVTYPE_FIXED:
+                pGeom->MediaType = FixedMedia;
+                break;
+            case DEVTYPE_TAPE:
+                pGeom->MediaType = RemovableMedia;
+                break;
+            case DEVTYPE_UNKNOWN: //others, include 1.44 3.5 inch disk drive
+                pGeom->MediaType = F3_1Pt44_512;
+                break;
+            case 8: //RW optical disk
+                pGeom->MediaType = RemovableMedia;
+                break;
+            case 9: //2.88 3.5 inch disk
+                pGeom->MediaType = F3_2Pt88_512;
+                break;
+            }
+            SetLastError(ERROR_SUCCESS_W);
+            return TRUE;
    }
    dprintf(("OSLibDosGetDiskGeometry: error %d -> %d", rc, error2WinError(rc)));
Index: trunk/src/kernel32/osliblvm.cpp
===================================================================
--- trunk/src/kernel32/osliblvm.cpp	(revision 9297)
+++ trunk/src/kernel32/osliblvm.cpp	(revision 9298)
@@ -1,3 +1,3 @@
-/* $Id: osliblvm.cpp,v 1.2 2002-05-10 14:55:13 sandervl Exp $ */
+/* $Id: osliblvm.cpp,v 1.3 2002-09-26 16:06:07 sandervl Exp $ */
 
 /*
@@ -319,8 +319,18 @@
         return FALSE;   //no more volumes
     }
-    volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[volindex].Volume_Handle, &lasterror);
-    if(lasterror != LVM_ENGINE_NO_ERROR) {
-        DebugInt3();
-        return FALSE;
+    while(volindex < volctrl->Count) {
+        volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[volindex].Volume_Handle, &lasterror);
+        if(lasterror != LVM_ENGINE_NO_ERROR) {
+            DebugInt3();
+            return FALSE;
+        }
+        //Don't report anything about LVM volumes until we support all those
+        //fancy features (like spanned volumes)
+        if(volinfo.Compatibility_Volume == TRUE) break;
+        dprintf(("Ignoring LVM volume %s", volinfo.Volume_Name));
+        volindex++;
+    }
+    if(volindex >= volctrl->Count) {
+        return FALSE;   //no more volumes
     }
     strncpy(lpszVolumeName, volinfo.Volume_Name, min(sizeof(volinfo.Volume_Name), cchBufferLength)-1);
@@ -428,4 +438,7 @@
     pPartition->StartingOffset.u.HighPart = partctrl.Partition_Array[0].Partition_Start >> 23;
     pPartition->StartingOffset.u.LowPart  = partctrl.Partition_Array[0].Partition_Start << 9;
+//    pPartition->PartitionLength.u.HighPart= partctrl.Partition_Array[0].True_Partition_Size >> 23;
+//    pPartition->PartitionLength.u.LowPart = partctrl.Partition_Array[0].True_Partition_Size << 9;
+//    pPartition->HiddenSectors             = 0;
     pPartition->PartitionLength.u.HighPart= partctrl.Partition_Array[0].Usable_Partition_Size >> 23;
     pPartition->PartitionLength.u.LowPart = partctrl.Partition_Array[0].Usable_Partition_Size << 9;
@@ -466,11 +479,32 @@
     }
 
+    //TODO: spanned volumes
     pVolExtent->NumberOfDiskExtents = 1;
     pVolExtent->Extents[0].DiskNumber  = 0;
     pVolExtent->Extents[0].StartingOffset.u.HighPart = partctrl.Partition_Array[0].Partition_Start >> 23;;
     pVolExtent->Extents[0].StartingOffset.u.LowPart  = partctrl.Partition_Array[0].Partition_Start << 9;
+//    pVolExtent->Extents[0].ExtentLength.u.HighPart   = partctrl.Partition_Array[0].True_Partition_Size >> 23;
+//    pVolExtent->Extents[0].ExtentLength.u.LowPart    = partctrl.Partition_Array[0].True_Partition_Size << 9;
     pVolExtent->Extents[0].ExtentLength.u.HighPart   = partctrl.Partition_Array[0].Usable_Partition_Size >> 23;
     pVolExtent->Extents[0].ExtentLength.u.LowPart    = partctrl.Partition_Array[0].Usable_Partition_Size << 9;
 
+    //find number of disk on which this volume is located
+    diskinfo = Get_Drive_Control_Data(&lasterror);
+    if(lasterror != LVM_ENGINE_NO_ERROR) {
+        return FALSE;
+    }
+    for(int i=0;i<diskinfo.Count;i++) {
+        if(diskinfo.Drive_Control_Data[i].Drive_Handle == partctrl.Partition_Array[0].Drive_Handle) {
+            //win32 base = 0, os2 base = 1
+            pVolExtent->Extents[0].DiskNumber = diskinfo.Drive_Control_Data[i].Drive_Number - 1;
+#ifdef DEBUG
+            if(diskinfo.Drive_Control_Data[i].Drive_Number == 0) DebugInt3();
+#endif
+            break;
+        }
+    }
+    if(i == diskinfo.Count) {
+        ret = FALSE;
+    }
     dprintf(("pVolExtent->NumberOfDiskExtents       %d", pVolExtent->NumberOfDiskExtents));
     dprintf(("pVolExtent->Extents[0].DiskNumber     %d",  pVolExtent->Extents[0].DiskNumber));
@@ -478,18 +512,4 @@
     dprintf(("pVolExtent->Extents[0].ExtentLength   %08x%08x", pVolExtent->Extents[0].ExtentLength.u.HighPart, pVolExtent->Extents[0].ExtentLength.u.LowPart));
 
-    //find number of disk on which this volume is located
-    diskinfo = Get_Drive_Control_Data(&lasterror);
-    if(lasterror != LVM_ENGINE_NO_ERROR) {
-        return FALSE;
-    }
-    for(int i=0;i<diskinfo.Count;i++) {
-        if(diskinfo.Drive_Control_Data[i].Drive_Handle == partctrl.Partition_Array[0].Drive_Handle) {
-            pVolExtent->Extents[0].DiskNumber = diskinfo.Drive_Control_Data[i].Drive_Number;
-            break;
-        }
-    }
-    if(i == diskinfo.Count) {
-        ret = FALSE;
-    }
     if(pfLVMVolume) {
         *pfLVMVolume = (volinfo.Compatibility_Volume == FALSE);
@@ -655,3 +675,44 @@
 //******************************************************************************
 //******************************************************************************
-
+BOOL OSLibLVMGetDiskGeometry(DWORD dwDiskNr, PDISK_GEOMETRY pGeom)
+{
+    Drive_Control_Array   driveinfo;
+    Drive_Control_Record *pDriveRec;
+    CARDINAL32            lasterror;
+    BOOL                  ret = FALSE;
+    int                   i;
+
+    driveinfo = Get_Drive_Control_Data(&lasterror);
+    if(lasterror != LVM_ENGINE_NO_ERROR) {
+        DebugInt3();
+        return FALSE;
+    }
+    pDriveRec = driveinfo.Drive_Control_Data;
+    if(pDriveRec == NULL) {
+        DebugInt3();
+        return FALSE;
+    }
+    if(dwDiskNr > driveinfo.Count) {
+        DebugInt3();
+        ret = FALSE;
+        goto endfunc;
+    }
+    for(i=0;i<driveinfo.Count;i++) {
+        if(pDriveRec->Drive_Number == dwDiskNr) {
+            pGeom->Cylinders.u.LowPart  = pDriveRec->Cylinder_Count;
+            pGeom->Cylinders.u.HighPart = 0;
+            pGeom->TracksPerCylinder    = pDriveRec->Heads_Per_Cylinder;
+            pGeom->SectorsPerTrack      = pDriveRec->Sectors_Per_Track;
+            pGeom->BytesPerSector       = 512;
+            pGeom->MediaType            = FixedMedia;
+
+            ret = TRUE;
+            break;
+        }
+    }
+endfunc:
+    Free_Engine_Memory((ULONG)driveinfo.Drive_Control_Data);
+    return ret;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/kernel32/osliblvm.h
===================================================================
--- trunk/src/kernel32/osliblvm.h	(revision 9297)
+++ trunk/src/kernel32/osliblvm.h	(revision 9298)
@@ -1,3 +1,3 @@
-/* $Id: osliblvm.h,v 1.2 2002-05-10 14:55:13 sandervl Exp $ */
+/* $Id: osliblvm.h,v 1.3 2002-09-26 16:06:07 sandervl Exp $ */
 /*
  * OS/2 LVM (Logical Volume Management) functions
@@ -343,4 +343,5 @@
 
 BOOL   OSLibLVMStripVolumeName(LPCSTR lpszWin32VolumeName, LPSTR lpszOS2VolumeName, DWORD cchBufferLength);
+BOOL   OSLibLVMGetDiskGeometry(DWORD dwDiskNr, PDISK_GEOMETRY pGeom);
 
 #endif //__OSLIBLVM_H__
