private static unsafe void Preallocate(string fullPath, long preallocationSize, SafeFileHandle fileHandle) { var allocationInfo = new Interop.Kernel32.FILE_ALLOCATION_INFO { AllocationSize = preallocationSize }; if (!Interop.Kernel32.SetFileInformationByHandle( fileHandle, Interop.Kernel32.FileAllocationInfo, &allocationInfo, (uint)sizeof(Interop.Kernel32.FILE_ALLOCATION_INFO))) { int errorCode = Marshal.GetLastPInvokeError(); // Only throw for errors that indicate there is not enough space. if (errorCode == Interop.Errors.ERROR_DISK_FULL || errorCode == Interop.Errors.ERROR_FILE_TOO_LARGE) { fileHandle.Dispose(); // Delete the file we've created. Interop.Kernel32.DeleteFile(fullPath); throw new IOException(SR.Format(errorCode == Interop.Errors.ERROR_DISK_FULL ? SR.IO_DiskFull_Path_AllocationSize : SR.IO_FileTooLarge_Path_AllocationSize, fullPath, preallocationSize)); } } }
private static unsafe void Preallocate(string fullPath, long preallocationSize, SafeFileHandle fileHandle) { var allocationInfo = new Interop.Kernel32.FILE_ALLOCATION_INFO { AllocationSize = preallocationSize }; if (!Interop.Kernel32.SetFileInformationByHandle( fileHandle, Interop.Kernel32.FileAllocationInfo, &allocationInfo, (uint)sizeof(Interop.Kernel32.FILE_ALLOCATION_INFO))) { int errorCode = Marshal.GetLastPInvokeError(); // we try to mimic the atomic NtCreateFile here: // if preallocation fails, close the handle and delete the file fileHandle.Dispose(); Interop.Kernel32.DeleteFile(fullPath); switch (errorCode) { case Interop.Errors.ERROR_DISK_FULL: throw new IOException(SR.Format(SR.IO_DiskFull_Path_AllocationSize, fullPath, preallocationSize)); case Interop.Errors.ERROR_FILE_TOO_LARGE: throw new IOException(SR.Format(SR.IO_FileTooLarge_Path_AllocationSize, fullPath, preallocationSize)); default: throw Win32Marshal.GetExceptionForWin32Error(errorCode, fullPath); } } }