| vbAccelerator - Contents of code file: IMAPIWrapper\IMAPIInterop.csThis file is part of the download IMAPI Wrapper, which is described in the article Image Mastering API (IMAPI) Wrapper for .NET. using System;
using System.Runtime.InteropServices;
using System.Text;
namespace vbAccelerator.Components.ImapiWrapper
{
#region Enumerations used within IMAPI and associated interfaces
/// <summary>
/// Property Set Flags
/// </summary>
[Flags]
internal enum PROPSETFLAG : int
{
PROPSETFLAG_DEFAULT = 0,
PROPSETFLAG_NONSIMPLE = 1,
PROPSETFLAG_ANSI = 2,
PROPSETFLAG_UNBUFFERED = 4
}
/// <summary>
/// Property ID types
/// </summary>
internal enum PRPSPEC : uint
{
PRSPEC_LPWSTR = 0,
PRSPEC_PROPID = 1,
PRSPEC_INVALID = 0xffffffff
}
/// <summary>
/// Contexts for CoCreateInstance
/// </summary>
internal enum CLSCTX : int
{
CLSCTX_INPROC_SERVER = 1,
CLSCTX_INPROC_HANDLER = 2,
CLSCTX_LOCAL_SERVER = 4,
CLSCTX_REMOTE_SERVER = 16
} ;
/// <summary>
/// CD Media Types
/// </summary>
public enum MEDIA_TYPES : int
{
/// <summary>
/// CDDA CDROM media
/// </summary>
MEDIA_CDDA_CDROM = 1,
/// <summary>
/// CD ROM XA media
/// </summary>
MEDIA_CD_ROM_XA = 2,
/// <summary>
/// CD_I media
/// </summary>
MEDIA_CD_I = 3,
/// <summary>
/// CD Extra media
/// </summary>
MEDIA_CD_EXTRA = 4,
/// <summary>
/// CD Other media
/// </summary>
MEDIA_CD_OTHER = 5,
/// <summary>
/// Special media
/// </summary>
MEDIA_SPECIAL = 6
}
/// <summary>
/// Flags describing media
/// </summary>
[Flags]
public enum MEDIA_FLAGS : int
{
/// <summary>
/// Blank media
/// </summary>
MEDIA_BLANK = 0x1,
/// <summary>
/// Read/Write media
/// </summary>
MEDIA_RW = 0x2,
/// <summary>
/// Writable media
/// </summary>
MEDIA_WRITABLE = 0x4,
/// <summary>
/// Unusable media
/// </summary>
MEDIA_FORMAT_UNUSABLE_BY_IMAPI = 0x8
}
/// <summary>
/// CD Recorder types
/// </summary>
public enum RECORDER_TYPES : int
{
/// <summary>
/// CDR recorder
/// </summary>
RECORDER_CDR = 0x1,
/// <summary>
/// CDRW recorder
/// </summary>
RECORDER_CDRW = 0x2
}
/// <summary>
/// State of a recorder on the system
/// </summary>
public enum RECORDER_STATE : int
{
/// <summary>
/// Recorder is idle.
/// </summary>
RECORDER_DOING_NOTHING = 0,
/// <summary>
/// Recorder is opened for exclusive access.
/// </summary>
RECORDER_OPENED = 0x1,
/// <summary>
/// Recorder is burning.
/// </summary>
RECORDER_BURNING = 0x2
}
/// <summary>
/// Flags for IStorage
/// </summary>
[Flags]
internal enum STGC : int
{
STGC_DEFAULT = 0,
STGC_OVERWRITE = 1,
STGC_ONLYIFCURRENT = 2,
STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,
STGC_CONSOLIDATE = 8
}
/// <summary>
/// Storage instantiation modes
/// </summary>
[Flags]
internal enum STGM : int
{
STGM_DIRECT = 0x00000000,
STGM_TRANSACTED = 0x00010000,
STGM_SIMPLE = 0x08000000,
STGM_READ = 0x00000000,
STGM_WRITE = 0x00000001,
STGM_READWRITE = 0x00000002,
STGM_SHARE_DENY_NONE = 0x00000040,
STGM_SHARE_DENY_READ = 0x00000030,
STGM_SHARE_DENY_WRITE = 0x00000020,
STGM_SHARE_EXCLUSIVE = 0x00000010,
STGM_PRIORITY = 0x00040000,
STGM_DELETEONRELEASE = 0x04000000,
STGM_NOSCRATCH = 0x00100000,
STGM_CREATE = 0x00001000,
STGM_CONVERT = 0x00020000,
STGM_FAILIFTHERE = 0x00000000,
STGM_NOSNAPSHOT = 0x00200000,
STGM_DIRECT_SWMR = 0x00400000,
}
/// <summary>
/// IStorage move and copy
/// </summary>
internal enum STGMOVE : int
{
STGMOVE_MOVE = 0,
STGMOVE_COPY = 1,
STGMOVE_SHALLOWCOPY = 2
}
/// <summary>
/// Status flags
/// </summary>
[Flags]
internal enum STATFLAG : int
{
STATFLAG_DEFAULT = 0,
STATFLAG_NONAME = 1,
STATFLAG_NOOPEN = 2
}
/// <summary>
/// Storage type
/// </summary>
internal enum STGTY : int
{
STGTY_STORAGE = 1,
STGTY_STREAM = 2,
STGTY_LOCKBYTES = 3,
STGTY_PROPERTY = 4
}
/// <summary>
/// Lock types
/// </summary>
[Flags]
internal enum LOCKTYPE : int
{
LOCK_WRITE = 1,
LOCK_EXCLUSIVE = 2,
LOCK_ONLYONCE = 4
}
/// <summary>
/// Stream seeking options
/// </summary>
internal enum STREAM_SEEK : int
{
STREAM_SEEK_SET = 0,
STREAM_SEEK_CUR = 1,
STREAM_SEEK_END = 2
}
internal enum GENERIC_ERROR_CODES : uint
{
S_OK = 0,
S_FALSE = 1,
E_NOTIMPL = 0x80004001,
E_FAIL = 0x80004005,
E_UNEXPECTED = 0x8000FFFF
}
internal enum STG_ERROR_CONSTANTS : uint
{
STG_E_INVALIDFUNCTION = 0x80030001,
STG_E_FILENOTFOUND = 0x80030002,
STG_E_INVALIDPOINTER = 0x80030009,
STG_E_INVALIDFLAG = 0x800300FF
}
/// <summary>
/// Error codes returned by IMAPI. These are thrown as <c>COMException</c>
/// errors on calling IMAPI methods; the <c>ErrorCode</c> property of the
/// exception can be compared to these values. Note that the framework
/// will fill in an arbitrary error description which is frequently
/// inappropriate as these codes appear to be the same as error codes
/// used elsewhere in COM.
/// </summary>
public enum IMAPI_ERROR_CODES : uint
{
/// <summary>
/// An unknown property was passed in a property set and it was ignored.
/// </summary>
IMAPI_S_PROPERTIESIGNORED = 0x80040200,
/// <summary>
/// Buffer too small
/// </summary>
IMAPI_S_BUFFER_TOO_SMALL = 0x80040201,
/// <summary>
/// A call to IDiscMaster::Open has not been made.
/// </summary>
IMAPI_E_NOTOPENED = 0x8004020B,
/// <summary>
/// A recorder object has not been initialized.
/// </summary>
IMAPI_E_NOTINITIALIZED = 0x8004020C,
/// <summary>
/// The user canceled the operation.
/// </summary>
IMAPI_E_USERABORT = 0x8004020D,
/// <summary>
/// A generic error occurred.
/// </summary>
IMAPI_E_GENERIC = 0x8004020E,
/// <summary>
/// There is no disc in the device.
/// </summary>
IMAPI_E_MEDIUM_NOTPRESENT = 0x8004020F,
/// <summary>
/// The media is not a type that can be used.
/// </summary>
IMAPI_E_MEDIUM_INVALIDTYPE = 0x80040210,
/// <summary>
/// The recorder does not support any properties.
/// </summary>
IMAPI_E_DEVICE_NOPROPERTIES = 0x80040211,
/// <summary>
/// The device cannot be used or is already in use.
/// </summary>
IMAPI_E_DEVICE_NOTACCESSIBLE = 0x80040212,
/// <summary>
/// The device is not present or has been removed.
/// </summary>
IMAPI_E_DEVICE_NOTPRESENT = 0x80040213,
/// <summary>
/// The recorder does not support an operation.
/// </summary>
IMAPI_E_DEVICE_INVALIDTYPE = 0x80040214,
/// <summary>
/// The drive interface could not be initialized for writing.
/// </summary>
IMAPI_E_INITIALIZE_WRITE = 0x80040215,
/// <summary>
/// The drive interface could not be initialized for closing.
/// </summary>
IMAPI_E_INITIALIZE_ENDWRITE = 0x80040216,
/// <summary>
/// "An error occurred while enabling/disabling file system access or
during auto-insertion detection.
/// </summary>
IMAPI_E_FILESYSTEM = 0x80040217,
/// <summary>
/// An error occurred while writing the image file.
/// </summary>
IMAPI_E_FILEACCESS = 0x80040218,
/// <summary>
/// An error occurred while trying to read disc data from the device.
/// </summary>
IMAPI_E_DISCINFO = 0x80040219,
/// <summary>
/// An audio track is not open for writing.
/// </summary>
IMAPI_E_TRACKNOTOPEN = 0x8004021A,
/// <summary>
/// An open audio track is already being staged.
/// </summary>
IMAPI_E_TRACKOPEN = 0x8004021B,
/// <summary>
/// The disc cannot hold any more data.
/// </summary>
IMAPI_E_DISCFULL = 0x8004021C,
/// <summary>
/// The application tried to add a badly named element to a disc.
/// </summary>
IMAPI_E_BADJOLIETNAME = 0x8004021D,
/// <summary>
/// The staged image is not suitable for a burn. It has been
/// corrupted or cleared and has no usable content.
/// </summary>
IMAPI_E_INVALIDIMAGE = 0x8004021E,
/// <summary>
/// An active format master has not been selected using
/// IDiscMaster::SetActiveDiscMasterFormat.
/// </summary>
IMAPI_E_NOACTIVEFORMAT = 0x8004021F,
/// <summary>
/// An active disc recorder has not been selected using
/// IDiscMaster::SetActiveDiscRecorder.
/// </summary>
IMAPI_E_NOACTIVERECORDER = 0x80040220,
/// <summary>
/// A call to IJolietDiscMaster has been made when IRedbookDiscMaster is
/// the active format, or vice versa. To use a different format, change
/// the format and clear the image file contents.
/// </summary>
IMAPI_E_WRONGFORMAT = 0x80040221,
/// <summary>
/// A call to IDiscMaster::Open has already been made against this
/// object by your application.
/// </summary>
IMAPI_E_ALREADYOPEN = 0x80040222,
/// <summary>
/// The IMAPI multi-session disc has been removed from the active
recorder.
/// </summary>
IMAPI_E_WRONGDISC = 0x80040223,
/// <summary>
/// The file to add is already in the image file and the overwrite
/// flag was not set.
/// </summary>
IMAPI_E_FILEEXISTS = 0x80040224,
/// <summary>
/// Another application is already using the IMAPI stash file required to
/// stage a disc image. Try again later.
/// </summary>
IMAPI_E_STASHINUSE = 0x80040225,
/// <summary>
/// Another application is already using this device, so IMAPI cannot
/// access the device.
/// </summary>
IMAPI_E_DEVICE_STILL_IN_USE = 0x80040226,
/// <summary>
/// Content streaming was lost; a buffer under-run may have occurred.
/// </summary>
IMAPI_E_LOSS_OF_STREAMING = 0x80040227,
/// <summary>
/// The stash is located on a compressed volume and cannot be read.
/// </summary>
IMAPI_E_COMPRESSEDSTASH = 0x80040228,
/// <summary>
/// The stash is located on an encrypted volume and cannot be read.
/// </summary>
IMAPI_E_ENCRYPTEDSTASH = 0x80040229,
/// <summary>
/// There is not enough free space to create the stash file on the
specified volume.
/// </summary>
IMAPI_E_NOTENOUGHDISKFORSTASH = 0x8004022A,
/// <summary>
/// The selected stash location is on a removable media.
/// </summary>
IMAPI_E_REMOVABLESTASH = 0x8004022B,
/// <summary>
/// Cannot write to the media.
/// </summary>
IMAPI_E_CANNOT_WRITE_TO_MEDIA = 0x8004022C,
/// <summary>
/// Track was too short.
/// </summary>
IMAPI_E_TRACK_NOT_BIG_ENOUGH = 0x8004022D,
/// <summary>
/// Attempt to create a bootable image on a non-blank disc.
/// </summary>
IMAPI_E_BOOTIMAGE_AND_NONBLANK_DISC = 0x8004022E
}
#endregion
#region Interop Structures
/// <summary>
/// STATPROPSTG
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential)]
internal struct STATPROPSTG
{
public IntPtr lpwstrName;
public int propid;
public short vt;
}
/// <summary>
/// PROPSPEC
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential)]
internal struct PROPSPEC
{
public PRPSPEC ulKind;
public IntPtr ID_or_LPWSTR;
}
/// <summary>
/// STATPROPSETSTG
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential)]
internal struct STATPROPSETSTG
{
public Guid fmtid;
public Guid clsid;
public int grfFlags;
public long mtime;
public long ctime;
public long atime;
public int dwOSVersion;
}
/// <summary>
/// STATSTG
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential)]
internal struct STATSTG
{
public IntPtr pwcsName;
public STGTY type;
public long cbSize;
public long mtime;
public long ctime;
public long atime;
public STGM grfMode;
public LOCKTYPE grfLocksSupported;
public Guid clsid;
public int grfStateBits;
public int reserved;
}
#endregion
#region Com Interop for IUnknown
/// <summary>
/// IUnknown Interface
/// </summary>
[ComImport, Guid("00000000-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IUnknown
{
[PreserveSig]
IntPtr QueryInterface(ref Guid riid, out IntPtr pVoid);
[PreserveSig]
IntPtr AddRef();
[PreserveSig]
IntPtr Release();
}
#endregion
#region COM Interop for IMalloc
[ComImportAttribute()]
[GuidAttribute("00000002-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
//helpstring("IMalloc interface")
internal interface IMalloc
{
[PreserveSig]
IntPtr Alloc(int cb);
[PreserveSig]
IntPtr Realloc(
IntPtr pv,
int cb);
[PreserveSig]
void Free(IntPtr pv);
[PreserveSig]
int GetSize(IntPtr pv);
[PreserveSig]
int DidAlloc(IntPtr pv);
[PreserveSig]
void HeapMinimize();
};
#endregion
#region COM Interop for IEnumSTATPROPSTG
/// <summary>
/// IEnumSTATPROPSTG interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("00000139-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IEnumSTATPROPSTG
{
[PreserveSig]
int Next(
int celt,
ref STATPROPSTG pSTATPROPSTG,
out int pceltFetched);
void Skip(
int celt);
void Reset();
void Clone(
ref IEnumSTATPROPSTG ppenum);
}
#endregion
#region COM Interop for IPropertyStorage
/// <summary>
/// IPropertyStorage interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("00000138-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPropertyStorage
{
void ReadMultiple(
int cpspec,
ref PROPSPEC rgpspec,
[MarshalAs(UnmanagedType.Struct)]
out object rgpropvar);
void WriteMultiple(
int cpspec,
ref PROPSPEC rgpspec,
[MarshalAs(UnmanagedType.Struct)]
ref object rgPropvar,
int propidNameFirst);
void DeleteMultiple(
int cpspec,
ref PROPSPEC rgpspec);
void ReadPropertyNames(
int cpropid,
[In()]
ref int rgpropidp,
[Out(), MarshalAs(UnmanagedType.LPWStr)]
out string rglpwstrName);
void WritePropertyNames(
int cpropid,
ref int rgpropid,
[In(), MarshalAs(UnmanagedType.LPWStr)]
ref string rglpwstrName);
void DeletePropertyNames(
int cpropid,
[In()]
ref int rgpropid);
void Commit(
ref STGC grfCommitFlags);
void Revert();
void Enum(
ref IEnumSTATPROPSTG ppenum);
void SetTimes(
[In()]
ref long pctime,
[In()]
ref long patime,
[In()]
ref long pmtime);
void SetClass(
ref Guid clsid);
void Stat(
out STATPROPSETSTG pstatpsstg);
}
#endregion
#region COM Interop for IStream
/// <summary>
/// IStream interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("0000000c-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IStream
{
[PreserveSig()]
uint Read(
IntPtr pv,
int cb,
ref int pcbRead);
[PreserveSig()]
uint Write(
IntPtr pv,
int cb,
ref int pcbWritten);
[PreserveSig()]
uint Seek(
long dlibMove,
STREAM_SEEK dwOrigin,
ref long plibNewPosition);
[PreserveSig()]
uint SetSize(
long libNewSize);
[PreserveSig()]
uint CopyTo(
[In()]
ref IStream pstm,
long cb,
ref long pcbRead,
ref long pcbWritten);
[PreserveSig()]
uint Commit(
ref STGC grfCommitFlags);
[PreserveSig()]
uint Revert();
[PreserveSig()]
uint LockRegion(
long libOffset,
long cb,
int dwLockType);
[PreserveSig()]
uint UnlockRegion(
long libOffset,
long cb,
int dwLockType);
[PreserveSig()]
uint Stat(
ref STATSTG pstatstg,
STATFLAG grfStatFlag);
[PreserveSig()]
uint Clone(
out IStream ppstm);
}
#endregion
#region COM Interop for IEnumSTATSTG
/// <summary>
/// IEnumSTATSTG interface.
/// </summary>
[ComImportAttribute()]
[GuidAttribute("0000000d-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IEnumSTATSTG
{
[PreserveSig()]
uint Next(
int celt,
ref STATSTG rgelt,
out int pceltFetched);
[PreserveSig()]
uint Skip(
int celt);
[PreserveSig()]
uint Reset();
[PreserveSig()]
uint Clone(
out IEnumSTATSTG ppenum);
}
#endregion
#region COM Interop for IStorage
/// <summary>
/// IStorage interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("0000000b-0000-0000-c000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IStorage
{
[PreserveSig()]
uint CreateStream(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName,
STGM grfMode,
int reserved1,
int reserved2,
out IStream ppstm);
[PreserveSig()]
uint OpenStream(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName,
int reserved1,
STGM grfMode,
int reserved2,
out IStream ppstm);
[PreserveSig()]
uint CreateStorage(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName,
STGM grfMode,
int reserved1,
int reserved2,
out IStorage ppstg);
[PreserveSig()]
uint OpenStorage(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName,
int pstgPriority,
STGM grfMode,
int snbExclude,
int reserved,
out IStorage ppstg);
[PreserveSig()]
uint CopyTo(
int ciidExclude,
ref Guid rgiidExclude,
int snbExclude,
[In()]
ref IStorage pstgDest);
[PreserveSig()]
uint MoveElementTo(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName,
[In()]
ref IStorage pstgDest,
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsNewName,
STGMOVE grfFlags);
[PreserveSig()]
uint Commit(
STGC grfCommitFlags);
[PreserveSig()]
uint Revert();
[PreserveSig()]
uint EnumElements(
int reserved1,
int reserved2,
int reserved3,
out IEnumSTATSTG ppenum);
[PreserveSig()]
uint DestroyElement(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName);
[PreserveSig()]
uint RenameElement(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsOldName,
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsNewName);
[PreserveSig()]
uint SetElementTimes(
[MarshalAs(UnmanagedType.LPWStr)]
string pwcsName,
[In()]
ref long pctime,
[In()]
ref long patime,
[In()]
ref long pmtime);
[PreserveSig()]
uint SetClass(
[In()]
ref Guid clsid);
[PreserveSig()]
uint SetStateBits(
int grfStateBits,
int grfMask);
[PreserveSig()]
uint Stat(
out STATSTG pstatstg,
STATFLAG grfStatFlag);
}
#endregion
#region COM Interop for ICDBurn
/// <summary>
/// ICDBurn interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("3d73a659-e5d0-4d42-afc0-5121ba425c8d")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface ICDBurn
{
/// <summary>
/// Gets the drive letter of the default recorder
/// </summary>
void GetRecorderDriveLetter(
[Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszPathBuffer,
int cch );
/// <summary>
/// Burns the files in the staging area to disc
/// </summary>
void Burn(
IntPtr hWnd );
/// <summary>
/// Gets whether the system has a recordable drive
/// </summary>
void HasRecordableDrive(
out int pfHasRecorder);
};
#endregion
/// <summary>
/// IDiscRecorder
/// </summary>
[ComImportAttribute()]
[GuidAttribute("85AC9776-CA88-4cf2-894E-09598C078A41")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IDiscRecorder
{
/// <summary>
/// Initializes the object for an underlying device. Used internally
only.
/// </summary>
void Init(
ref IntPtr pbyUniqueID,
int nulIDSize,
int nulDriveNumber);
/// <summary>
/// Retrieves the underlying device GUID.
/// </summary>
/// <param name="pbyUniqueID"></param>
/// <param name="ulBufferSize"></param>
/// <param name="pulReturnSizeRequired"></param>
void GetRecorderGUID(
ref IntPtr pbyUniqueID,
int ulBufferSize,
out int pulReturnSizeRequired);
/// <summary>
/// Identifies the device as CD-R or CD-RW
/// </summary>
/// <param name="fTypeCode"></param>
void GetRecorderType(
out int fTypeCode);
/// <summary>
/// Retrieves a name suitable for GUI display
/// </summary>
void GetDisplayNames(
[MarshalAs(UnmanagedType.BStr)] ref string pbstrVendorID,
[MarshalAs(UnmanagedType.BStr)] ref string pbstrProductID,
[MarshalAs(UnmanagedType.BStr)] ref string pbstrRevision);
/// <summary>
/// Returns an identifier unique to the device class
/// </summary>
/// <param name="pbstrPath"></param>
void GetBasePnPID(
[MarshalAs(UnmanagedType.BStr)] out string pbstrPath);
/// <summary>
/// Returns an OS Path to the device
/// </summary>
/// <param name="pbstrPath"></param>
void GetPath(
[MarshalAs(UnmanagedType.BStr)] out string pbstrPath);
/// <summary>
/// Retrieves a pointer to the IPropertyStorage interface for the recorder
/// </summary>
/// <param name="ppPropStg"></param>
void GetRecorderProperties(
out IPropertyStorage ppPropStg);
/// <summary>
/// Sets properties for the recorder
/// </summary>
void SetRecorderProperties(
[In()]
ref IPropertyStorage ppPropStg);
/// <summary>
/// Checks if the recorder is ready to burn
/// </summary>
void GetRecorderState(
out int pulDevStateFlags);
/// <summary>
/// Opens a device for exclusive use
/// </summary>
void OpenExclusive();
/// <summary>
/// Identifies the type of media in the recorder
/// </summary>
void QueryMediaType(
out int fMediaType,
out int fMediaFlags);
/// <summary>
/// Retrieves the media properties
/// </summary>
void QueryMediaInfo(
out byte pbSessions,
out byte pbLastTrack,
out int ulStartAddress,
out int ulNextWritable,
out int ulFreeBlocks);
/// <summary>
/// Ejects a recorder's tray, if possible
/// </summary>
void Eject();
/// <summary>
/// Erases CD-RW media, if possible
/// </summary>
void Erase(
int bFulLErase);
/// <summary>
/// Closes a recorder after exclusive access
/// </summary>
void Close();
}
/// <summary>
/// IEnumDiscMasterFormats interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("DDF445E1-54BA-11d3-9144-00104BA11C5E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IEnumDiscMasterFormats
{
[PreserveSig()]
int Next(
int cFormats,
out Guid lpiidFormatID,
out int pcFetched);
void Skip(
int cFormats);
void Reset();
void Clone(
out IEnumDiscMasterFormats ppEnum);
}
/// <summary>
/// IEnumDiscRecorders interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("9B1921E1-54AC-11d3-9144-00104BA11C5E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IEnumDiscRecorders
{
[PreserveSig()]
int Next(
int cRecorders,
out IDiscRecorder ppRecorder,
out int pcFetched);
void Skip(
int cRecorders);
void Reset();
void Clone(
out IEnumDiscRecorders ppEnum);
}
/// <summary>
/// IDiscMasterProgressEvents interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("EC9E51C1-4E5D-11D3-9144-00104BA11C5E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IDiscMasterProgressEvents
{
/// <summary>
/// Called to request whether the burn event should be cancelled
/// </summary>
void QueryCancel(
out int pbCancel);
/// <summary>
/// Notifies that a Plug and Play activity has occurred that has changed
the list of recorders.
/// </summary>
void NotifyPnPActivity();
/// <summary>
/// Notifies addition of data to the CD image in the stash.
/// </summary>
void NotifyAddProgress(
int nCompleted,
int nTotal);
/// <summary>
/// Notifies an application of block progress whilst burning a disc.
/// </summary>
void NotifyBlockProgress(
int nCurrentBlock,
int nTotalBlocks);
/// <summary>
/// Notifies an application of track progress whilst burning an audio
disc.
/// </summary>
void NotifyTrackProgress(
int nCurrentTrack,
int nTotalTracks);
/// <summary>
/// Notifies an application that IMAPI is preparing to burn a disc.
/// </summary>
void NotifyPreparingBurn(
int nEstimatedSeconds);
/// <summary>
/// Notifies an application that IMAPI is closing a disc.
/// </summary>
void NotifyClosingDisc(
int nEstimatedSeconds);
/// <summary>
/// Notifies an application that IMAPI has completed burning a disc.
/// </summary>
void NotifyBurnComplete(
int status);
/// <summary>
/// Notifies an application that IMAPI has completed erasing a disc.
/// </summary>
void NotifyEraseComplete(
int status);
}
/// <summary>
/// IDiscMaster interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("520CCA62-51A5-11D3-9144-00104BA11C5E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IDiscMaster
{
/// <summary>
/// Opens an IMAPI object
/// </summary>
void Open();
/// <summary>
/// Retrieves a format enumerator
/// </summary>
void EnumDiscMasterFormats(
out IEnumDiscMasterFormats ppEnum);
/// <summary>
/// Retrieves the currently selected recorder format
/// </summary>
void GetActiveDiscMasterFormat(
out Guid lpiid);
/// <summary>
/// Sets a new active recorder format
/// </summary>
void SetActiveDiscMasterFormat(
[In()]
ref Guid riid,
[MarshalAs(UnmanagedType.Interface)]
out object ppUnk);
/// <summary>
/// Retrieves a recorder enumerator
/// </summary>
void EnumDiscRecorders(
out IEnumDiscRecorders ppEnum);
/// <summary>
/// Gets the active disc recorder
/// </summary>
void GetActiveDiscRecorder(
out IDiscRecorder ppRecorder);
/// <summary>
/// Sets the active disc recorder
/// </summary>
void SetActiveDiscRecorder(
IDiscRecorder pRecorder);
/// <summary>
/// Clears the contents of an unburnt image
/// </summary>
void ClearFormatContent();
/// <summary>
/// Registers for progress notifications
/// </summary>
void ProgressAdvise(
IDiscMasterProgressEvents pEvents,
out IntPtr pvCookie);
/// <summary>
/// Cancels progress notifications
/// </summary>
void ProgressUnadvise(
IntPtr vCookie);
/// <summary>
/// Burns the staged image to the active recorder
/// </summary>
void RecordDisc(
int bSimulate,
int bEjectAfterBurn);
/// <summary>
/// Closes the interface
/// </summary>
void Close();
}
/// <summary>
/// IRedbookDiscMaster interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("E3BC42CD-4E5C-11D3-9144-00104BA11C5E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IRedbookDiscMaster
{
/// <summary>
/// Gets the total number of audio tracks
/// </summary>
void GetTotalAudioTracks(
out int pnTracks);
/// <summary>
/// Gets the total number of audio blocks
/// </summary>
void GetTotalAudioBlocks(
out int pnBlocks);
/// <summary>
/// Gets the used number of audio blocks
/// </summary>
void GetUsedAudioBlocks(
out int pnBlocks);
/// <summary>
/// Gets the number of available audio track blocks
/// </summary>
void GetAvailableAudioTrackBlocks(
out int pnBlocks);
/// <summary>
/// Gets the size of an audio block in bytes
/// </summary>
void GetAudioBlockSize(
out int pnBlockBytes);
/// <summary>
/// Creates a new audio track in the staging area
/// </summary>
void CreateAudioTrack(
int nBlocks);
/// <summary>
/// Adds a block to the current audio track
/// </summary>
void AddAudioTrackBlocks(
IntPtr cb,
int pby);
/// <summary>
/// Closes the current audio track
/// </summary>
void CloseAudioTrack();
}
/// <summary>
/// IJolietDiscMaster interface
/// </summary>
[ComImportAttribute()]
[GuidAttribute("E3BC42CE-4E5C-11D3-9144-00104BA11C5E")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IJolietDiscMaster
{
/// <summary>
/// Gets the total number of data blocks
/// </summary>
void GetTotalDataBlocks(
out int pnBlocks);
/// <summary>
/// Gets the number of used data blocks
/// </summary>
void GetUsedDataBlocks(
out int pnBlocks);
/// <summary>
/// Gets the size of a data block
/// </summary>
void GetDataBlockSize(
out int pnBlockBytes);
/// <summary>
/// Adds data from an IStorage interface
/// </summary>
void AddData(
IStorage pStorage,
int lFileOverwrite);
/// <summary>
/// Gets the properties of the Joliet writer
/// </summary>
void GetJolietProperties(
out IPropertyStorage ppPropStg);
/// <summary>
/// Sets the properties of the Joliet writer
/// </summary>
void SetJolietProperties(
[In()]
ref IPropertyStorage pPropStg);
}
#region IMAPIObjectFactory class
/// <summary>
/// A factory for instantiating IMAPI and ICDBurn objects.
/// </summary>
internal class IMAPIObjectFactory
{
private const string CLSID_CDBURN =
"fbeb8a05-beee-4442-804e-409d6c4515e9";
private const string IID_CDBURN =
"3d73a659-e5d0-4d42-afc0-5121ba425c8d";
private const string CLSID_MSDiscMasterObj =
"520CCA63-51A5-11D3-9144-00104BA11C5E";
private const string IID_IDiscMaster =
"520CCA62-51A5-11D3-9144-00104BA11C5E";
[DllImport("ole32", CharSet = CharSet.Unicode)]
private extern static int CoCreateInstance(
ref Guid CLSID,
IntPtr pUnkOuter,
CLSCTX dwClsContext,
ref Guid IID,
[MarshalAs(UnmanagedType.Interface)]
out object ppv);
/// <summary>
/// Should not be able to instantiate this class
/// </summary>
private IMAPIObjectFactory()
{
}
/// <summary>
/// Creates a new instance of the <c>ICDBurn</c> implementation
/// on this system, if the system supports it.
/// </summary>
/// <returns>Implementating intance of <c>ICDBurn</c></returns>
/// <exception cref="COMException">if the system does not have an
/// <c>ICDBurn</c> implementation.</exception>
public static ICDBurn CreateCDBurn()
{
object cdBurn = null;
Guid clsIdCDBurn = new Guid(CLSID_CDBURN);
Guid iidCDBurn = new Guid(IID_CDBURN);
int hResult = IMAPIObjectFactory.CoCreateInstance(
ref clsIdCDBurn, IntPtr.Zero, CLSCTX.CLSCTX_INPROC_SERVER,
ref iidCDBurn, out cdBurn);
if (ComUtility.Failed(hResult))
{
throw new COMException("Failed to instantiate the ICDBurn
implementation",
(int) hResult);
}
return (ICDBurn) cdBurn;
}
/// <summary>
/// Creates a new instance of the <c>IDiscMaster</c> implementation
/// on this system, if the system supports it.
/// </summary>
/// <returns>Implementating intance of <c>IDiscMaster</c></returns>
/// <exception cref="COMException">if the system does not have an
/// <c>IDiscMaster</c> implementation.</exception>
public static IDiscMaster CreateDiscMaster()
{
object discMaster = null;
Guid clsIdDiscMaster = new Guid(CLSID_MSDiscMasterObj);
Guid iidDiscMaster = new Guid(IID_IDiscMaster);
int hResult = IMAPIObjectFactory.CoCreateInstance(
ref clsIdDiscMaster, IntPtr.Zero, CLSCTX.CLSCTX_INPROC_SERVER |
CLSCTX.CLSCTX_LOCAL_SERVER,
ref iidDiscMaster, out discMaster);
if (ComUtility.Failed(hResult))
{
throw new COMException("Failed to instantiate the IDiscMaster
implementation",
hResult);
}
return (IDiscMaster) discMaster;
}
}
#endregion
[StructLayout(LayoutKind.Explicit)]
internal struct Variant
{
[FieldOffset(0)]
public short vt;
[FieldOffset(8)]
public IntPtr ptr;
[FieldOffset(8)]
public byte Byte;
[FieldOffset(8)]
public long Long;
/// <summary>
/// Converts an object to a variant in this structure
/// </summary>
/// <param name="o">Object to convert</param>
public void ForObject(object o)
{
if (o is string)
{
vt = (short) VarEnum.VT_LPWSTR;
ptr = Marshal.StringToHGlobalUni((string) o);
}
else if (o is DateTime)
{
vt = (short) VarEnum.VT_DATE;
Long = ((DateTime) o).ToFileTime();
}
else if (o is bool)
{
vt = (short) VarEnum.VT_BOOL;
Byte = (byte) ((bool) o ? 1 : 0);
}
else if (o is byte)
{
vt = (short) VarEnum.VT_UI1;
Byte = (byte) o;
}
else if (o is short)
{
vt = (short) VarEnum.VT_UI2;
ptr = (IntPtr) o;
}
else if (o is int)
{
vt = (short) VarEnum.VT_I4;
ptr = (IntPtr) o;
}
else if (o is long)
{
vt = (short) VarEnum.VT_I8;
Long = (long) o;
}
else
{
throw new ArgumentException(
String.Format("Unsupported variant type {0}", vt));
}
}
/// <summary>
/// Converts a variant to an object
/// </summary>
/// <returns></returns>
public object ToObject()
{
object ret = null;
switch ((VarEnum) vt)
{
case VarEnum.VT_BSTR:
ret = Marshal.PtrToStringBSTR(ptr);
Marshal.FreeCoTaskMem(ptr);
break;
case VarEnum.VT_UI1:
ret = Byte;
break;
case VarEnum.VT_UI2:
ret = (short) Long;
break;
case VarEnum.VT_I4:
ret = (int) ptr;
break;
case VarEnum.VT_UI8:
ret = Long;
break;
case VarEnum.VT_INT:
ret = (short) Long;
break;
case VarEnum.VT_LPSTR:
ret = Marshal.PtrToStringAnsi(ptr);
Marshal.FreeCoTaskMem(ptr);
break;
case VarEnum.VT_LPWSTR:
ret = Marshal.PtrToStringUni(ptr);
Marshal.FreeCoTaskMem(ptr);
break;
case VarEnum.VT_FILETIME:
ret = DateTime.FromFileTime(Long);
break;
case VarEnum.VT_BOOL:
ret = (Byte == 0 ? false : true);
break;
case VarEnum.VT_NULL:
case VarEnum.VT_EMPTY:
break;
default:
throw new ArgumentException(
String.Format("Unsupported variant type {0}", vt));
}
return ret;
}
/// <summary>
/// Clears up any resources associated with the structure
/// </summary>
public void Clear()
{
if ((vt == (short) VarEnum.VT_LPSTR)
|| (vt == (short) VarEnum.VT_LPWSTR)
|| (vt == (short) VarEnum.VT_BSTR))
{
Marshal.FreeHGlobal(ptr);
}
else
{
ComUtility.VariantClear(this);
}
}
}
internal class ComUtility
{
private const uint FAIL_BIT = 0x80000000;
private ComUtility()
{
}
[DllImport("ole32")]
public extern static int VariantClear(Variant vt);
public static bool Failed(int hResult)
{
return (((uint) hResult & FAIL_BIT) == FAIL_BIT);
}
}
}
| |||
|
|
||||