public void Create(ulong driveSize) { Header = new VhdFooter(); Header.InitDefaults(); Header.OrigSize = driveSize.EndianSwap(); Header.CurSize = driveSize.EndianSwap(); DynamicDiskHeader = new VhdDynamicDiskHeader(); DynamicDiskHeader.InitDefaults(); var batEntryCount = (uint)(driveSize/DynamicDiskHeader.BlockSize.EndianSwap()); BlockAllocationTable = new uint[(int) batEntryCount]; for (uint i = 0; i < batEntryCount; i++) BlockAllocationTable[i] = 0xFFFFFFFF; DynamicDiskHeader.MaxTableEntries = batEntryCount.EndianSwap(); Header.CalculateChecksum(); DynamicDiskHeader.CalculateChecksum(); }
public void Create(ulong driveSize) { Header = new VhdFooter(); Header.InitDefaults(); Header.OrigSize = driveSize.EndianSwap(); Header.CurSize = driveSize.EndianSwap(); DynamicDiskHeader = new VhdDynamicDiskHeader(); DynamicDiskHeader.InitDefaults(); var batEntryCount = (uint)(driveSize / DynamicDiskHeader.BlockSize.EndianSwap()); BlockAllocationTable = new uint[(int)batEntryCount]; for (uint i = 0; i < batEntryCount; i++) { BlockAllocationTable[i] = 0xFFFFFFFF; } DynamicDiskHeader.MaxTableEntries = batEntryCount.EndianSwap(); Header.CalculateChecksum(); DynamicDiskHeader.CalculateChecksum(); }
public bool ConvertToVhd(string destFile) { if (IsEncrypted) return false; // xvd -> vhd conversion just needs the FS data extracted with a vhd footer put at the end // seems to work for older OS XVDs, newer XVCs use a 4k sector size though and windows VHD driver doesn't like it, not sure what new OS XVDs use // todo: look into converting 4k sectors to 512 using(var vhdFile = new IO(destFile, FileMode.Create)) { _io.Stream.Position = (long)DataOffset; if (IsXvcFile) // if it's an XVC file then find the correct XVC data offset { bool foundFs = false; foreach (var hdr in RegionHeaders) { if (hdr.Description == "FS-MD" || hdr.Id == 0x40000002) { foundFs = true; _io.Stream.Position = (long)hdr.Offset; break; } } if (!foundFs) { // no FS-MD in the file, older XVCs seem to use the last region for it _io.Stream.Position = (long)RegionHeaders[RegionHeaders.Count - 1].Offset; } } vhdFile.Stream.Position = 0; var driveSize = (long)Header.DriveSize; while (_io.Stream.Length > _io.Stream.Position) { long toRead = 0x4000; if (_io.Stream.Position + toRead > _io.Stream.Length) toRead = _io.Stream.Length - _io.Stream.Position; byte[] data = _io.Reader.ReadBytes((int) toRead); vhdFile.Writer.Write(data); } vhdFile.Stream.Position = driveSize; var footer = new VhdFooter(); footer.InitDefaults(); footer.OrigSize = ((ulong) driveSize).EndianSwap(); footer.CurSize = footer.OrigSize; footer.UniqueId = Header.VDUID; // don't need to calculate these footer.DiskGeometryHeads = 0; footer.DiskGeometrySectors = 0; footer.DiskGeometryCylinders = 0; footer.TimeStamp = 0; footer.CalculateChecksum(); vhdFile.Writer.WriteStruct(footer); } if (DisableNativeFunctions) return true; // make sure NTFS compression is disabled on the vhd int lpBytesReturned = 0; // ReSharper disable InconsistentNaming const int FSCTL_SET_COMPRESSION = 0x9C040; short COMPRESSION_FORMAT_NONE = 0; // ReSharper restore InconsistentNaming using (FileStream f = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { #pragma warning disable 618 Natives.DeviceIoControl(f.Handle, FSCTL_SET_COMPRESSION, #pragma warning restore 618 ref COMPRESSION_FORMAT_NONE, 2 /*sizeof(short)*/, IntPtr.Zero, 0, ref lpBytesReturned, IntPtr.Zero); } return true; }
public bool ConvertToVhd(string destFile) { if (IsEncrypted) { return(false); } // xvd -> vhd conversion just needs the FS data extracted with a vhd footer put at the end // seems to work for older OS XVDs, newer XVCs use a 4k sector size though and windows VHD driver doesn't like it, not sure what new OS XVDs use // todo: look into converting 4k sectors to 512 using (var vhdFile = new IO(destFile, FileMode.Create)) { _io.Stream.Position = (long)DataOffset; if (IsXvcFile) // if it's an XVC file then find the correct XVC data offset { bool foundFs = false; foreach (var hdr in RegionHeaders) { if (hdr.Description == "FS-MD" || hdr.Id == 0x40000002) { foundFs = true; _io.Stream.Position = (long)hdr.Offset; break; } } if (!foundFs) { // no FS-MD in the file, older XVCs seem to use the last region for it _io.Stream.Position = (long)RegionHeaders[RegionHeaders.Count - 1].Offset; } } vhdFile.Stream.Position = 0; var driveSize = (long)Header.DriveSize; while (_io.Stream.Length > _io.Stream.Position) { long toRead = 0x4000; if (_io.Stream.Position + toRead > _io.Stream.Length) { toRead = _io.Stream.Length - _io.Stream.Position; } byte[] data = _io.Reader.ReadBytes((int)toRead); vhdFile.Writer.Write(data); } vhdFile.Stream.Position = driveSize; var footer = new VhdFooter(); footer.InitDefaults(); footer.OrigSize = ((ulong)driveSize).EndianSwap(); footer.CurSize = footer.OrigSize; footer.UniqueId = Header.VDUID; // don't need to calculate these footer.DiskGeometryHeads = 0; footer.DiskGeometrySectors = 0; footer.DiskGeometryCylinders = 0; footer.TimeStamp = 0; footer.CalculateChecksum(); vhdFile.Writer.WriteStruct(footer); } if (DisableNativeFunctions) { return(true); } // make sure NTFS compression is disabled on the vhd int lpBytesReturned = 0; // ReSharper disable InconsistentNaming const int FSCTL_SET_COMPRESSION = 0x9C040; short COMPRESSION_FORMAT_NONE = 0; // ReSharper restore InconsistentNaming using (FileStream f = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { #pragma warning disable 618 Natives.DeviceIoControl(f.Handle, FSCTL_SET_COMPRESSION, #pragma warning restore 618 ref COMPRESSION_FORMAT_NONE, 2 /*sizeof(short)*/, IntPtr.Zero, 0, ref lpBytesReturned, IntPtr.Zero); } return(true); }