/// <summary> /// Disposes of this instance. /// </summary> /// <param name="disposing"><c>true</c> if disposing, else <c>false</c>.</param> protected override void Dispose(bool disposing) { try { _metaDataStream.Dispose(); _metaDataStream = null; _file = null; } finally { base.Dispose(disposing); } }
internal WimFileSystem(WimFile file, int index) { _file = file; ShortResourceHeader metaDataFileInfo = _file.LocateImage(index); if (metaDataFileInfo == null) { throw new ArgumentException("No such image: " + index, "index"); } using(Stream metaDataStream = _file.OpenResourceStream(metaDataFileInfo)) { ReadMetaData(metaDataStream); } }
internal WimFileSystem(WimFile file, int index) { _file = file; ShortResourceHeader metaDataFileInfo = _file.LocateImage(index); if (metaDataFileInfo == null) { throw new ArgumentException("No such image: " + index, "index"); } _metaDataStream = _file.OpenResourceStream(metaDataFileInfo); ReadSecurityDescriptors(); _dirCache = new ObjectCache<long, List<DirectoryEntry>>(); }
internal WimFileSystem(WimFile file, int index) { _file = file; ShortResourceHeader metaDataFileInfo = _file.LocateImage(index); if (metaDataFileInfo == null) { throw new ArgumentException("No such image: " + index, "index"); } _metaDataStream = _file.OpenResourceStream(metaDataFileInfo); ReadSecurityDescriptors(); _dirCache = new ObjectCache <long, List <DirectoryEntry> >(); }
internal WimFileSystem(WimFile file, int index) { _file = file; ShortResourceHeader metaDataFileInfo = _file.LocateImage(index); if (metaDataFileInfo == null) { throw new ArgumentException("No such image: " + index, "index"); } using (Stream metaDataStream = _file.OpenResourceStream(metaDataFileInfo)) { ReadMetaData(metaDataStream); } }
internal List<XenRef<VDI>> ImportFile(Session xenSession, string vmname, string pathToOvf, string filename, string compression, string version, string passcode, string sruuid, string description, string vdiuuid) { List<XenRef<VDI>> vdiRef = new List<XenRef<VDI>>(); // Get the disk transport method from the configuration in XenOvfTransport.Properties.Settings.TransferType. TransferType useTransport = (TransferType)Enum.Parse(typeof(TransferType), Properties.Settings.Default.TransferType, true); TransferMethod useTransferMethod = TransferMethod.Image; string sourcefile = filename; string encryptfilename = null; string uncompressedfilename = null; string destinationPath = Properties.Settings.Default.xenISOMount; string StartPath = Directory.GetCurrentDirectory(); Directory.SetCurrentDirectory(pathToOvf); Stream dataStream = null; long dataCapacity = 0; #region SET UP TRANSPORT if (filename != null) { if (IsKnownURIType(filename)) { Uri fileUri = new Uri(filename); filename = DownloadFileAsync(fileUri, 0); sourcefile = filename; } if (File.Exists(filename)) { string ext = Path.GetExtension(filename); try { encryptfilename = "enc_" + filename; uncompressedfilename = "unc_" + filename; // OK.. lets see is the file encrypted? #region ENCRYPTION if (passcode != null) { var statusMessage = string.Format(Messages.START_FILE_DECRYPTION, filename); OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOn, "Security", statusMessage)); log.Debug(statusMessage); OVF.DecryptToTempFile(EncryptionClass, filename, version, passcode, encryptfilename); sourcefile = encryptfilename; statusMessage += Messages.COMPLETE; OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOff, "Security", statusMessage)); } #endregion #region COMPRESSION // Identity == no compression, it is meant when a URL is used to identify the compression during transport. if (compression != null && !compression.ToLower().Equals("none") && !compression.ToLower().Equals("identity")) { // gz is the only understood 'compressed' format, strip it.. // the OVF is marked with "compressed=gzip" therefor it will get decompress // correctly and use with its disk extension (vmdk/vhd/vdi)... if (ext.ToLower().EndsWith(".gz")) { string newfilename = Path.GetFileNameWithoutExtension(uncompressedfilename); uncompressedfilename = newfilename; ext = Path.GetExtension(uncompressedfilename); } var statusMessage = string.Format(Messages.START_FILE_EXPANSION, filename); OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOn, "Compression", statusMessage)); var ovfCompressor = new OvfCompressor(); ovfCompressor.UncompressFile(sourcefile, uncompressedfilename, compression); if (File.Exists(encryptfilename)) { File.Delete(encryptfilename); } sourcefile = uncompressedfilename; statusMessage += Messages.COMPLETE; OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.MarqueeOff, "Compression", statusMessage)); } #endregion #region DISK SELECTION bool knownDisk = false; foreach (string diskext in VirtualDisk.SupportedDiskFormats) { if (ext.ToLower().Contains(diskext.ToLower())) { knownDisk = true; break; } } if (knownDisk) { log.DebugFormat("Found file {0} using {1} Stream", filename, ext); vhdDisk = VirtualDisk.OpenDisk(sourcefile, FileAccess.Read); dataStream = vhdDisk.Content; dataCapacity = vhdDisk.Capacity; } else if (ext.ToLower().Contains("wim")) { log.WarnFormat("EXPERIMENTAL CODE: Found file {0} using WIM file structure", filename); wimDisk = new DiscUtils.Wim.WimFile(new FileStream(sourcefile, FileMode.Open, FileAccess.Read)); //wimFS = wimDisk.GetImage(wimDisk.BootImage); dataStream = null; string manifest = wimDisk.Manifest; Wim_Manifest wimManifest = (Wim_Manifest)Tools.Deserialize(manifest, typeof(Wim_Manifest)); ulong imagesize = wimManifest.Image[wimDisk.BootImage].TotalBytes; // <----<<< Image data size wimFileCount = wimManifest.Image[wimDisk.BootImage].FileCount; dataCapacity = (long)(imagesize + AdditionalSpace); useTransferMethod = TransferMethod.Files; } else if (ext.ToLower().Contains("xva")) { log.WarnFormat("EXPERIMENTAL CODE: Found file {0} using XVA Stream (DISK {1} is being imported).", filename, xvadisk); DiscUtils.Xva.VirtualMachine vm = new DiscUtils.Xva.VirtualMachine(new FileStream(sourcefile, FileMode.Open, FileAccess.Read)); int i = 0; foreach (DiscUtils.Xva.Disk d in vm.Disks) { if (i == xvadisk) { vhdDisk = d; break; } } dataStream = vhdDisk.Content; dataCapacity = vhdDisk.Capacity; } else if (ext.ToLower().EndsWith("iso")) { if (string.IsNullOrEmpty(sruuid)) { useTransport = TransferType.Skip; } else { //DiscUtils.Iso9660.CDReader cdr = new DiscUtils.Iso9660.CDReader(File.OpenRead(filename), true); dataStream = File.OpenRead(filename); dataCapacity = dataStream.Length + (512 * KB); // Xen does 512KB rounding this is to ensure it doesn't round down below size. } } #endregion } catch (Exception ex) { log.Error(Messages.ISCSI_ERROR_CANNOT_OPEN_DISK); throw new Exception(Messages.ISCSI_ERROR_CANNOT_OPEN_DISK, ex); } } else { throw new FileNotFoundException(string.Format(Messages.FILE_MISSING, filename)); } } else { log.Error(Messages.ERROR_FILE_NAME_NULL); throw new InvalidDataException(Messages.ERROR_FILE_NAME_NULL); } #endregion try { #region SEE IF TARGET SR HAS ENOUGH SPACE if (useTransport == TransferType.UploadRawVDI || useTransport == TransferType.iSCSI) { long freespace; string contenttype = string.Empty; if(vdiuuid != null) { XenRef<VDI> vdiLookup = VDI.get_by_uuid(xenSession, vdiuuid); freespace = VDI.get_virtual_size(xenSession, vdiLookup); } else { XenRef<SR> srRef = SR.get_by_uuid(xenSession, sruuid); long size = SR.get_physical_size(xenSession, srRef); long usage = SR.get_physical_utilisation(xenSession, srRef); contenttype = SR.get_content_type(xenSession, srRef); freespace = size - usage; } if (freespace <= dataCapacity) { string message = string.Format(Messages.NOT_ENOUGH_SPACE_IN_SR, sruuid, Convert.ToString(vhdDisk.Capacity), filename); log.Error(message); throw new IOException(message); } } #endregion #region UPLOAD FILE switch (useTransport) { case TransferType.UploadRawVDI: { vdiRef.Add(UploadRawVDI(xenSession, sruuid, vmname, dataStream, dataCapacity, description)); break; } case TransferType.iSCSI: { if (useTransferMethod == TransferMethod.Image) { vdiRef.Add(UploadiSCSI(xenSession, sruuid, vmname, dataStream, dataCapacity, description, vdiuuid)); } else { for (int i = 0; i < wimDisk.ImageCount; i++) { Wim_Manifest wimManifest = (Wim_Manifest)Tools.Deserialize(wimDisk.Manifest, typeof(Wim_Manifest)); wimFileCount = wimManifest.Image[i].FileCount; int wimArch = wimManifest.Image[i].Windows.Architecture; vdiRef.Add(UploadiSCSIbyWimFile(xenSession, sruuid, vmname, wimDisk, i, dataCapacity, wimFileCount, wimArch, "")); } } break; } case TransferType.Skip: { log.Info("ImportFile: Upload Skipped"); break; } default: { log.Error(Messages.UNSUPPORTED_TRANSPORT); throw new InvalidDataException(Messages.UNSUPPORTED_TRANSPORT); } } #endregion } catch (Exception ex) { if (ex is OperationCanceledException) throw; throw new Exception(Messages.FILE_TRANSPORT_FAILED, ex); } finally { if (vhdDisk != null) { vhdDisk.Dispose(); vhdDisk = null; } if (wimDisk != null) { wimDisk = null; } if (File.Exists(encryptfilename)) { File.Delete(encryptfilename); } if (File.Exists(uncompressedfilename)) { File.Delete(uncompressedfilename); } } Directory.SetCurrentDirectory(StartPath); log.DebugFormat("OVF.Import.ImportFile leave: created {0} VDIs", vdiRef.Count); return vdiRef; }
private XenRef<VDI> UploadiSCSIbyWimFile(Session xenSession, string sruuid, string label, WimFile wimDisk, int imageindex, long capacity, ulong wimFileCount, int arch, string description) { log.Debug("OVF.Import.UploadiSCSIbyWimFile Enter"); log.DebugFormat("OVF.Import.UploadiSCSIbyWimFile SRUUID: {0}", sruuid); log.DebugFormat("OVF.Import.UploadiSCSIbyWimFile Label: {0}", label); log.DebugFormat("OVF.Import.UploadiSCSIbyWimFile ImageIndex: {0}", imageindex); log.DebugFormat("OVF.Import.UploadiSCSIbyWimFile Capacity: {0}", capacity); string vdilabel = string.Format("{0}{1}", label, imageindex); XenRef<VDI> vdiRef = CreateVDI(xenSession, sruuid, vdilabel, capacity, description); byte[] mbr = null; byte[] boot = null; //byte[] bcd = null; //byte[] bootmgr = null; string vhdfile = FindReferenceVHD(Properties.Settings.Default.ReferenceVHDName); if (File.Exists(vhdfile)) { mbr = ExtractMBRFromVHD(vhdfile); boot = ExtractBootFromVHD(vhdfile); //bcd = ExtractBCDFromVHD(vhdfile, arch); //bootmgr = ExtractBootmgrFromVHD(vhdfile, arch); } else { log.WarnFormat("Refernce VHD not found [{0}]", Properties.Settings.Default.ReferenceVHDName); } #region UPLOAD iSCSI STREAM OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.FileStart, "Import", string.Format(Messages.FILES_TRANSPORT_SETUP, _currentfilename))); m_iscsi = new iSCSI { UpdateHandler = iscsi_UpdateHandler, Cancel = Cancel //in case it has already been cancelled }; m_iscsi.ConfigureTvmNetwork(m_networkUuid, m_isTvmIpStatic, m_tvmIpAddress, m_tvmSubnetMask, m_tvmGateway); try { wimFileIndex = 0; string vdiuuid = VDI.get_uuid(xenSession, vdiRef); Stream iSCSIStream = m_iscsi.Connect(xenSession, vdiuuid, false); WimFileSystem w = wimDisk.GetImage(imageindex); if (mbr != null) { m_iscsi.ScsiDisk.SetMasterBootRecord(mbr); } else { log.WarnFormat("System will not be bootable, cannot find [{0}] to extract master boot record.", vhdfile); OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.FileStart, "Import", Messages.WARNING_TARGET_NOT_BOOTABLE)); } m_iscsi.ScsiDisk.Signature = new Random().Next(); BiosPartitionTable table = BiosPartitionTable.Initialize(m_iscsi.ScsiDisk, WellKnownPartitionType.WindowsNtfs); VolumeManager volmgr = new VolumeManager(m_iscsi.ScsiDisk); NtfsFileSystem ntfs = null; if (wimDisk.BootImage == imageindex && boot != null) { table.SetActivePartition(0); ntfs = NtfsFileSystem.Format(volmgr.GetLogicalVolumes()[0], "New Volume", boot); } else { ntfs = NtfsFileSystem.Format(volmgr.GetLogicalVolumes()[0], "New Volume"); } //AddBCD(ntfs, bcd); //AddBootMgr(ntfs, bootmgr); // If it's not there it'll be created if it is it will not.. not below filecopy will overwrite if one it exists. FileCopy(m_iscsi, w.Root.GetFiles(), w, ntfs); FileCopy(m_iscsi, w.Root.GetDirectories(), w, ntfs); FixBCD(ntfs, volmgr); ntfs.Dispose(); } catch (Exception ex) { if (ex is OperationCanceledException) throw; log.ErrorFormat("{0} {1}", Messages.ERROR_ISCSI_UPLOAD_FAILED, ex.Message); vdiRef = null; throw new Exception(Messages.ERROR_ISCSI_UPLOAD_FAILED, ex); } finally { OnUpdate(new XenOvfTranportEventArgs(XenOvfTranportEventType.FileStart, "Import", string.Format(Messages.FILES_TRANSPORT_CLEANUP, _currentfilename))); m_iscsi.Disconnect(xenSession); } #endregion log.Debug("OVF.Import.UploadiSCSIbyWimFile Leave"); return vdiRef; }
private bool GetDiskCapacityImage(out string error) { error = string.Empty; string filename = m_textBoxFile.Text; FileInfo info = new FileInfo(filename); ImageLength = info.Length > 0 ? (ulong)info.Length : 0; if (IsWIM) { try { using (FileStream wimstream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { WimFile wimDisk = new WimFile(wimstream); string manifest = wimDisk.Manifest; Wim_Manifest wimManifest = (Wim_Manifest)Tools.Deserialize(manifest, typeof(Wim_Manifest)); DiskCapacity = wimManifest.Image[wimDisk.BootImage].TotalBytes; //image data size return true; } } catch (Exception) { error = Messages.IMAGE_SELECTION_PAGE_ERROR_CORRUPT_FILE; return false; } } try { using (VirtualDisk vd = VirtualDisk.OpenDisk(filename, FileAccess.Read)) { DiskCapacity = (ulong)vd.Capacity; return true; } } catch (IOException ioe) { error = ioe.Message.Contains("Invalid VMDK descriptor file") ? Messages.IMAGE_SELECTION_PAGE_ERROR_INVALID_VMDK_DESCRIPTOR : Messages.IMAGE_SELECTION_PAGE_ERROR_INVALID_FILE_TYPE; return false; } catch (Exception) { error = Messages.IMAGE_SELECTION_PAGE_ERROR_CORRUPT_FILE; return false; } }