Ejemplo n.º 1
0
        static int Main(string[] args)
        {
            int Result = 0;
            bool HasExclusive = false;

            // First and second arguments
            string Drive = null, ISOImage = null;

            MsftDiscMaster2Class DiscMaster = new MsftDiscMaster2Class();
            MsftDiscRecorder2Class DiscRecorder = null;
            DDiscFormat2DataEvents_UpdateEventHandler EventHandler = new DDiscFormat2DataEvents_UpdateEventHandler(DiscFormatData_Update);

            // Check arguments.
            if (args.Length < 2)
            {
                Log("Usage: ISOBurn <DrivePath> <ISOImage>");
                Log("\tISOBurn e: d:\\summerpics.iso");
                Result = ERR_INVALID_ARGS;
                goto Exit;
            }

            ISOImage = args[1];

            // If the file doesn't exist, waste no more time
            if (!System.IO.File.Exists(args[1]))
            {
                Console.WriteLine("File not found: {0}", ISOImage);
                Result = ERR_FILE_NOT_FOUND;
                goto Exit;
            }

            // Find the corresponding disc recorder for the drive
            for (int i = 0; i < DiscMaster.Count; ++i)
            {
                MsftDiscRecorder2Class DR = new MsftDiscRecorder2Class();
                DR.InitializeDiscRecorder(DiscMaster[i]);
                foreach (string s in DR.VolumePathNames)
                {
                    // Indicate the drive letter the system is using and set the disc recorder
                    if (s.StartsWith(args[0], StringComparison.CurrentCultureIgnoreCase))
                    {
                        Log("Using drive {0} for burning from ID {1}", s, DiscMaster[i]);
                        Drive = s;
                        DiscRecorder = DR;
                        break;
                    }
                }
            }

            // If we didn't set DiscRecorder, then no drive was found
            if (DiscRecorder == null)
            {
                Log("The drive {0} to burn to was not found.", Drive);
                Result = ERR_DRIVE_NOT_FOUND;
                goto Exit;
            }

            // Ensure the drive supports writing.
            List<IMAPI_FEATURE_PAGE_TYPE> Features = new List<IMAPI_FEATURE_PAGE_TYPE>();
            foreach (IMAPI_FEATURE_PAGE_TYPE IFPT in DiscRecorder.SupportedFeaturePages)
            {
                Features.Add(IFPT);
            }

            // Is there a better way to do this?  Doesn't look like a bitfield based on the enums (saddened)
            if (!Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_BD_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CD_RW_MEDIA_WRITE_SUPPORT) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CDRW_CAV_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_R_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_RW_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R_DUAL_LAYER) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_RW) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_HD_DVD_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CD_MASTERING))
            {
                Log("The drive {0} does not appear to support writing.", Drive);
                Result = ERR_DRIVE_NOT_SUPPORTED;
                goto Exit;
            }

            // Check to see if another application is already using the media and if so bail
            MsftDiscFormat2DataClass DiscFormatData = null;
            if (DiscRecorder.ExclusiveAccessOwner != null && DiscRecorder.ExclusiveAccessOwner.Length != 0)
            {
                Log("The drive {0} is in use by the application: {1}", Drive, DiscRecorder.ExclusiveAccessOwner);
                Result = ERR_DRIVE_IN_USE;
                goto Exit;
            }
            // Try to get exclusive access.  This is important.  In Vista 5728, Media Player causes this to return E_FAIL
            // even if it is just playing music in the background.
            try
            {
                DiscRecorder.AcquireExclusiveAccess(false, "ISOBurn Commandline Tool");
            }
            catch (System.Exception e)
            {
                Log("Failed to acquire exclusive access to the burner: Message: {0}\nStack Trace: {1}", e.Message, e.StackTrace);
                Result = ERR_DRIVE_FAILED_ACQUIRE;
                goto Exit;
            }

            // Disable media change notifications so we don't have anyone else being notified that I'm doing stuff on the drive
            DiscRecorder.DisableMcn();

            // Indicate we have exclusive access.
            HasExclusive = true;

            // Get the disk format which will hopefully let us know if we can write to the disk safely.
            Result = GetDiskFormatData(DiscRecorder, Drive, out DiscFormatData);
            if (Result != 0)
            {
                goto Exit;
            }

            // I would like to get the amount of free space on the media and compare that against the file size, but I'm not sure
            // if the file size of the ISO represents the raw sectors that would be written or whether it might be more tightly
            // packed.  Also there might be additional sectors written on the disk to identify the image, etc that isn't
            // represented in the ISO.  These are details I don't know to make this a little bit more robust.

            // Get the image to write
            IMAPI2.IStream Stream = null;
            int Res = SHCreateStreamOnFile(ISOImage, 0x20, out Stream);
            if (Res < 0)
            {
                Log("Opening the source ISO image {0} failed with error: {1}", ISOImage, Res);
                Result = Res;
                goto Exit;
            }

            // Set the client name
            DiscFormatData.ClientName = "ISOBurn Commandline Tool";
            // Add the event handler *WHICH CURRENTLY DOES GENERATE EVENTS*
            DiscFormatData.Update += EventHandler;

            Log("Disk write speed is {0} sectors/second", DiscFormatData.CurrentWriteSpeed);

            // Write the stream
            try
            {
                DiscFormatData.Write(Stream);
                Log("Burn complete of {0} to {1}!", ISOImage, Drive);
            }
            catch (System.Exception e)
            {
                Log("Burn Failed: {0}\n{1}", e.Message, e.StackTrace.ToString());
                goto Exit;
            }

            Exit:
            // Cleanup
            if (DiscRecorder != null && HasExclusive)
            {
                DiscRecorder.EnableMcn();
                DiscRecorder.ReleaseExclusiveAccess();
                DiscRecorder.EjectMedia();
            }

            return Result;
        }
Ejemplo n.º 2
0
        static int Main(string[] args)
        {
            int  Result       = 0;
            bool HasExclusive = false;

            // First and second arguments
            string Drive = null, ISOImage = null;

            MsftDiscMaster2Class   DiscMaster       = new MsftDiscMaster2Class();
            MsftDiscRecorder2Class DiscRecorder     = null;
            DDiscFormat2DataEvents_UpdateEventHandler EventHandler = new DDiscFormat2DataEvents_UpdateEventHandler(DiscFormatData_Update);

#if DEBUG
            Drive    = "D:\\";
            ISOImage = @"C:\Users\manue\Desktop\Windows x64.iso";
#endif

            // Check arguments if no parameters already set
            if (string.IsNullOrEmpty(Drive) == true && string.IsNullOrEmpty(ISOImage) == true && args.Length < 2)
            {
                Log("Usage: ISOBurn <DrivePath> <ISOImage>");
                Log("\tISOBurn e: d:\\summerpics.iso");
                Result = ERR_INVALID_ARGS;
                goto Exit;
            }

            if (string.IsNullOrEmpty(Drive) == true)
            {
                Drive = args[0];
            }
            if (string.IsNullOrEmpty(ISOImage) == true)
            {
                ISOImage = args[1];
            }

            // If the file doesn't exist, waste no more time
            if (!System.IO.File.Exists(ISOImage))
            {
                Console.WriteLine("File not found: {0}", ISOImage);
                Result = ERR_FILE_NOT_FOUND;
                goto Exit;
            }

            //// Check registry for windows 10 cd burning enabled
            //// https://www.technipages.com/enable-disable-cd-burning-windows
            //// https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-create-a-key-in-the-registry
            //Microsoft.Win32.RegistryKey oExplorerKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\Explorer");
            //string sName = "NoCDBurning";
            //if (oExplorerKey != null)
            //{
            //	oExplorerKey.SetValue(sName, 0);
            //	oExplorerKey.Close();
            //}

            // Find the corresponding disc recorder for the drive
            for (int i = 0; i < DiscMaster.Count; ++i)
            {
                MsftDiscRecorder2Class DR = new MsftDiscRecorder2Class();
                DR.InitializeDiscRecorder(DiscMaster[i]);
                foreach (string s in DR.VolumePathNames)
                {
                    // Indicate the drive letter the system is using and set the disc recorder
                    if (s.StartsWith(Drive, StringComparison.CurrentCultureIgnoreCase))
                    {
                        Log("Using drive {0} for burning from ID {1}", s, DiscMaster[i]);
                        Drive        = s;
                        DiscRecorder = DR;
                        break;
                    }
                }
            }

            // If we didn't set DiscRecorder, then no drive was found
            if (DiscRecorder == null)
            {
                Log("The drive {0} to burn to was not found.", Drive);
                Result = ERR_DRIVE_NOT_FOUND;
                goto Exit;
            }

            // Ensure the drive supports writing.
            List <IMAPI_FEATURE_PAGE_TYPE> Features = new List <IMAPI_FEATURE_PAGE_TYPE>();
            foreach (IMAPI_FEATURE_PAGE_TYPE IFPT in DiscRecorder.SupportedFeaturePages)
            {
                Features.Add(IFPT);
            }

            // Is there a better way to do this?  Doesn't look like a bitfield based on the enums (saddened)
            if (!Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_BD_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CD_RW_MEDIA_WRITE_SUPPORT) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CDRW_CAV_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_R_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DOUBLE_DENSITY_CD_RW_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_DASH_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_R_DUAL_LAYER) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_PLUS_RW) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_HD_DVD_WRITE) &&
                !Features.Contains(IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CD_MASTERING))
            {
                Log("The drive {0} does not appear to support writing.", Drive);
                Result = ERR_DRIVE_NOT_SUPPORTED;
                goto Exit;
            }

            // Check to see if another application is already using the media and if so bail
            MsftDiscFormat2DataClass DiscFormatData = null;
            if (DiscRecorder.ExclusiveAccessOwner != null && DiscRecorder.ExclusiveAccessOwner.Length != 0)
            {
                Log("The drive {0} is in use by the application: {1}", Drive, DiscRecorder.ExclusiveAccessOwner);
                Result = ERR_DRIVE_IN_USE;
                goto Exit;
            }
            // Try to get exclusive access.  This is important.  In Vista 5728, Media Player causes this to return E_FAIL
            // even if it is just playing music in the background.
            try
            {
                DiscRecorder.AcquireExclusiveAccess(false, "ISOBurn Commandline Tool");
            }
            catch (System.Exception e)
            {
                Log("Failed to acquire exclusive access to the burner: Message: {0}\nStack Trace: {1}", e.Message, e.StackTrace);
                Result = ERR_DRIVE_FAILED_ACQUIRE;
                goto Exit;
            }

            // Disable media change notifications so we don't have anyone else being notified that I'm doing stuff on the drive
            DiscRecorder.DisableMcn();

            // Indicate we have exclusive access.
            HasExclusive = true;

            // Get the disk format which will hopefully let us know if we can write to the disk safely.
            Result = GetDiskFormatData(DiscRecorder, Drive, out DiscFormatData);
            if (Result != 0)
            {
                goto Exit;
            }

            // I would like to get the amount of free space on the media and compare that against the file size, but I'm not sure
            // if the file size of the ISO represents the raw sectors that would be written or whether it might be more tightly
            // packed.  Also there might be additional sectors written on the disk to identify the image, etc that isn't
            // represented in the ISO.  These are details I don't know to make this a little bit more robust.

            // Get the image to write
            IMAPI2.IStream Stream                   = null;
            int            Res                      = SHCreateStreamOnFile(ISOImage, 0x20, out Stream);
            if (Res < 0)
            {
                Log("Opening the source ISO image {0} failed with error: {1}", ISOImage, Res);
                Result = Res;
                goto Exit;
            }

            // Set the client name
            DiscFormatData.ClientName = "ISOBurn Commandline Tool";
            // Add the event handler *WHICH CURRENTLY DOES GENERATE EVENTS*
            DiscFormatData.Update += EventHandler;

            Log("Disk write speed is {0} sectors/second", DiscFormatData.CurrentWriteSpeed);

            // Write the stream
            try
            {
                DiscFormatData.Write(Stream);
                Log("Burn complete of {0} to {1}!", ISOImage, Drive);
            }
            catch (System.Exception e)
            {
                Log("Burn Failed: {0}\n{1}", e.Message, e.StackTrace.ToString());
                goto Exit;
            }

Exit:
            // Cleanup
            if (DiscRecorder != null && HasExclusive)
            {
                DiscRecorder.EnableMcn();
                DiscRecorder.ReleaseExclusiveAccess();
                DiscRecorder.EjectMedia();
            }

            return(Result);
        }