static void Main(string[] args) { Byte[] data; // a variable to hold our desired data... Win32Exception ex, ex2; //see using block below int outputBufferSize = 4096000; //just some buffer ... way to big, but hey ... var unmanagedOutputBuffer = Marshal.AllocHGlobal(outputBufferSize); // Marshal will give us an unmanaged buffer of desired size ... hopefully RAW_READ_INFO ri = new RAW_READ_INFO { DiskOffset = 0, SectorCount = 20, TrackMode = TRACK_MODE_TYPE.YellowMode2 }; // what do we want to read? var ri_size = Marshal.SizeOf(ri); // since we are giving ri to an unmanaged function, we need to tell that function the size of ri int bytesReturned = 0; // if everything works as expected, we will get something written in our unmanaged buffer ... here we can store how many bytes were written using (var hDev = CreateFile(@"\\.\H:", EFileAccess.GenericRead, EFileShare.Read | EFileShare.Write, IntPtr.Zero, ECreationDisposition.OpenExisting, EFileAttributes.Normal, IntPtr.Zero)) { // since we are working with a handle, we have to make sure we release it after we are done ... "using" does that for us ex = new Win32Exception(); //will tell you if CreateFile worked var b = DeviceIoControl(hDev, IOCTL_CDROM_RAW_READ, ref ri, ri_size, unmanagedOutputBuffer, outputBufferSize, ref bytesReturned, IntPtr.Zero); // the magic happens here ex2 = new Win32Exception(); //will tell you if DeviceIoControl worked } if (bytesReturned > 0) { data = new byte[bytesReturned]; //this time, a managed buffer to hold our data Marshal.Copy(unmanagedOutputBuffer, data, 0, bytesReturned); // copy from unmanaged buffer to managed buffer (from the land of dragons and monsters into the .net world) } Marshal.FreeHGlobal(unmanagedOutputBuffer); //release the unmanaged buffer // if everything worked as expected you should now have the first 20 sectors of a ordinary CD-Rom (Yellow Book - Mode 2) in the data array ... }
public extern static int DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, [In] ref RAW_READ_INFO lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped);
private static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, ref RAW_READ_INFO InBuffer, // with RAW_READ_INFO int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize, ref int pBytesReturned, IntPtr lpOverlapped);
public extern static int DeviceIoControl(IntPtr hDevice, uint IoControlCode, [In] RAW_READ_INFO rri, uint InBufferSize, [In, Out] byte[] OutBuffer, uint OutBufferSize, ref uint BytesReturned, IntPtr Overlapped);