//trial private void button1_Click(object sender, RoutedEventArgs e) { IDiscRecorder2 recorder = new MsftDiscRecorder2(); recorder.InitializeDiscRecorder(selectedDrive); IDiscRecorder2Ex dr2 = recorder as IDiscRecorder2Ex; //recorder.QueryInterface(); byte[] resp = new byte[32]; byte[] recv = new byte[18]; uint sb = 1024; IntPtr respPtr; resp[0] = 0; resp[1] = 0; resp[2] = 0; resp[3] = 0; resp[4] = 0; resp[5] = 0; resp[6] = 0; resp[7] = 0; resp[8] = 0; resp[9] = 0; resp[10] = 0; resp[11] = 0; resp[12] = 0; try { dr2.SendCommandNoData(resp, 6, recv, 60); dr2.GetDiscInformation(out respPtr, ref sb); if (sb > 1024) { sb = 1024; } Marshal.Copy(respPtr, resp, 0, (int)sb); } catch (System.Runtime.InteropServices.COMException) { } }
/// <summary> /// Sends a MMC command to the recording device requesting data from the device. /// </summary> /// <param name="cdb"> /// Command packet to send to the device. Must be between 6 and 16 bytes. /// </param> /// <param name="timeout"> /// Time limit, in seconds, allowed for the send command to receive a result. /// </param> /// <param name="buffer"> /// Application-allocated data buffer that will receive data associated /// with the send command. Must not be null. /// </param> /// <returns> /// Sense data returned by the recording device. /// </returns> Byte[] IDiscRecorder2X.SendCommandGetDataFromDevice(Byte[] cdb, Byte[] buffer, uint timeout) { if (cdb.Length < 6 || cdb.Length > 16) { // TODO: log error throw new ArgumentException("The command packet to send to the device must be between 6 and 16 bytes."); } if (buffer == null || buffer.Length == 0) { // TODO: log error throw new ArgumentNullException("buffer", "The buffer that will receive data associated with the send command must not be null or w/o space."); } uint bufferFetched = 0; Byte[] senseBuffer = new Byte[18]; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.SendCommandGetDataFromDevice(cdb, (uint)cdb.Length, senseBuffer, timeout, buffer, (uint)buffer.Length, ref bufferFetched); if (buffer.Length != bufferFetched) { Array.Resize <Byte>(ref buffer, (int)bufferFetched); } return(senseBuffer); }
/// <summary> /// Sends a DVD structure to the media. /// </summary> /// <param name="format"> /// Format field of the command packet. Acceptable values range from zero to 0xFF. /// </param> /// <param name="data"> /// Data buffer that contains the DVD structure to send to the media. /// Do not include a header; this method generates and prepends a header to the DVD structure. /// </param> void IDiscRecorder2X.SendDvdStructure(Byte[] dvdStructure, uint format) { if (format > 0xFF) { // TODO: log error throw new ArgumentOutOfRangeException("format", "Acceptable values range from zero to 0xFF."); } IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.SendDvdStructure(format, dvdStructure, (uint)dvdStructure.Length); }
/// <summary> /// Sends a MMC command to the recording device. Use this function when no data buffer /// is sent to nor received from the device. /// </summary> /// <remarks>For details of the contents of the command packet and sense data, see the latest revision of the /// MMC specification at ftp://ftp.t10.org/t10/drafts/mmc5/. /// <para>Client-defined commands (CDBs) used with this method must be between 6 and 16 bytes in length. /// In addition, the size of each command must match the size defined by the operation code as defined in the /// following table.</para> /// <para><list type="table"> /// <listheader> /// <term>CDB group</term> /// <term>CDB operation code range</term> /// <term>Required CDB size</term> /// </listheader> /// <item> /// <description>0</description> /// <description>0x00 — 0x1F</description> /// <description>6 bytes</description> /// </item> /// <item> /// <description>1</description> /// <description>0x20 — 0x3F</description> /// <description>10 bytes</description> /// </item> /// <item> /// <description>2</description> /// <description>0x40 — 0x5F</description> /// <description>10 bytes</description> /// </item> /// <item> /// <description>3</description> /// <description>0x60 — 0x7F</description> /// <description>TBD - will enforce standard-specified size requirements for this opcode range in the future.</description> /// </item> /// <item> /// <description>4</description> /// <description>0x80 — 0x9F</description> /// <description>16 bytes</description> /// </item> /// <item> /// <description>5</description> /// <description>0xA0 — 0xBF</description> /// <description>12 bytes</description> /// </item> /// <item> /// <description>6</description> /// <description>0xC0 — 0xDF</description> /// <description>Vendor Unique - Any size allowed</description> /// </item> /// <item> /// <description>7</description> /// <description>0xE0 — 0xFF</description> /// <description>Vendor Unique - Any size allowed</description> /// </item> /// </list></para> /// <para>Some very early devices used vendor-unique opcodes and therefore some opcodes cannot be validated /// in this manner. The following opcodes are still valid and only verify that the size is between 6 and 16 /// bytes:</para><para>0x02, 0x05, 0x06, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x13, 0x14, 0x19, 0x20, 0x21, 0x22, /// 0x23, 0x24, 0x26, 0x27, 0x29, 0x2C, 0x2D</para></remarks> /// <param name="cdb"> /// Command packet to send to the device. /// Must be between 6 and 16 bytes. /// </param> /// <param name="Timeout"> /// Time limit, in seconds, allowed for the send command to receive a result. /// </param> /// <returns>Sense data returned by the recording device.</returns> Byte[] IDiscRecorder2X.SendCommandNoData(Byte[] cdb, uint timeout) { if (cdb.Length < 6 || cdb.Length > 16) { // TODO: log error throw new ArgumentException("The command packet to send to the device must be between 6 and 16 bytes."); } Byte[] senseBuffer = new Byte[18]; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.SendCommandNoData(cdb, (uint)cdb.Length, senseBuffer, timeout); return(senseBuffer); }
/// <summary> /// Retrieves the supported mode pages for the device. /// </summary> /// <param name="requestType"> /// Type of mode page data to retrieve, for example, /// the current settings or the settings that are write enabled. /// For possible values, see the ModePageRequestType enumeration type. /// </param> /// <returns> /// Data buffer that contains one or more mode page types. /// For possible values, see the ModePageType enumeration type. /// To get the mode page data associated with the mode page type, call the IDiscRecorder2Ex.GetModePage /// method. /// </returns> Byte[] IDiscRecorder2X.GetSupportedModePages(ModePageRequestType requestType) { uint byteSize = 0; IntPtr modePageTypesPtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.GetSupportedModePages(requestType, out modePageTypesPtr, ref byteSize); Byte[] modePageTypes = new Byte[byteSize]; Marshal.Copy(modePageTypesPtr, modePageTypes, 0, (int)byteSize); Marshal.FreeCoTaskMem(modePageTypesPtr); return(modePageTypes); }
/// <summary> /// Retrieves the supported profiles or the current profiles of the device. /// </summary> /// <param name="currentOnly"> /// Set to True to retrieve the current profiles. /// Otherwise, False to return all supported profiles of the device. /// </param> /// <returns> /// Data buffer that contains one or more profile types. /// For possible values, see the ProfileType enumeration type. /// </returns> Byte[] IDiscRecorder2X.GetSupportedProfiles(bool currentOnly) { uint validProfiles = 0; IntPtr profileTypesPtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.GetSupportedProfiles(currentOnly, out profileTypesPtr, ref validProfiles); Byte[] profileTypes = new Byte[validProfiles]; Marshal.Copy(profileTypesPtr, profileTypes, 0, (int)validProfiles); Marshal.FreeCoTaskMem(profileTypesPtr); return(profileTypes); }
/// <summary> /// Retrieves the list of supported feature pages or the current feature pages of the device. /// </summary> /// <param name="currentFeatureOnly"> /// Set to True to retrieve only current feature pages. /// Otherwise, False to retrieve all feature pages that the device supports. /// </param> /// <returns> /// Data buffer that contains one or more feature page types. /// For possible values, see the FeaturePageType enumeration type. /// To get the feature page data associated with the feature page type, call the /// IDiscRecorder2X.GetFeaturePage method. /// </returns> Byte[] IDiscRecorder2X.GetSupportedFeaturePages(bool currentFeatureOnly) { uint byteSize = 0; IntPtr featureDataPtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.GetSupportedFeaturePages(currentFeatureOnly, out featureDataPtr, ref byteSize); Byte[] featureData = new Byte[byteSize]; Marshal.Copy(featureDataPtr, featureData, 0, (int)byteSize); Marshal.FreeCoTaskMem(featureDataPtr); return(featureData); }
/// <summary> /// Retrieves the track information from the media (via READ_TRACK_INFORMATION). /// </summary> /// <param name="address"> /// Address field. The addressType parameter provides additional context for /// this parameter. /// </param> /// <param name="addressType"> /// Type of address specified in the address parameter, for example, /// if this is an LBA address or a track number. For possible values, see the ReadTrackAddressType /// enumeration type. /// </param> /// <returns> /// Data buffer that contains the track information. /// For details of the contents of the data buffer, see the READ TRACK INFORMATION command in the /// latest revision of the MMC specification at ftp://ftp.t10.org/t10/drafts/mmc5/. /// </returns> Byte[] IDiscRecorder2X.GetTrackInformation(uint address, ReadTrackAddressType addressType) { uint byteSize = 0; IntPtr trackInformationPtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.GetTrackInformation(address, addressType, out trackInformationPtr, ref byteSize); Byte[] trackInformation = new Byte[byteSize]; Marshal.Copy(trackInformationPtr, trackInformation, 0, (int)byteSize); Marshal.FreeCoTaskMem(trackInformationPtr); return(trackInformation); }
/// <summary> /// Retrieves the disc information from the media (via READ_DISC_INFORMATION).</summary> /// <returns> /// Data buffer that contains disc information from the media. /// For details of the contents of the data buffer, see the READ DISC INFORMATION command in the latest /// revision of the MMC specification at ftp://ftp.t10.org/t10/drafts/mmc5/. /// </returns> Byte[] IDiscRecorder2X.GetDiscInformation() { uint byteSize = 0; IntPtr discDescriptorPtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.GetDiscInformation(out discDescriptorPtr, ref byteSize); Byte[] discDescriptor = new Byte[byteSize]; Marshal.Copy(discDescriptorPtr, discDescriptor, 0, (int)byteSize); Marshal.FreeCoTaskMem(discDescriptorPtr); return(discDescriptor); }
/// <summary> /// Retrieves the adapter descriptor for the device (via IOCTL_STORAGE_QUERY_PROPERTY). /// </summary> /// <returns> /// Data buffer that contains the descriptor of the storage adapter. /// For details of the contents of the data buffer, see the STORAGE_ADAPTER_DESCRIPTOR structure in the DDK. /// </returns> Byte[] IDiscRecorder2X.GetAdapterDescriptor() { uint byteSize = 0; IntPtr adapterDescriptorPtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.GetAdapterDescriptor(out adapterDescriptorPtr, ref byteSize); Byte[] adapterDescriptor = new Byte[byteSize]; Marshal.Copy(adapterDescriptorPtr, adapterDescriptor, 0, (int)byteSize); Marshal.FreeCoTaskMem(adapterDescriptorPtr); return(adapterDescriptor); }
/// <summary> /// Read a DVD Structure from the media /// </summary> /// <param name="format"> /// Format field of the command packet. Acceptable values range from zero to 0xFF. /// </param> /// <param name="address"> /// Address field of the command packet. /// </param> /// <param name="layer"> /// Layer field of the command packet. /// </param> /// <param name="agid"> /// Authentication grant ID (AGID) field of the command packet. /// </param> /// <returns> /// Data buffer that contains the DVD structure. /// For details of the contents of the data buffer, see the READ DISC STRUCTURE command in the /// latest revision of the MMC specification at ftp://ftp.t10.org/t10/drafts/mmc5/. /// This method removes headers from the buffer. /// </returns> Byte[] IDiscRecorder2X.ReadDvdStructure(uint format, uint address, uint layer, uint agid) { if (format > 0xFF) { // TODO: log error throw new ArgumentOutOfRangeException("format", "Acceptable values range from zero to 0xFF."); } uint count = 0; IntPtr dvdStructurePtr; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.ReadDvdStructure(format, address, layer, agid, out dvdStructurePtr, ref count); Byte[] dvdStructure = new Byte[count]; Marshal.Copy(dvdStructurePtr, dvdStructure, 0, (int)count); Marshal.FreeCoTaskMem(dvdStructurePtr); return(dvdStructure); }
/// <summary> /// Sends a MMC command and its associated data buffer to the recording device. /// </summary> /// <param name="cdb"> /// Command packet to send to the device. Must be between 6 and 16 bytes. /// </param> /// <param name="buffer"> /// Buffer containing data associated with the send command. Must not be NULL. /// </param> /// <param name="timeout"> /// Time limit, in seconds, allowed for the send command to receive a result. /// </param> /// <returns> /// Sense data returned by the recording device. /// </returns> Byte[] IDiscRecorder2X.SendCommandSendDataToDevice(Byte[] cdb, Byte[] buffer, uint timeout) { if (cdb.Length < 6 || cdb.Length > 16) { // TODO: log error throw new ArgumentException("The command packet to send to the device must be between 6 and 16 bytes."); } if (buffer == null) { // TODO: log error throw new ArgumentNullException("buffer", "The data associated with the send command must not be NULL."); } Byte[] senseBuffer = new Byte[18]; IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.SendCommandSendDataToDevice(cdb, (uint)cdb.Length, senseBuffer, timeout, buffer, (uint)buffer.Length); return(senseBuffer); }
public void UpdateMediaStatus() { int i; IDiscRecorder2 recorder = new MsftDiscRecorder2(); isSupportedMediaReady = false; isRewritableMedia = false; textSupportedMedia.Text = ""; if (!driveListBox.IsEnabled) { insertedMedia.Text = ""; NextPage.IsEnabled = false; return; } recorder.InitializeDiscRecorder(selectedDrive); IDiscFormat2Data dataWriterImage = new MsftDiscFormat2Data(); try { dataWriterImage.Recorder = recorder; } catch (System.Runtime.InteropServices.COMException e) { if ((uint)e.ErrorCode == 0xC0AA0407) //E_IMAPI_DF2DATA_RECORDER_NOT_SUPPORTED { insertedMedia.Text = ""; NextPage.IsEnabled = false; return; } } int nf, nsec; try{ nf = dataWriterImage.FreeSectorsOnMedia; nsec = dataWriterImage.TotalSectorsOnMedia; } catch (System.Runtime.InteropServices.COMException) { } IDiscRecorder2Ex rc2 = recorder as IDiscRecorder2Ex; byte[] resp = new byte[1024]; uint sb = 1024; IntPtr respPtr; rc2.GetFeaturePage(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_PROFILE_LIST, true, out respPtr, ref sb); if (sb > 1024) { sb = 1024; } Marshal.Copy(respPtr, resp, 0, (int)sb); for (i = 4; i < (int)sb; i += 4) { if (resp[i + 2] != 0) { textSupportedMedia.Text += "*"; isSupportedMediaReady = true; } switch (resp[i + 1]) { case 9: textSupportedMedia.Text += "CD-R "; break; case 10: textSupportedMedia.Text += "CD-RW "; break; case 17: textSupportedMedia.Text += "DVD-R "; break; case 18: textSupportedMedia.Text += "DVD-RAM "; break; case 19: textSupportedMedia.Text += "DVD-RW "; break; case 21: textSupportedMedia.Text += "DVD-R_DL "; break; case 26: textSupportedMedia.Text += "DVD+RW "; break; case 27: textSupportedMedia.Text += "DVD+R "; break; case 43: textSupportedMedia.Text += "DVD+R_DL "; break; case 65: textSupportedMedia.Text += "BD-R "; break; case 67: textSupportedMedia.Text += "BD-RE "; break; } } IMAPI_MEDIA_PHYSICAL_TYPE n; try { n = dataWriterImage.CurrentPhysicalMediaType; switch (n) { case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM: insertedMedia.Text = "CD-ROM or Audio CD"; isCD = true; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR: insertedMedia.Text = Properties.Resources.MediaType_BlankCDR;//"Blank CD-R"; isSupportedMediaReady = true; isCD = true; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW: insertedMedia.Text = "CD-RW"; isSupportedMediaReady = true; isRewritableMedia = true; isCD = true; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW: insertedMedia.Text = Properties.Resources.MediaType_DVDRW; isSupportedMediaReady = true; isRewritableMedia = true; isCD = false; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR: insertedMedia.Text = Properties.Resources.MediaType_BlankDVDR;//"Blank DVD-R"; isSupportedMediaReady = true; isCD = false; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM: insertedMedia.Text = Properties.Resources.MediaType_DVDROM; isCD = false; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR: insertedMedia.Text = Properties.Resources.MediaType_BlankDVDPlusR;//"Blank DVD+R"; isSupportedMediaReady = true; isCD = false; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW: insertedMedia.Text = Properties.Resources.MediaType_DVDPlusRW; isSupportedMediaReady = true; isRewritableMedia = true; isCD = false; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM: //IMAPI_PROFILE_TYPE_DVD_RAM: insertedMedia.Text = Properties.Resources.MediaType_DVDRAM; isSupportedMediaReady = true; isCD = false; isBD = false; isRewritableMedia = true; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR: insertedMedia.Text = Properties.Resources.MediaType_BlankBDR; isSupportedMediaReady = true; isCD = false; isBD = true; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE: insertedMedia.Text = "BD-RE"; isSupportedMediaReady = true; isRewritableMedia = true; isCD = false; isBD = true; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER: insertedMedia.Text = Properties.Resources.MediaType_BlankDVDR_DL; isSupportedMediaReady = true; isCD = false; isBD = false; break; case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER: insertedMedia.Text = Properties.Resources.MediaType_BlankDVDPlusR_DL; isSupportedMediaReady = true; isCD = false; isBD = false; break; default: insertedMedia.Text = Properties.Resources.MediaType_UnknownMedia; break; } } catch (System.Runtime.InteropServices.COMException e) { if ((uint)e.ErrorCode == 0xC0AA0202) //E_IMAPI_RECORDER_MEDIA_NO_MEDIA { insertedMedia.Text = Properties.Resources.MediaTypeError_NoMediaInserted; //"No media inserted."; } else if ((uint)e.ErrorCode == 0xC0AA02FF) //E_IMAPI_RECORDER_INVALID_RESPONSE_FROM_DEVICE { insertedMedia.Text = Properties.Resources.MediaTypeError_InvalidResponseFromDevice; } else { insertedMedia.Text = "No media detected due to internal error."; } } if (isSupportedMediaReady) { NextPage.IsEnabled = true; } else { NextPage.IsEnabled = false; } if (isBD) { //aaa = dataWriterImage.TotalSectorsOnMedia; //aaa = dataWriterImage.FreeSectorsOnMedia; } }
/// <summary> /// Retrieves the maximum page-aligned transfer size for the device. /// </summary> /// <returns> /// Maximum size, in bytes, of a page-aligned buffer. /// </returns> uint IDiscRecorder2X.GetMaximumPageAlignedTransferSize() { IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; return(recorderEx.GetMaximumPageAlignedTransferSize()); }
/// <summary> /// Retrieves the byte alignment mask for the device. /// </summary> /// <returns> /// Byte alignment mask that you use to determine if the buffer is aligned to the correct byte /// boundary for the device. The byte alignment value is always a number that is a power of 2. /// </returns> uint IDiscRecorder2X.GetByteAlignmentMask() { IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; return(recorderEx.GetByteAlignmentMask()); }
/// <summary> /// Sets the mode page data for the device (via MODE_SELECT10). /// </summary> /// <param name="requestType"> /// Type of mode page data to send. /// For possible values, see the ModePageRequestType enumeration type. /// </param> /// <param name="modePage"> /// Data buffer that contains the mode page data to send to the media. /// Do not include a header; this method generates and prepends a header to the mode page data. /// For details on specifying the fields of the mode page data, see the MODE SELECT (10) command in the /// latest revision of the MMC specification at ftp://ftp.t10.org/t10/drafts/mmc5/. /// </param> void IDiscRecorder2X.SetModePage(ModePageRequestType requestType, Byte[] modePage) { IDiscRecorder2Ex recorderEx = (IDiscRecorder2Ex)this; recorderEx.SetModePage(requestType, modePage, (uint)modePage.Length); }