private static void AttachAutomatics(List <FileWithOptions> todoList, List <FileWithOptions> failedList) { foreach (var fwo in todoList) { try { Thread.Sleep(1000); //a bit of breather var access = Medo.IO.VirtualDiskAccessMask.All; var options = Medo.IO.VirtualDiskAttachOptions.PermanentLifetime; if (fwo.ReadOnly) { options |= Medo.IO.VirtualDiskAttachOptions.ReadOnly; } if (fwo.NoDriveLetter) { options |= Medo.IO.VirtualDiskAttachOptions.NoDriveLetter; } var fileName = fwo.FileName; using (var disk = new Medo.IO.VirtualDisk(fileName)) { disk.Open(access); disk.Attach(options); } } catch (Exception ex) { if (failedList != null) { failedList.Add(fwo); } Trace.TraceError("E: Cannot attach file \"" + fwo.FileName + "\". " + ex.Message); Medo.Diagnostics.ErrorReport.SaveToTemp(ex, fwo.FileName); } } }
private static void ReceivedAttach(TinyPacket packet) { try { var path = packet["Path"]; var isReadOnly = packet["MountReadOnly"].Equals("True", StringComparison.OrdinalIgnoreCase); var shouldInitialize = packet["InitializeDisk"].Equals("True", StringComparison.OrdinalIgnoreCase); string diskPath = null; using (var disk = new Medo.IO.VirtualDisk(path)) { var access = Medo.IO.VirtualDiskAccessMask.All; var options = Medo.IO.VirtualDiskAttachOptions.PermanentLifetime; if (isReadOnly) { if (shouldInitialize == false) { access = Medo.IO.VirtualDiskAccessMask.AttachReadOnly; } options |= Medo.IO.VirtualDiskAttachOptions.ReadOnly; } disk.Open(access); disk.Attach(options); if (shouldInitialize) { diskPath = disk.GetAttachedPath(); } } if (shouldInitialize) { DiskIO.InitializeDisk(diskPath); } } catch (Exception ex) { throw new InvalidOperationException(string.Format("Virtual disk file \"{0}\" cannot be attached.", (new FileInfo(packet["Path"])).Name), ex); } }
private void UnmountAndDetach(string vhdFileName) { FileInfo fi = new FileInfo(vhdFileName); if (!fi.Exists) { return; } Log.WriteLine("UnmountAndDetach({0})", vhdFileName); fi.IsReadOnly = false; //unlock file to enable load try { if (_virtualDisk != null) // && _virtualDisk.FileName.CompareTo(vhdFileName) != 0) { _virtualDisk.Close(); _virtualDisk = null; } if (_virtualDisk == null || !_virtualDisk.IsOpen) { _virtualDisk = new Medo.IO.VirtualDisk(vhdFileName); _virtualDisk.Open(); } string diskPath = _virtualDisk.GetAttachedPath(); if (!string.IsNullOrWhiteSpace(diskPath)) //if device is attached { DiskCryptor.DriveInfo drive = FindDriveInfo(diskPath); if (drive != null) { try { UnmountDiscryptorDrive(drive); } catch (Exception err) { Log.WriteLine("UnmountDiscryptorDrive({0}) - Error: {1}", diskPath, err); } } _virtualDisk.Detach(); } } catch (Exception err) { Log.WriteLine("UnmountAndDetach({0}): {1}", vhdFileName, err.ToString()); throw; } finally { if (_virtualDisk != null) { _virtualDisk.Close(); _virtualDisk = null; } fi.IsReadOnly = true; //lock file to improve security } }
private static void ReceivedDetach(TinyPacket packet) { try { var path = packet["Path"]; using (var disk = new Medo.IO.VirtualDisk(path)) { disk.Open(Medo.IO.VirtualDiskAccessMask.Detach); disk.Detach(); } } catch (Exception ex) { throw new InvalidOperationException(string.Format("Virtual disk file \"{0}\" cannot be detached.", (new FileInfo(packet["Path"])).Name), ex); } }
private void m_btnAttachVHDandMount_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(GetPasswordFunc())) { PopUp.Error("Password is empty", "Password"); return; } FileInfo fi = new FileInfo(m_cmbVHD_FileName.Text); if (!fi.Exists) { if (PopUp.Question("File not found: " + fi.FullName + "\nRemove from Recent Files List?", "Mount VHD - ERROR", MessageBoxImage.Asterisk, TextAlignment.Center, PopUp.PopUpButtonsType.NoYes) == PopUp.PopUpResult.Yes) { _recentFiles.RemoveFromList(m_cmbVHD_FileName.Text, m_mnuFileAttachVHD.DropDown, m_cmbVHD_FileName); } return; } ExecuteClickAction(() => { _recentFiles.AddRecent(m_cmbVHD_FileName.Text, m_mnuFileAttachVHD.DropDown, m_cmbVHD_FileName); fi.IsReadOnly = false; //unlock file to enable load _cachedDriveInfo = new List <DiskCryptor.DriveInfo>(_diskCryptor.DriveList); if (_virtualDisk != null) { _virtualDisk.Close(); } _virtualDisk = new Medo.IO.VirtualDisk(fi.FullName); _virtualDisk.Open(); try { _virtualDisk.Detach(); } catch (Exception err) { Debug.WriteLine("Cannot detach: " + err.Message); } _selectedDriveLetterForMount = _selectedDriveLetter; _diskCryptor.OnDisksAdded += OnDiskAddedMountDiskCryptorDisk; //mount DiskCryptor disk Medo.IO.VirtualDiskAttachOptions options = Medo.IO.VirtualDiskAttachOptions.NoDriveLetter; if (m_chkPermanent.Checked) { options |= Medo.IO.VirtualDiskAttachOptions.PermanentLifetime; } _virtualDisk.Attach(options); fi.IsReadOnly = true; //lock file to improve security }, sender); }
private static void AttachAutomatics(List<FileWithOptions> todoList, List<FileWithOptions> failedList) { foreach (var fwo in todoList) { try { Thread.Sleep(1000); //a bit of breather var access = Medo.IO.VirtualDiskAccessMask.All; var options = Medo.IO.VirtualDiskAttachOptions.PermanentLifetime; if (fwo.ReadOnly) { options |= Medo.IO.VirtualDiskAttachOptions.ReadOnly; } if (fwo.NoDriveLetter) { options |= Medo.IO.VirtualDiskAttachOptions.NoDriveLetter; } var fileName = fwo.FileName; using (var disk = new Medo.IO.VirtualDisk(fileName)) { disk.Open(access); disk.Attach(options); } } catch (Exception ex) { if (failedList != null) { failedList.Add(fwo); } Trace.TraceError("E: Cannot attach file \"" + fwo.FileName + "\". " + ex.Message); Medo.Diagnostics.ErrorReport.SaveToTemp(ex, fwo.FileName); } } }
private void UpdateData(string vhdFileName) { if (vhdFileName == null) { list.Items.Clear(); list.Groups.Clear(); mnuRefresh.Enabled = false; mnuAttach.Enabled = false; mnuDetach.Enabled = false; mnuAutomount.Enabled = false; mnuDrive.Enabled = false; mnuAutomount_DropDownOpening(null, null); mnuDrive_DropDownOpening(null, null); return; } try { this.Cursor = Cursors.WaitCursor; mnuRefresh.Enabled = true; using (var document = new Medo.IO.VirtualDisk(vhdFileName)) { var items = new List<ListViewItem>(); var fileInfo = new FileInfo(document.FileName); items.Add(new ListViewItem(new string[] { "File path", fileInfo.Directory.FullName }) { Group = GroupFileSystem }); items.Add(new ListViewItem(new string[] { "File name", fileInfo.Name }) { Group = GroupFileSystem }); try { var fi = new FileInfo(document.FileName); items.Add(new ListViewItem(new string[] { "File size", string.Format(CultureInfo.CurrentCulture, "{0} ({1:#,##0} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(fi.Length, "B", "0"), fi.Length) }) { Group = GroupFileSystem }); } catch { } try { var di = new DriveInfo(new FileInfo(document.FileName).Directory.Root.FullName); items.Add(new ListViewItem(new string[] { "Free space on " + di.Name, string.Format(CultureInfo.CurrentCulture, "{0} ({1:#,##0} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(di.AvailableFreeSpace, "B", "0"), di.AvailableFreeSpace) }) { Group = GroupFileSystem }); } catch { } document.Open(Medo.IO.VirtualDiskAccessMask.GetInfo | Medo.IO.VirtualDiskAccessMask.Detach); //Workaround: The VirtualDiskAccessMask parameter must include the VIRTUAL_DISK_ACCESS_DETACH (0x00040000) flag. string attachedDevice = null; string[] attachedPaths = null; try { attachedDevice = document.GetAttachedPath(); attachedPaths = PathFromDevice.GetPath(attachedDevice); } catch { } if (attachedDevice != null) { items.Add(new ListViewItem(new string[] { "Attached device", attachedDevice }) { Group = GroupFileSystem }); } if (attachedPaths != null) { for (int i = 0; i < attachedPaths.Length; i++) { items.Add(new ListViewItem(new string[] { ((i == 0) ? "Attached path" : ""), attachedPaths[i] }) { Group = GroupFileSystem }); } } try { long virtualSize; long physicalSize; int blockSize; int sectorSize; document.GetSize(out virtualSize, out physicalSize, out blockSize, out sectorSize); items.Add(new ListViewItem(new string[] { "Virtual size", string.Format(CultureInfo.CurrentCulture, "{0} ({1:#,##0} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(virtualSize, "B", "0"), virtualSize) }) { Group = GroupDetails }); if (fileInfo.Length != physicalSize) { items.Add(new ListViewItem(new string[] { "Physical size", string.Format(CultureInfo.CurrentCulture, "{0} ({1:#,##0} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(physicalSize, "B", "0"), physicalSize) }) { Group = GroupDetails }); } if (blockSize != 0) { items.Add(new ListViewItem(new string[] { "Block size", string.Format(CultureInfo.CurrentCulture, "{0} ({1:#,##0} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(((long)blockSize), "B", "0"), blockSize) }) { Group = GroupDetails }); } items.Add(new ListViewItem(new string[] { "Sector size", string.Format(CultureInfo.CurrentCulture, "{0} ({1} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(((long)sectorSize), "B", "0"), sectorSize) }) { Group = GroupDetails }); } catch { } try { items.Add(new ListViewItem(new string[] { "Identifier", document.GetIdentifier().ToString() }) { Group = GroupDetails }); } catch { } try { int deviceId; Guid vendorId; document.GetVirtualStorageType(out deviceId, out vendorId); string deviceText = string.Format(CultureInfo.InvariantCulture, "Unknown ({0})", deviceId); switch (deviceId) { case 1: deviceText = "ISO"; break; case 2: deviceText = "VHD"; break; case 3: deviceText = "VHDX"; break; } string vendorText = string.Format(CultureInfo.InvariantCulture, "Unknown ({0})", vendorId); if (vendorId.Equals(new Guid("EC984AEC-A0F9-47e9-901F-71415A66345B"))) { vendorText = "Microsoft"; } items.Add(new ListViewItem(new string[] { "Device ID", deviceText }) { Group = GroupDetails }); items.Add(new ListViewItem(new string[] { "Vendor ID", vendorText }) { Group = GroupDetails }); } catch { } try { items.Add(new ListViewItem(new string[] { "Provider subtype", string.Format(CultureInfo.CurrentCulture, "{0} (0x{0:x8})", document.GetProviderSubtype()) }) { Group = GroupDetails }); } catch { } if (document.DiskType == Medo.IO.VirtualDiskType.Vhd) { try { var footerCopyBytes = new byte[512]; var headerBytes = new byte[1024]; var footerBytes = new byte[512]; using (var vhdFile = new FileStream(vhdFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { vhdFile.Read(footerCopyBytes, 0, 512); vhdFile.Read(headerBytes, 0, 1024); vhdFile.Position = vhdFile.Length - 512; vhdFile.Read(footerBytes, 0, 512); } var footer = new HardDiskFooter(footerBytes); if (footer.Cookie != "conectix") { items.Add(new ListViewItem(new string[] { "Cookie", footer.Cookie }) { Group = GroupInternals }); } items.Add(new ListViewItem(new string[] { "Creation time stamp", string.Format(CultureInfo.CurrentCulture, "{0}", footer.TimeStamp.ToLocalTime()) }) { Group = GroupInternals }); var creatorApplicationText = string.Format(CultureInfo.InvariantCulture, "Unknown (0x{0:x4})", (int)footer.CreatorApplication); switch (footer.CreatorApplication) { case VhdCreatorApplication.JosipMedvedVhdAttach: creatorApplicationText = "Josip Medved's VHD Attach"; break; case VhdCreatorApplication.MicrosoftSysinternalsDisk2Vhd: creatorApplicationText = "Microsoft Sysinternals Disk2vhd"; break; case VhdCreatorApplication.MicrosoftVirtualPC: creatorApplicationText = "Microsoft Virtual PC"; break; case VhdCreatorApplication.MicrosoftVirtualServer: creatorApplicationText = "Microsoft Virtual Server"; break; case VhdCreatorApplication.MicrosoftWindows: creatorApplicationText = "Microsoft Windows"; break; case VhdCreatorApplication.OracleVirtualBox: creatorApplicationText = "Oracle VirtualBox"; break; } items.Add(new ListViewItem(new string[] { "Creator application", string.Format(CultureInfo.InvariantCulture, "{0} {1}.{2}", creatorApplicationText, footer.CreatorVersion.Major, footer.CreatorVersion.Minor) }) { Group = GroupInternals }); var creatorHostOsText = string.Format(CultureInfo.InvariantCulture, "Unknown (0x{0:x4})", (int)footer.CreatorHostOs); switch (footer.CreatorHostOs) { case VhdCreatorHostOs.Windows: creatorHostOsText = "Windows"; break; case VhdCreatorHostOs.Macintosh: creatorHostOsText = "Macintosh"; break; } items.Add(new ListViewItem(new string[] { "Creator host OS", creatorHostOsText }) { Group = GroupInternals }); items.Add(new ListViewItem(new string[] { "Disk geometry", string.Format(CultureInfo.CurrentCulture, "{0}, {1}, {2}", CylinderSuffix.GetText(footer.DiskGeometryCylinders), HeadSuffix.GetText(footer.DiskGeometryHeads), SectorSuffix.GetText(footer.DiskGeometrySectors)) }) { Group = GroupInternals }); var diskTypeText = string.Format(CultureInfo.CurrentCulture, "Unknown ({0}: 0x{0:x4})", (int)footer.DiskType); switch ((int)footer.DiskType) { case 0: diskTypeText = "None"; break; case 1: diskTypeText = "Reserved (deprecated: 0x0001)"; break; case 2: diskTypeText = "Fixed hard disk"; break; case 3: diskTypeText = "Dynamic hard disk"; break; case 4: diskTypeText = "Differencing hard disk"; break; case 5: diskTypeText = "Reserved (deprecated: 0x0005)"; break; case 6: diskTypeText = "Reserved (deprecated: 0x0006)"; break; } items.Add(new ListViewItem(new string[] { "Disk type", diskTypeText }) { Group = GroupInternals }); if ((footer.DiskType == VhdDiskType.DynamicHardDisk) || (footer.DiskType == VhdDiskType.DifferencingHardDisk)) { var header = new DynamicDiskHeader(headerBytes); if (header.Cookie != "cxsparse") { items.Add(new ListViewItem(new string[] { "Cookie", header.Cookie }) { Group = GroupInternalsDynamic }); } if (header.DataOffset != ulong.MaxValue) { items.Add(new ListViewItem(new string[] { "Data offset", header.DataOffset.ToString("#,##0") }) { Group = GroupInternalsDynamic }); } items.Add(new ListViewItem(new string[] { "Max table entries", header.MaxTableEntries.ToString("#,##0") }) { Group = GroupInternalsDynamic }); items.Add(new ListViewItem(new string[] { "Block size", string.Format(CultureInfo.CurrentCulture, "{0} ({1:#,##0} bytes)", BinaryPrefixExtensions.ToBinaryPrefixString(header.BlockSize, "B", "0"), header.BlockSize) }) { Group = GroupInternalsDynamic }); } } catch { } } mnuAttach.Enabled = string.IsNullOrEmpty(attachedDevice); mnuDetach.Enabled = !mnuAttach.Enabled; mnuAutomount.Enabled = true; mnuDrive.Enabled = true; mnuAutomount_DropDownOpening(null, null); mnuDrive_DropDownOpening(null, null); list.BeginUpdate(); list.Items.Clear(); list.Groups.Clear(); list.Groups.Add(GroupFileSystem); list.Groups.Add(GroupDetails); list.Groups.Add(GroupInternals); list.Groups.Add(GroupInternalsDynamic); foreach (var iItem in items) { list.Items.Add(iItem); } list.EndUpdate(); } } finally { this.Cursor = Cursors.Default; } this.Text = GetFileTitle(vhdFileName) + " - " + Medo.Reflection.EntryAssembly.Title; }
private void tmrUpdateMenu_Tick(object sender, EventArgs e) { #if DEBUG var sw = Stopwatch.StartNew(); #endif if (this.VhdFileName == null) { mnuRefresh.Enabled = false; mnuAttach.Enabled = false; mnuDetach.Enabled = false; mnuAutomount.Enabled = false; mnuDrive.Enabled = false; return; } try { mnuRefresh.Enabled = true; if (!File.Exists(this.VhdFileName)) { return; } using (var document = new Medo.IO.VirtualDisk(this.VhdFileName)) { document.Open(Medo.IO.VirtualDiskAccessMask.GetInfo | Medo.IO.VirtualDiskAccessMask.Detach); //Workaround: The VirtualDiskAccessMask parameter must include the VIRTUAL_DISK_ACCESS_DETACH (0x00040000) flag. string attachedDevice = null; try { attachedDevice = document.GetAttachedPath(); } catch { } mnuAttach.Enabled = string.IsNullOrEmpty(attachedDevice); mnuDetach.Enabled = !mnuAttach.Enabled; mnuAutomount.Enabled = true; mnuDrive.Enabled = true; if (!mnuAutomount.DropDownButtonPressed) { mnuAutomount_DropDownOpening(null, null); } if (!mnuDrive.DropDownButtonPressed) { mnuDrive_DropDownOpening(null, null); } } } catch { } #if DEBUG sw.Stop(); Debug.WriteLine("VhdAttach: Menu update in " + sw.ElapsedMilliseconds.ToString(CultureInfo.InvariantCulture) + " milliseconds."); #endif }
private void mnuDrive_DropDownOpening(object sender, EventArgs e) { string newMenuTitle = null; string attachedDevice = null; try { using (var document = new Medo.IO.VirtualDisk(this.VhdFileName)) { document.Open(Medo.IO.VirtualDiskAccessMask.GetInfo); attachedDevice = document.GetAttachedPath(); } } catch { } mnuDrive.Tag = null; mnuDrive.Text = "Drive"; mnuDrive.DropDownItems.Clear(); if (attachedDevice != null) { var volumes = new List<Volume>(Volume.GetVolumesOnPhysicalDrive(attachedDevice)); var availableVolumes = new List<Volume>(); foreach (var volume in volumes) { if (volume.DriveLetter2 != null) { availableVolumes.Add(volume); } } if (availableVolumes.Count > 0) { foreach (var volume in availableVolumes) { mnuDrive.DropDownItems.Add(new ToolStripMenuItem("Open " + volume.DriveLetter3, null, mnuDriveOpen_Click) { Tag = volume }); if (newMenuTitle == null) { mnuDrive.Tag = volume; newMenuTitle = volume.DriveLetter3; } } } if (volumes.Count > 0) { if (mnuDrive.DropDownItems.Count > 0) { mnuDrive.DropDownItems.Add(new ToolStripSeparator()); } foreach (var volume in volumes) { if (volume.DriveLetter2 != null) { mnuDrive.DropDownItems.Add(new ToolStripMenuItem("Change drive letter " + volume.DriveLetter2, null, mnuDriveLetter_Click) { Tag = volume }); } else { if (mnuDrive.Tag == null) { mnuDrive.Tag = volume; } mnuDrive.DropDownItems.Add(new ToolStripMenuItem("Add drive letter", null, mnuDriveLetter_Click) { Tag = volume }); } } } } if (newMenuTitle == null) { newMenuTitle = "Drive"; } mnuDrive.Text = newMenuTitle; mnuDrive.Enabled = (mnuDrive.DropDownItems.Count > 0); }
/// <summary> /// Change the drive letter of an attached VHD. /// <summary> public int ChangeDriveLetter(string[] args) { // Init and parameter checks if (args.Length != 2) { string err = "Changing drive letter failed. Wrong number of arguments.\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return 1; } string fileName = args[0]; if (!File.Exists(fileName)) { string err = "Changing drive letter failed. File not found: " + fileName + "\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return 1; } string driveLetterRaw = args[1]; if (driveLetterRaw.Length > 3 || (driveLetterRaw.Length == 3 && driveLetterRaw.Substring(1,2) != ":\\") || (driveLetterRaw.Length == 2 && driveLetterRaw.Substring(1,1) != ":")) { string err = "Changing drive letter failed. Drive Letter parameter seems to be invalid.\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return 1; } string allowedLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; string driveLetter1 = args[1].Substring(0, 1); string driveLetter2 = driveLetter1 + ":"; if (allowedLetters.IndexOf(driveLetter1) == -1) { string err = "Changing drive letter failed. Drive Letter parameter seems to be invalid.\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return 1; } // Test-Code, please ignore // PipeClient.Attach(fileName, false, false); // PipeClient.Detach(fileName); // The actual drive letter operation begins here string attachedDevice = null; try { using (var document = new Medo.IO.VirtualDisk(fileName)) { document.Open(Medo.IO.VirtualDiskAccessMask.GetInfo); attachedDevice = document.GetAttachedPath(); } } catch { string err = "Changing Drive letter failed. Could not open device.\n"; err += "Possible reasons include:\n"; err += "The specified file might not be attached or maybe isn't an VHD file."; showError(err); return 1; } if (attachedDevice != null) { var volumes = new List<Volume>(Volume.GetVolumesOnPhysicalDrive(attachedDevice)); var availableVolumes = new List<Volume>(); if (volumes != null && volumes.Count > 0) { string oldLetter2 = volumes[0].DriveLetter2; PipeResponse res = PipeClient.ChangeDriveLetter(volumes[0].VolumeName, driveLetter2); if (res.IsError == true) { PipeClient.ChangeDriveLetter(volumes[0].VolumeName, oldLetter2); string err = "Changing drive letter failed. Drive letter possibly in use."; showError(err); return 1; } } } return 0; }
private static void DetachDrive(string path) { var device = DeviceFromPath.GetDevice(path); #region VDS COM FileInfo vhdFile = null; VdsServiceLoader loaderClass = new VdsServiceLoader(); IVdsServiceLoader loader = (IVdsServiceLoader)loaderClass; IVdsService service; loader.LoadService(null, out service); service.WaitForServiceReady(); IEnumVdsObject providerEnum; service.QueryProviders(VDS_QUERY_PROVIDER_FLAG.VDS_QUERY_VIRTUALDISK_PROVIDERS, out providerEnum); while (true) { uint fetchedProvider; object unknownProvider; providerEnum.Next(1, out unknownProvider, out fetchedProvider); if (fetchedProvider == 0) break; IVdsVdProvider provider = (IVdsVdProvider)unknownProvider; Console.WriteLine("Got VD Provider"); IEnumVdsObject diskEnum; provider.QueryVDisks(out diskEnum); while (true) { uint fetchedDisk; object unknownDisk; diskEnum.Next(1, out unknownDisk, out fetchedDisk); if (fetchedDisk == 0) break; IVdsVDisk vDisk = (IVdsVDisk)unknownDisk; VDS_VDISK_PROPERTIES vdiskProperties; vDisk.GetProperties(out vdiskProperties); try { IVdsDisk disk; provider.GetDiskFromVDisk(vDisk, out disk); VDS_DISK_PROP diskProperties; disk.GetProperties(out diskProperties); if (diskProperties.pwszName.Equals(device, StringComparison.OrdinalIgnoreCase)) { vhdFile = new FileInfo(vdiskProperties.pPath); break; } else { Trace.TraceError(diskProperties.pwszName + " = " + vdiskProperties.pPath); } Console.WriteLine("-> Disk Name=" + diskProperties.pwszName); Console.WriteLine("-> Disk Friendly=" + diskProperties.pwszFriendlyName); } catch (COMException) { } } if (vhdFile != null) { break; } } #endregion if (vhdFile != null) { using (var disk = new Medo.IO.VirtualDisk(vhdFile.FullName)) { disk.Open(Medo.IO.VirtualDiskAccessMask.Detach); disk.Detach(); } } else { throw new FormatException(string.Format("Drive \"{0}\" is not a virtual hard disk.", path)); } }
/// <summary> /// Change the drive letter of an attached VHD. /// <summary> public int ChangeDriveLetter(string[] args) { // Init and parameter checks if (args.Length != 2) { string err = "Changing drive letter failed. Wrong number of arguments.\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return(1); } string fileName = args[0]; if (!File.Exists(fileName)) { string err = "Changing drive letter failed. File not found: " + fileName + "\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return(1); } string driveLetterRaw = args[1]; if (driveLetterRaw.Length > 3 || (driveLetterRaw.Length == 3 && driveLetterRaw.Substring(1, 2) != ":\\") || (driveLetterRaw.Length == 2 && driveLetterRaw.Substring(1, 1) != ":")) { string err = "Changing drive letter failed. Drive Letter parameter seems to be invalid.\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return(1); } string allowedLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; string driveLetter1 = args[1].Substring(0, 1); string driveLetter2 = driveLetter1 + ":"; if (allowedLetters.IndexOf(driveLetter1) == -1) { string err = "Changing drive letter failed. Drive Letter parameter seems to be invalid.\n"; err += "Usage: VhdAttach -ChangeLetter VHDFilename Driveletter:"; showError(err); return(1); } // Test-Code, please ignore // PipeClient.Attach(fileName, false, false); // PipeClient.Detach(fileName); // The actual drive letter operation begins here string attachedDevice = null; try { using (var document = new Medo.IO.VirtualDisk(fileName)) { document.Open(Medo.IO.VirtualDiskAccessMask.GetInfo); attachedDevice = document.GetAttachedPath(); } } catch { string err = "Changing Drive letter failed. Could not open device.\n"; err += "Possible reasons include:\n"; err += "The specified file might not be attached or maybe isn't an VHD file."; showError(err); return(1); } if (attachedDevice != null) { var volumes = new List <Volume>(Volume.GetVolumesOnPhysicalDrive(attachedDevice)); var availableVolumes = new List <Volume>(); if (volumes != null && volumes.Count > 0) { string oldLetter2 = volumes[0].DriveLetter2; PipeResponse res = PipeClient.ChangeDriveLetter(volumes[0].VolumeName, driveLetter2); if (res.IsError == true) { PipeClient.ChangeDriveLetter(volumes[0].VolumeName, oldLetter2); string err = "Changing drive letter failed. Drive letter possibly in use."; showError(err); return(1); } } } return(0); }
private static void DetachDrive(string path) { var device = DeviceFromPath.GetDevice(path); #region VDS COM FileInfo vhdFile = null; VdsServiceLoader loaderClass = new VdsServiceLoader(); IVdsServiceLoader loader = (IVdsServiceLoader)loaderClass; IVdsService service; loader.LoadService(null, out service); service.WaitForServiceReady(); IEnumVdsObject providerEnum; service.QueryProviders(VDS_QUERY_PROVIDER_FLAG.VDS_QUERY_VIRTUALDISK_PROVIDERS, out providerEnum); while (true) { uint fetchedProvider; object unknownProvider; providerEnum.Next(1, out unknownProvider, out fetchedProvider); if (fetchedProvider == 0) { break; } IVdsVdProvider provider = (IVdsVdProvider)unknownProvider; Console.WriteLine("Got VD Provider"); IEnumVdsObject diskEnum; provider.QueryVDisks(out diskEnum); while (true) { uint fetchedDisk; object unknownDisk; diskEnum.Next(1, out unknownDisk, out fetchedDisk); if (fetchedDisk == 0) { break; } IVdsVDisk vDisk = (IVdsVDisk)unknownDisk; VDS_VDISK_PROPERTIES vdiskProperties; vDisk.GetProperties(out vdiskProperties); try { IVdsDisk disk; provider.GetDiskFromVDisk(vDisk, out disk); VDS_DISK_PROP diskProperties; disk.GetProperties(out diskProperties); if (diskProperties.pwszName.Equals(device, StringComparison.OrdinalIgnoreCase)) { vhdFile = new FileInfo(vdiskProperties.pPath); break; } else { Trace.TraceError(diskProperties.pwszName + " = " + vdiskProperties.pPath); } Console.WriteLine("-> Disk Name=" + diskProperties.pwszName); Console.WriteLine("-> Disk Friendly=" + diskProperties.pwszFriendlyName); } catch (COMException) { } } if (vhdFile != null) { break; } } #endregion if (vhdFile != null) { using (var disk = new Medo.IO.VirtualDisk(vhdFile.FullName)) { disk.Open(Medo.IO.VirtualDiskAccessMask.Detach); disk.Detach(); } } else { throw new FormatException(string.Format("Drive \"{0}\" is not a virtual hard disk.", path)); } }