public extern static int DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, [Out] out CDROM_TOC lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped);
internal DiscWin32NT(string device) { int colon = device.IndexOf (':'); if (colon == -1) { throw new ArgumentException ("The device path is not valid.", "device"); } string filename = string.Concat (@"\\.\", device.Substring (0, colon + 1)); CDROM_TOC_SESSION_DATA session = new CDROM_TOC_SESSION_DATA (); CDROM_TOC toc = new CDROM_TOC(); using (SafeFileHandle file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)) { if (file.IsInvalid) { throw new LocalDiscException ("Could not open the CD device."); } uint returned; GCHandle session_handle = GCHandle.Alloc (session, GCHandleType.Pinned); try { bool result = DeviceIoControl (file, IOCTL_CDROM_GET_LAST_SESSION, IntPtr.Zero, 0, session_handle.AddrOfPinnedObject (), (uint)Marshal.SizeOf (session), out returned, IntPtr.Zero); if (!result) { throw new LocalDiscException ("There was a problem while reading the disc TOC."); } } finally { session_handle.Free (); } IntPtr toc_ptr = Marshal.AllocHGlobal (Marshal.SizeOf (toc)); Marshal.StructureToPtr (toc, toc_ptr, false); try { bool result = DeviceIoControl (file, IOCTL_CDROM_READ_TOC, IntPtr.Zero, 0, toc_ptr, (uint)Marshal.SizeOf (toc), out returned, IntPtr.Zero); if (!result) { throw new LocalDiscException ("There was a problem while reading the disc TOC."); } Marshal.PtrToStructure (toc_ptr, toc); } finally { Marshal.FreeHGlobal (toc_ptr); } } first_track = toc.FirstTrack; if (session.FirstCompleteSession != session.LastCompleteSession) { last_track = (byte)(session.TrackData.TrackNumber - 1); track_offsets[0] = toc.TrackData[last_track].GetSectors () - XA_INTERVAL; } else { last_track = toc.LastTrack; track_offsets[0] = toc.TrackData[last_track].GetSectors (); } for (int i = first_track; i <= last_track; i++) { track_offsets[i] = toc.TrackData[i - 1].GetSectors (); } Init (); }
public extern static int DeviceIoControl(IntPtr hDevice, uint IoControlCode, IntPtr InBuffer, uint InBufferSize, [Out] CDROM_TOC OutTOC, uint OutBufferSize, ref uint BytesReturned, IntPtr Overlapped);
internal DiscWin32NT(string device) { int colon = device.IndexOf(':'); if (colon == -1) { throw new ArgumentException("The device path is not valid.", "device"); } string filename = string.Concat(@"\\.\", device.Substring(0, colon + 1)); CDROM_TOC_SESSION_DATA session = new CDROM_TOC_SESSION_DATA(); CDROM_TOC toc = new CDROM_TOC(); using (SafeFileHandle file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero)) { if (file.IsInvalid) { throw new LocalDiscException("Could not open the CD device."); } uint returned; GCHandle session_handle = GCHandle.Alloc(session, GCHandleType.Pinned); try { bool result = DeviceIoControl(file, IOCTL_CDROM_GET_LAST_SESSION, IntPtr.Zero, 0, session_handle.AddrOfPinnedObject(), (uint)Marshal.SizeOf(session), out returned, IntPtr.Zero); if (!result) { throw new LocalDiscException("There was a problem while reading the disc TOC."); } } finally { session_handle.Free(); } IntPtr toc_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(toc)); Marshal.StructureToPtr(toc, toc_ptr, false); try { bool result = DeviceIoControl(file, IOCTL_CDROM_READ_TOC, IntPtr.Zero, 0, toc_ptr, (uint)Marshal.SizeOf(toc), out returned, IntPtr.Zero); if (!result) { throw new LocalDiscException("There was a problem while reading the disc TOC."); } Marshal.PtrToStructure(toc_ptr, toc); } finally { Marshal.FreeHGlobal(toc_ptr); } } first_track = toc.FirstTrack; if (session.FirstCompleteSession != session.LastCompleteSession) { last_track = (byte)(session.TrackData.TrackNumber - 1); track_offsets[0] = toc.TrackData[last_track].GetSectors() - XA_INTERVAL; } else { last_track = toc.LastTrack; track_offsets[0] = toc.TrackData[last_track].GetSectors(); } for (int i = first_track; i <= last_track; i++) { track_offsets[i] = toc.TrackData[i - 1].GetSectors(); } Init(); }