Note that there are some explanatory texts on larger screens.

plurals
  1. POReadFile Kernel32 Maximum Buffer Size
    text
    copied!<p>I am reading directly from a disk using C# and pinvoking the kernel32 ReadFile method. I notice that with larger reads (currently only reading in single chunks) the buffer size is out of range.</p> <p>Does anyone know the maximum size of the read buffer here? </p> <p>If so what is the purpose of limiting the buffer size when I have surplus memory I <em>want</em> to read into? I understand the concepts of buffering and keeping a small memory footprint but why is a small size forced upon us? Perhaps just an artefact of an old Win32 API?</p> <p>EDIT: The error received from <code>Marshal.GetLastWin32Error()</code> is "Value does not fall within the expected range."</p> <p>The upper limit before I receive this error is 8192 bytes (8KB - hence my confusion).</p> <pre><code>using System; using System.IO; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; namespace DiskRead { class Program { public const uint GenericRead = 0x80000000; public const uint FileShareRead = 1; public const uint FileShareWrite = 2; public const uint OpenExisting = 3; [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); static void Main(string[] args) { string path = @"\\.\PhysicalDrive0"; IntPtr ptr = CreateFile(path, GenericRead, FileShareRead | FileShareWrite, IntPtr.Zero, OpenExisting, 0, IntPtr.Zero); SafeFileHandle handleValue = new SafeFileHandle(ptr, true); FileStream fileStream = new FileStream(handleValue, FileAccess.Read); const uint numberOfBytesToRead = 8193; uint bytesRead; byte[] buffer = new byte[numberOfBytesToRead]; if (!ReadFile(handleValue.DangerousGetHandle(), buffer, numberOfBytesToRead, out bytesRead, IntPtr.Zero)) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } } } </code></pre> <p>Thanks in advance.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload