vbAccelerator - Contents of code file: IMAPIWrapper\SimpleDiscRecorder.cs

This 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.IO;
using System.Text;
using System.Runtime.InteropServices;

namespace vbAccelerator.Components.ImapiWrapper
{
   /// <summary>
   /// Provides a wrapper around the Shell <c>ICDBurn</c> implementation
   /// on this system.
   /// </summary>
   public class SimpleDiscRecorder : IDisposable
   {
      #region Unmanaged methods
      [DllImport("shell32", CharSet = CharSet.Auto)]
      private extern static int SHGetMalloc(out IMalloc ppMalloc);

      [DllImport("shell32", CharSet = CharSet.Auto)]
      private extern static int SHGetPathFromIDList (
         IntPtr pidl, 
         StringBuilder pszPath);
   
      [DllImport("shell32", CharSet = CharSet.Auto)]
      private extern static int SHGetSpecialFolderLocation(
         IntPtr hWndOwner,
         int nFolder,
         ref IntPtr pidl);
      #endregion

      #region Member Variables
      private const int CSIDL_CDBURN_AREA = 0x3B;
      private bool disposed = false;
      private readonly ICDBurn cdBurnImpl = null;
      private IMalloc alloc = null;
      #endregion

      /// <summary>
      /// Prevent construction of this class outside of the
      /// wrapper
      /// </summary>
      /// <param name="cdBurnImpl">ICDBurn implementation</param>
      internal SimpleDiscRecorder(ICDBurn cdBurnImpl)
      {
         this.cdBurnImpl = cdBurnImpl;
      }

      /// <summary>
      /// Disposes any resources associated with this class.
      /// </summary>
      public void Dispose()
      {
         Dispose(true);
         GC.SuppressFinalize(this);
      }

      /// <summary>
      /// Disposes any resources associated with this class
      /// </summary>
      /// <param name="disposing"><c>true</c> if called from the
      /// <c>Dispose</c> method, otherwise <c>false</c></param>
      protected virtual void Dispose(bool disposing)
      {
         if (!disposed)
         {
            if (disposing)
            {
               if (alloc != null)
               {
                  Marshal.ReleaseComObject(alloc);
               }
               if (cdBurnImpl != null)
               {
                  Marshal.ReleaseComObject(cdBurnImpl);
               }
               disposed = true;
            }
         }
      }

      /// <summary>
      /// Destructor
      /// </summary>
      ~SimpleDiscRecorder()
      {
         Dispose(false);
      }

      /// <summary>
      /// Gets the burn staging area folder.
      /// </summary>
      /// <param name="handle">Handle to the main form of the calling
      /// application.</param>
      /// <returns>Path of the burn staging area folder.</returns>
      public string GetBurnStagingAreaFolder(IntPtr handle)
      {
         IntPtr pidl = IntPtr.Zero;
         SHGetSpecialFolderLocation(
            handle, CSIDL_CDBURN_AREA, ref pidl);
         string folder = PathFromPidl(pidl);
         Allocator.Free(pidl);
         
         return folder;
      }

      /// <summary>
      /// Gets whether this system has a CD recorder or not.
      /// </summary>
      /// <returns><c>true</c> if the system has a CD recorder,
      /// <c>false</c> otherwise.</returns>
      public bool HasRecordableDrive()
      {
         int hasRecorder = 0;
         cdBurnImpl.HasRecordableDrive(out hasRecorder);
         return ((hasRecorder == 0) ? false : true);
      }

      /// <summary>
      /// Gets the drive letter for the CD recorder on this
      /// system, if the system has a CD recorder.
      /// </summary>
      /// <returns>Drive letter of the CD recorder, for example,
      /// C:\</returns>
      public string GetRecorderDriveLetter()
      {
         StringBuilder pathBuffer = new StringBuilder(10, 10);
         cdBurnImpl.GetRecorderDriveLetter(pathBuffer, pathBuffer.MaxCapacity);
         string driveLetter = pathBuffer.ToString();
         return driveLetter;
      }

      /// <summary>
      /// Initiates the Windows Burn CD Wizard to copy any files in
      /// the staging folder onto disc.
      /// </summary>
      /// <param name="handle">Handle to the main form of the calling
      /// application.</param>
      public void Burn(IntPtr handle)
      {
         cdBurnImpl.Burn(handle);
      }

      /// <summary>
      /// Converts a <c>PIDL</c> (pointer to an ID list) to a file path on
      /// the system.
      /// </summary>
      /// <param name="pidl">PIDL to convert</param>
      /// <returns>String path for the PIDL.</returns>
      private string PathFromPidl(
         IntPtr pidl
         )
      {
         StringBuilder path = new StringBuilder(260, 260);
         int result = SHGetPathFromIDList(pidl, path);
         if (result == 0)
         {
            return string.Empty;
         }
         else
         {
            return path.ToString();   
         }
      }

      /// <summary>
      /// Gets an instance of the Shell's memory allocator.
      /// </summary>
      private IMalloc Allocator
      {
         get
         {
            if (!disposed)
            {
               if (alloc == null)
               {
                  SHGetMalloc(out alloc);               
               }
            }
            else
            {
               System.Diagnostics.Debug.Assert(false, "Object has been
                disposed.");
            }
            return alloc;
         }
      }

   }
}