Changeset 82834 in vbox for trunk/src/VBox/Runtime/r3/win
- Timestamp:
- Jan 22, 2020 4:25:19 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/fileio-win.cpp
r80585 r82834 44 44 #include <iprt/ldr.h> 45 45 #include <iprt/log.h> 46 #include <iprt/utf16.h> 46 47 #include "internal/file.h" 47 48 #include "internal/fs.h" … … 753 754 754 755 756 #if 0 757 /** 758 * If @a hFile is opened in append mode, try return a handle with 759 * FILE_WRITE_DATA permissions. 760 * 761 * @returns Duplicate handle. 762 * @param hFile The NT handle to check & duplicate. 763 * 764 * @todo It would be much easier to implement this by not dropping the 765 * FILE_WRITE_DATA access and instead have the RTFileWrite APIs 766 * enforce the appending. That will require keeping additional 767 * information along side the handle (instance structure). However, on 768 * windows you can grant append permissions w/o giving people access to 769 * overwrite existing data, so the RTFileOpenEx code would have to deal 770 * with those kinds of STATUS_ACCESS_DENIED too then. 771 */ 772 static HANDLE rtFileReOpenAppendOnlyWithFullWriteAccess(HANDLE hFile) 773 { 774 OBJECT_BASIC_INFORMATION BasicInfo = {0}; 775 ULONG cbActual = 0; 776 NTSTATUS rcNt = NtQueryObject(hFile, ObjectBasicInformation, &BasicInfo, sizeof(BasicInfo), &cbActual); 777 if (NT_SUCCESS(rcNt)) 778 { 779 if ((BasicInfo.GrantedAccess & (FILE_APPEND_DATA | FILE_WRITE_DATA)) == FILE_APPEND_DATA) 780 { 781 /* 782 * We cannot use NtDuplicateObject here as it is not possible to 783 * upgrade the access on files, only making it more strict. So, 784 * query the path and re-open it (we could do by file/object/whatever 785 * id too, but that may not work with all file systems). 786 */ 787 for (uint32_t i = 0; i < 16; i++) 788 { 789 UNICODE_STRING NtName; 790 int rc = RTNtPathFromHandle(&NtName, hFile, 0); 791 AssertRCReturn(rc, INVALID_HANDLE_VALUE); 792 793 HANDLE hDupFile = RTNT_INVALID_HANDLE_VALUE; 794 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 795 OBJECT_ATTRIBUTES ObjAttr; 796 InitializeObjectAttributes(&ObjAttr, &NtName, BasicInfo.Attributes & ~OBJ_INHERIT, NULL, NULL); 797 798 NTSTATUS rcNt = NtCreateFile(&hDupFile, 799 BasicInfo.GrantedAccess | FILE_WRITE_DATA, 800 &ObjAttr, 801 &Ios, 802 NULL /* AllocationSize*/, 803 FILE_ATTRIBUTE_NORMAL, 804 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 805 FILE_OPEN, 806 FILE_OPEN_FOR_BACKUP_INTENT, 807 NULL /*EaBuffer*/, 808 0 /*EaLength*/); 809 RTUtf16Free(NtName.Buffer); 810 if (NT_SUCCESS(rcNt)) 811 { 812 /** @todo Check that the two handles are for the same file object. */ 813 814 return hDupFile; 815 } 816 } 817 } 818 } 819 return INVALID_HANDLE_VALUE; 820 } 821 #endif 822 823 755 824 RTR3DECL(int) RTFileSetSize(RTFILE hFile, uint64_t cbSize) 756 825 { 826 #if 0 827 HANDLE hNtFile = (HANDLE)RTFileToNative(hFile); 828 HANDLE hDupFile = INVALID_HANDLE_VALUE; 829 union 830 { 831 FILE_END_OF_FILE_INFORMATION Eof; 832 FILE_ALLOCATION_INFORMATION Alloc; 833 } uInfo; 834 835 /* 836 * Change the EOF marker. We may have to 837 */ 838 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; 839 uInfo.Eof.EndOfFile.QuadPart = cbSize; 840 NTSTATUS rcNt = NtSetInformationFile(hNtFile, &Ios, &uInfo.Eof, sizeof(uInfo.Eof), FileEndOfFileInformation); 841 if (rcNt == STATUS_ACCESS_DENIED) 842 { 843 hDupFile = rtFileReOpenAppendOnlyWithFullWriteAccess(hNtFile); 844 if (hDupFile != INVALID_HANDLE_VALUE) 845 { 846 hNtFile = hDupFile; 847 uInfo.Eof.EndOfFile.QuadPart = cbSize; 848 rcNt = NtSetInformationFile(hNtFile, &Ios, &uInfo.Eof, sizeof(uInfo.Eof), FileEndOfFileInformation); 849 } 850 } 851 852 if (NT_SUCCESS(rcNt)) 853 { 854 /* 855 * Change the allocation. 856 */ 857 uInfo.Alloc.AllocationSize.QuadPart = cbSize; 858 rcNt = NtSetInformationFile(hNtFile, &Ios, &uInfo.Eof, sizeof(uInfo.Alloc), FileAllocationInformation); 859 } 860 861 /* 862 * Close the temporary file handle: 863 */ 864 if (hDupFile != INVALID_HANDLE_VALUE) 865 NtClose(hDupFile); 866 867 if (RT_SUCCESS(rcNt)) 868 return VINF_SUCCESS; 869 return RTErrConvertFromNtStatus(rcNt); 870 871 #else /* this version of the code will fail to truncate files when RTFILE_O_APPEND is in effect, which isn't what we want... */ 757 872 /* 758 873 * Get current file pointer. … … 795 910 796 911 return RTErrConvertFromWin32(rc); 912 #endif 797 913 } 798 914
Note:
See TracChangeset
for help on using the changeset viewer.