You were on the right track. The program was running as administrator so the "Access denied" was confusing me as well. The SafeFileHandle was created like this ...
using (dd = new FileStream(path + ".dd", FileMode.Open, FileAccess.Write, FileShare.Write))
bool finished = NativeMethods.GetSparseRange(ldd.SafeFileHandle, query, ref response, 1024);
So when the DeviceIoControl was called the file was empty which for some reason caused the return code 5.
Changing the FileStream creation for an existing file stopped the error.
However now I get an 0x00000057 error, parameter error which brings me back to the original question as how to pass an array of structures to DeviceIoControl.
This is what I've tried, the output buffer is the issue I think....
public static bool GetSparseRange(SafeFileHandle hdrive, in FILE_ALLOCATED_RANGE_BUFFER query, ref FILE_ALLOCATED_RANGE_BUFFER response, int count)
int nInBufferSize = (int)Marshal.SizeOf(typeof(FILE_ALLOCATED_RANGE_BUFFER));
IntPtr lpInBuffer = Marshal.AllocHGlobal(nInBufferSize);
Marshal.StructureToPtr(query, lpInBuffer, true);
int nOutBufferSize = nInBufferSize * count;
IntPtr lpOutBuffer = Marshal.AllocHGlobal(nOutBufferSize);
//IntPtr ptrArr = new IntPtr[count];
//for (int i = 0; i < count; ++i)
// ptrArr[i] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FILE_ALLOCATED_RANGE_BUFFER)));
// Marshal.StructureToPtr(response[i], ptrArr[i], true);
bool rc = DeviceIoControl(
hdrive, // device to be queried
(uint)EIOControlCode.FsctlQueryAllocatedRanges, // operation to perform
lpInBuffer, (uint)nInBufferSize, // input buffer
//ptrArr, (uint)(nInBufferSize * count), // output buffer
ref bytesread, // # bytes returned
IntPtr.Zero); // synchronous I/O
// Get the last error and display it.
int error = Marshal.GetLastWin32Error();
//for (int j = 0; j < count / nInBufferSize; ++j)
// if (j < bytesread / nInBufferSize)
// Marshal.PtrToStructure(ptrArr[j], response[j]);
General News Suggestion Question Bug Answer Joke Praise Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.