Changeset 8401 for trunk/src/kernel32/hmdisk.cpp
- Timestamp:
- May 10, 2002, 4:55:13 PM (23 years ago)
- File:
-
- 1 edited
-
trunk/src/kernel32/hmdisk.cpp (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/hmdisk.cpp
r8397 r8401 1 /* $Id: hmdisk.cpp,v 1.4 3 2002-05-09 13:55:33sandervl Exp $ */1 /* $Id: hmdisk.cpp,v 1.44 2002-05-10 14:55:11 sandervl Exp $ */ 2 2 3 3 /* 4 4 * Win32 Disk API functions for OS/2 5 5 * 6 * Copyright 2000 Sander van Leeuwen6 * Copyright 2000-2002 Sander van Leeuwen 7 7 * 8 8 * … … 12 12 #include <os2win.h> 13 13 #include <string.h> 14 #include <stdio.h> 14 15 #include <versionos2.h> 15 16 … … 23 24 #include "oslibdos.h" 24 25 #include "osliblvm.h" 26 #include "asmutil.h" 25 27 26 28 #define DBG_LOCALLOG DBG_hmdisk … … 35 37 { 36 38 HINSTANCE hInstAspi; 37 DWORD (WIN32API *GetASPI32SupportInfo)();38 DWORD (CDECL *SendASPI32Command)(LPSRB lpSRB);39 DWORD (WIN32API *GetASPI32SupportInfo)(); 40 DWORD (CDECL *SendASPI32Command)(LPSRB lpSRB); 39 41 ULONG driveLetter; 40 42 ULONG driveType; … … 47 49 LPSECURITY_ATTRIBUTES lpSecurityAttributes; 48 50 HFILE hTemplate; 51 BOOL fPhysicalDisk; 52 LARGE_INTEGER StartingOffset; 53 LARGE_INTEGER PartitionSize; 54 LARGE_INTEGER CurrentFilePointer; 55 CHAR szVolumeName[256]; 49 56 } DRIVE_INFO; 50 57 … … 70 77 BOOL HMDeviceDiskClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength) 71 78 { 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 } 84 93 85 94 //\\.\x: -> length 6 … … 94 103 } 95 104 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) 98 107 if((strncmp(lpDeviceName, "\\\\.\\", 4) == 0) && 99 108 namelength == 6 && lpDeviceName[5] == ':') … … 107 116 } 108 117 //****************************************************************************** 109 //TODO: PHYSICALDRIVEn!!110 118 //****************************************************************************** 111 119 DWORD HMDeviceDiskClass::CreateFile (LPCSTR lpFileName, … … 114 122 PHMHANDLEDATA pHMHandleDataTemplate) 115 123 { 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; 119 131 120 132 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)); 126 134 127 135 //TODO: check in NT if CREATE_ALWAYS is allowed!! … … 136 144 137 145 //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 } 151 189 } 152 190 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 } 154 207 } 155 208 else { 209 strcpy(szDiskName, lpFileName); 156 210 szDrive[0] = *lpFileName; 157 }158 dwDriveType = GetDriveTypeA(szDrive);211 dwDriveType = GetDriveTypeA(szDrive); 212 } 159 213 160 214 //Disable error popus. NT allows an app to open a cdrom/dvd drive without a disk inside 161 215 //OS/2 fails in that case with error ERROR_NOT_READY 162 216 ULONG oldmode = SetErrorMode(SEM_FAILCRITICALERRORS); 163 hFile = OSLibDosCreateFile( (LPSTR)lpFileName,217 hFile = OSLibDosCreateFile(szDiskName, 164 218 pHMHandleData->dwAccess, 165 219 pHMHandleData->dwShare, … … 177 231 { 178 232 pHMHandleData->dwAccess &= ~GENERIC_WRITE; 179 hFile = OSLibDosCreateFile((LPSTR) lpFileName,233 hFile = OSLibDosCreateFile((LPSTR)szDiskName, 180 234 pHMHandleData->dwAccess, 181 235 pHMHandleData->dwShare, … … 211 265 drvInfo->dwAccess = pHMHandleData->dwFlags; 212 266 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); 213 276 214 277 drvInfo->driveLetter = *lpFileName; //save drive letter … … 242 305 } 243 306 244 if(hFile ) {307 if(hFile && drvInfo->driveType != DRIVE_FIXED) { 245 308 OSLibDosQueryVolumeSerialAndName(1 + drvInfo->driveLetter - 'A', &drvInfo->dwVolumelabel, NULL, 0); 246 309 } 247 310 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 } 248 318 return (NO_ERROR); 249 319 } … … 618 688 { 619 689 APIRET rc; 620 DWORD ret;690 DWORD ret; 621 691 ULONG ulBytesRead = 0; /* Number of bytes read by DosRead */ 622 692 ULONG ulWrote = 0; /* Number of bytes written by DosWrite */ … … 638 708 return FALSE; 639 709 } 710 else 711 if(drvInfo->driveType == DRIVE_FIXED) { 712 SetLastError(ERROR_SUCCESS); 713 return TRUE; 714 } 640 715 641 716 OSLibDosDevIOCtl(pHMHandleData->hHMHandle,IOCTL_DISK,DSK_LOCKDRIVE,0,0,0,0,0,0); … … 720 795 //label has changed 721 796 //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 } 734 812 } 735 813 … … 754 832 *lpBytesReturned = sizeof(PARTITION_INFORMATION); 755 833 } 756 if(OSLibLVMGetPartitionInfo(drvInfo->driveLetter, pPartition)) {834 if(OSLibLVMGetPartitionInfo(drvInfo->driveLetter, drvInfo->szVolumeName, pPartition) == FALSE) { 757 835 SetLastError(ERROR_NOT_ENOUGH_MEMORY); //wrong error, but who cares 758 836 return FALSE; … … 781 859 return FALSE; 782 860 } 783 if(OSLibLVMGetVolumeExtents(drvInfo->driveLetter, pVolExtent)) {861 if(OSLibLVMGetVolumeExtents(drvInfo->driveLetter, drvInfo->szVolumeName, pVolExtent) == FALSE) { 784 862 SetLastError(ERROR_NOT_ENOUGH_MEMORY); //wrong error, but who cares 785 863 return FALSE; … … 816 894 } ParameterBlock; 817 895 #pragma pack() 818 819 896 PCDROM_TOC pTOC = (PCDROM_TOC)lpOutBuffer; 820 897 DWORD rc, numtracks; … … 915 992 case IOCTL_CDROM_PLAY_AUDIO_MSF: 916 993 { 917 dprintf(("Play CDROM audio playback"));918 919 994 #pragma pack(1) 920 995 struct … … 926 1001 } ParameterBlock; 927 1002 #pragma pack() 1003 dprintf(("Play CDROM audio playback")); 928 1004 929 1005 PCDROM_PLAY_AUDIO_MSF pPlay = (PCDROM_PLAY_AUDIO_MSF)lpInBuffer; … … 1096 1172 case IOCTL_STORAGE_CHECK_VERIFY: 1097 1173 { 1174 #pragma pack(1) 1175 typedef struct 1176 { 1177 BYTE ucCommandInfo; 1178 WORD usDriveUnit; 1179 } ParameterBlock; 1180 #pragma pack() 1181 1098 1182 dprintf(("IOCTL_CDROM(DISK/STORAGE)CHECK_VERIFY %s", drvInfo->signature)); 1099 1183 if(lpBytesReturned) { … … 1109 1193 } 1110 1194 } 1111 1112 #pragma pack(1)1113 typedef struct1114 {1115 BYTE ucCommandInfo;1116 WORD usDriveUnit;1117 } ParameterBlock;1118 #pragma pack()1119 1195 1120 1196 DWORD parsize = sizeof(ParameterBlock); … … 1354 1430 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 1355 1431 { 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 { 1420 1491 bRC = OSLibDosRead(pHMHandleData->hHMHandle, 1421 1492 (PVOID)lpRealBuf, … … 1424 1495 // } 1425 1496 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; 1433 1504 } 1434 1505 /***************************************************************************** … … 1446 1517 * Author : Patrick Haller [Wed, 1999/06/17 20:44] 1447 1518 *****************************************************************************/ 1448 1449 1519 DWORD HMDeviceDiskClass::SetFilePointer(PHMHANDLEDATA pHMHandleData, 1450 1520 LONG lDistanceToMove, … … 1452 1522 DWORD dwMoveMethod) 1453 1523 { 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; 1482 1623 } 1483 1624 … … 1499 1640 1500 1641 BOOL 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) 1506 1647 { 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 } 1586 1719 // else { 1587 1720 bRC = OSLibDosWrite(pHMHandleData->hHMHandle, … … 1591 1724 // } 1592 1725 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; 1598 1731 } 1599 1732 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 1746 DWORD 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 } 1600 1795 1601 1796 /***************************************************************************** … … 1613 1808 DWORD HMDeviceDiskClass::GetFileType(PHMHANDLEDATA pHMHandleData) 1614 1809 { 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; 1620 1814 } 1621 1815 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.
