123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
- *
- * You can redistribute this program and/or modify it under the terms of
- * the GNU Lesser Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- */
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Text;
- using Utilities;
- namespace DiskAccessLibrary.VMDK
- {
- public class VirtualMachineDiskDescriptor
- {
- public int Version;
- public uint ContentID;
- public uint ParentContentID;
- public VirtualMachineDiskType DiskType;
- public List<VirtualMachineDiskExtentEntry> ExtentEntries;
- public string Adapter;
- public long Cylinders;
- public int TracksPerCylinder; // heads
- public int SectorsPerTrack;
- public VirtualMachineDiskDescriptor(List<string> lines)
- {
- ParseDescriptor(lines);
- }
- private void ParseDescriptor(List<string> lines)
- {
- ExtentEntries = new List<VirtualMachineDiskExtentEntry>();
- foreach (string line in lines)
- {
- if (line.StartsWith("version", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- Version = Conversion.ToInt32(value);
- }
- else if (line.StartsWith("CID", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- ContentID = UInt32.Parse(value, System.Globalization.NumberStyles.HexNumber);
- }
- else if (line.StartsWith("ParentCID", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- ParentContentID = UInt32.Parse(value, System.Globalization.NumberStyles.HexNumber);
- }
- else if (line.StartsWith("createType", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- value = QuotedStringUtils.Unquote(value);
- DiskType = GetFromString(value);
- }
- else if (line.StartsWith("RW", StringComparison.InvariantCultureIgnoreCase) ||
- line.StartsWith("RDONLY", StringComparison.InvariantCultureIgnoreCase) ||
- line.StartsWith("NOACCESS", StringComparison.InvariantCultureIgnoreCase))
- {
- VirtualMachineDiskExtentEntry entry = VirtualMachineDiskExtentEntry.ParseEntry(line);
- ExtentEntries.Add(entry);
- }
- else if (line.StartsWith("ddb.adapterType", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- value = QuotedStringUtils.Unquote(value);
- Adapter = value;
- }
- else if (line.StartsWith("ddb.geometry.sectors", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- value = QuotedStringUtils.Unquote(value);
- SectorsPerTrack = Conversion.ToInt32(value);
- }
- else if (line.StartsWith("ddb.geometry.heads", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- value = QuotedStringUtils.Unquote(value);
- TracksPerCylinder = Conversion.ToInt32(value);
- }
- else if (line.StartsWith("ddb.geometry.cylinders", StringComparison.InvariantCultureIgnoreCase))
- {
- string value = line.Substring(line.IndexOf('=') + 1).Trim();
- value = QuotedStringUtils.Unquote(value);
- Cylinders = Conversion.ToInt64(value);
- }
- }
- }
- public void UpdateExtentEntries(List<string> lines)
- {
- int startIndex = -1;
- // Remove previous extent entries
- for (int index = 0; index < lines.Count; index++)
- {
- string line = lines[index];
- if (line.StartsWith("RW", StringComparison.InvariantCultureIgnoreCase) ||
- line.StartsWith("RDONLY", StringComparison.InvariantCultureIgnoreCase) ||
- line.StartsWith("NOACCESS", StringComparison.InvariantCultureIgnoreCase))
- {
- if (startIndex == -1)
- {
- startIndex = index;
- }
- lines.RemoveAt(index);
- index--;
- }
- }
- if (startIndex >= 0)
- {
- foreach (VirtualMachineDiskExtentEntry entry in ExtentEntries)
- {
- lines.Insert(startIndex, entry.GetEntryLine());
- startIndex++;
- }
- }
- }
- public static VirtualMachineDiskDescriptor ReadFromFile(string descriptorPath)
- {
- List<string> lines = ReadASCIITextLines(descriptorPath);
- if (lines == null)
- {
- return null;
- }
- return new VirtualMachineDiskDescriptor(lines);
- }
- private static VirtualMachineDiskType GetFromString(string createType)
- {
- switch (createType.ToLower())
- {
- case "custom":
- return VirtualMachineDiskType.Custom;
- case "monolithicsparse":
- return VirtualMachineDiskType.MonolithicSparse;
- case "monolithicflat":
- return VirtualMachineDiskType.MonolithicFlat;
- case "2Gbmaxextentsparse":
- return VirtualMachineDiskType.TwoGbMaxExtentSparse;
- case "2Gbmaxextentflat":
- return VirtualMachineDiskType.TwoGbMaxExtentFlat;
- case "fulldevice":
- return VirtualMachineDiskType.FullDevice;
- case "partitioneddevice":
- return VirtualMachineDiskType.PartitionedDevice;
- case "vmfspreallocated":
- return VirtualMachineDiskType.VmfsPreallocated;
- case "vmfseagerzeroedthick":
- return VirtualMachineDiskType.VmfsEagerZeroedThick;
- case "vmfsthin":
- return VirtualMachineDiskType.VmfsThin;
- case "vmfssparse":
- return VirtualMachineDiskType.VmfsSparse;
- case "vmfsrdm":
- return VirtualMachineDiskType.VmfsRDM;
- case "vmfsRDMP":
- return VirtualMachineDiskType.VmfsRDMP;
- case "vmfsraw":
- return VirtualMachineDiskType.VmfsRaw;
- case "streamoptimized":
- return VirtualMachineDiskType.StreamOptimized;
- default:
- return VirtualMachineDiskType.Custom;
- }
- }
- public static List<string> ReadASCIITextLines(string path)
- {
- string text = ReadASCIIText(path);
- if (text == null)
- {
- return null;
- }
- return GetLines(text);
- }
- public static List<string> GetLines(string text)
- {
- List<string> result = new List<string>();
- StringReader reader = new StringReader(text);
- string line;
- while ((line = reader.ReadLine()) != null)
- {
- result.Add(line);
- }
- return result;
- }
- public static string ReadASCIIText(string path)
- {
- StringBuilder builder = new StringBuilder();
- FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
- int bufferSize = 0x1000; // default FileStream buffer size
- byte[] buffer = new byte[bufferSize];
- int bytesRead = stream.Read(buffer, 0, buffer.Length);
- string temp = ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead);
- while (bytesRead > 0)
- {
- foreach (char c in temp)
- {
- if (char.IsControl(c) && c != '\r' && c != '\n')
- {
- stream.Close();
- return null;
- }
- }
- builder.Append(temp);
- if (bytesRead == bufferSize)
- {
- bytesRead = stream.Read(buffer, 0, buffer.Length);
- temp = ASCIIEncoding.ASCII.GetString(buffer, 0, bytesRead);
- }
- else
- {
- break;
- }
- }
- stream.Close();
- return builder.ToString();
- }
- }
- }
|