Changeset 77231 in vbox for trunk/src/VBox/Runtime/r3/win
- Timestamp:
- Feb 8, 2019 11:18:13 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/fileio-win.cpp
r77211 r77231 96 96 97 97 /** 98 * This is a helper to check if an attempt was made to grow a file beyond the 99 * limit of the filesystem. 100 * 101 * @returns true for file size limit exceeded. 102 * @param hFile Filehandle. 103 * @param offSeek Offset to seek. 104 * @param uMethod The seek method. 98 * Helper for checking if a VERR_DISK_FULL isn't a VERR_FILE_TOO_BIG. 99 * @returns VERR_DISK_FULL or VERR_FILE_TOO_BIG. 105 100 */ 106 DECLINLINE(bool) IsBeyondLimit(RTFILE hFile, uint64_t offSeek, unsigned uMethod) 107 { 108 bool fIsBeyondLimit = false; 109 110 /* 111 * Get the current file position and try set the new one. 112 * If it fails with a seek error it's because we hit the file system limit. 113 */ 114 /** @todo r=bird: I'd be very interested to know on which versions of windows and on which file systems 115 * this supposedly works. The fastfat sources in the latest WDK makes no limit checks during 116 * file seeking, only at the time of writing (and some other odd ones we cannot make use of). */ 117 uint64_t offCurrent; 118 if (MySetFilePointer(hFile, 0, &offCurrent, FILE_CURRENT)) 119 { 120 if (!MySetFilePointer(hFile, offSeek, NULL, uMethod)) 121 fIsBeyondLimit = GetLastError() == ERROR_SEEK; 122 else /* Restore file pointer on success. */ 123 MySetFilePointer(hFile, offCurrent, NULL, FILE_BEGIN); 124 } 125 126 return fIsBeyondLimit; 101 static int rtFileWinCheckIfDiskReallyFull(RTFILE hFile, uint64_t cbDesired) 102 { 103 /* 104 * Windows doesn't appear to have a way to query the file size limit of a 105 * file system, so we have to deduce the limit from the file system driver name. 106 * This means it will only work for known file systems. 107 */ 108 if (cbDesired >= _2G - 1) 109 { 110 uint64_t cbMaxFile = UINT64_MAX; 111 RTFSTYPE enmFsType; 112 int rc = rtNtQueryFsType((HANDLE)RTFileToNative(hFile), &enmFsType); 113 if (RT_SUCCESS(rc)) 114 switch (enmFsType) 115 { 116 case RTFSTYPE_NTFS: 117 case RTFSTYPE_EXFAT: 118 case RTFSTYPE_UDF: 119 cbMaxFile = UINT64_C(0xffffffffffffffff); /* (May be limited by IFS.) */ 120 break; 121 122 case RTFSTYPE_ISO9660: 123 cbMaxFile = 8 *_1T; 124 break; 125 126 case RTFSTYPE_FAT: 127 cbMaxFile = _4G; 128 break; 129 130 case RTFSTYPE_HPFS: 131 cbMaxFile = _2G; 132 break; 133 134 default: 135 break; 136 } 137 if (cbDesired >= cbMaxFile) 138 return VERR_FILE_TOO_BIG; 139 } 140 return VERR_DISK_FULL; 127 141 } 128 142 … … 563 577 { 564 578 int rc = RTErrConvertFromWin32(GetLastError()); 565 if ( rc == VERR_DISK_FULL 566 && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT) 567 ) 568 rc = VERR_FILE_TOO_BIG; 579 if (rc == VERR_DISK_FULL) 580 rc = rtFileWinCheckIfDiskReallyFull(hFile, RTFileTell(hFile) + cbToWriteAdj - cbWritten); 569 581 return rc; 570 582 } … … 607 619 } 608 620 int rc = RTErrConvertFromWin32(dwErr); 609 if ( rc == VERR_DISK_FULL 610 && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT)) 611 rc = VERR_FILE_TOO_BIG; 621 if (rc == VERR_DISK_FULL) 622 rc = rtFileWinCheckIfDiskReallyFull(hFile, RTFileTell(hFile) + cbToWrite); 612 623 return rc; 613 624 } … … 628 639 629 640 int rc = RTErrConvertFromWin32(dwErr); 630 if ( rc == VERR_DISK_FULL 631 && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT)) 632 rc = VERR_FILE_TOO_BIG; 641 if (rc == VERR_DISK_FULL) 642 rc = rtFileWinCheckIfDiskReallyFull(hFile, RTFileTell(hFile) + cbToWriteAdj); 633 643 return rc; 634 644 } … … 669 679 { 670 680 int rc = RTErrConvertFromWin32(GetLastError()); 671 if ( rc == VERR_DISK_FULL 672 && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT) 673 ) 674 rc = VERR_FILE_TOO_BIG; 681 if (rc == VERR_DISK_FULL) 682 rc = rtFileWinCheckIfDiskReallyFull(hFile, off + cbToWriteAdj); 675 683 return rc; 676 684 } … … 684 692 685 693 int rc = RTErrConvertFromWin32(GetLastError()); 686 if ( rc == VERR_DISK_FULL 687 && IsBeyondLimit(hFile, cbToWriteAdj - cbWritten, FILE_CURRENT)) 688 rc = VERR_FILE_TOO_BIG; 694 if (rc == VERR_DISK_FULL) 695 rc = rtFileWinCheckIfDiskReallyFull(hFile, off + cbToWriteAdj); 689 696 return rc; 690 697 } … … 703 710 704 711 705 RTR3DECL(int) 712 RTR3DECL(int) RTFileSetSize(RTFILE hFile, uint64_t cbSize) 706 713 { 707 714 /* … … 734 741 rc = GetLastError(); 735 742 MySetFilePointer(hFile, offCurrent, NULL, FILE_BEGIN); 743 744 if (rc == ERROR_DISK_FULL) 745 return rtFileWinCheckIfDiskReallyFull(hFile, cbSize); 736 746 } 737 747 else
Note:
See TracChangeset
for help on using the changeset viewer.