RetainHelper.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Text;
  10. using DiskAccessLibrary;
  11. using Utilities;
  12. namespace DiskAccessLibrary.LogicalDiskManager
  13. {
  14. public class RetainHelper
  15. {
  16. public static bool IsVolumeRetained(DynamicVolume volume, out bool isBootVolume)
  17. {
  18. if (volume is SimpleVolume)
  19. {
  20. return IsVolumeRetained((SimpleVolume)volume, out isBootVolume);
  21. }
  22. else if (volume is MirroredVolume)
  23. {
  24. foreach (DynamicVolume component in ((MirroredVolume)volume).Components)
  25. {
  26. if (component.IsOperational && component is SimpleVolume)
  27. {
  28. if (IsVolumeRetained((SimpleVolume)component, out isBootVolume))
  29. {
  30. return true;
  31. }
  32. }
  33. }
  34. }
  35. isBootVolume = false;
  36. return false;
  37. }
  38. public static bool IsVolumeRetained(SimpleVolume volume, out bool isBootVolume)
  39. {
  40. isBootVolume = false;
  41. DynamicDisk disk = DynamicDisk.ReadFromDisk(volume.Disk);
  42. long bootPartitionStartLBA;
  43. List<ExtentRecord> retained = GetRetainedExtentsOnDisk(disk, out bootPartitionStartLBA);
  44. foreach(ExtentRecord record in retained)
  45. {
  46. if (record.ExtentId == volume.DiskExtent.ExtentID)
  47. {
  48. if ((long)(disk.PrivateHeader.PublicRegionStartLBA + record.DiskOffsetLBA) == bootPartitionStartLBA)
  49. {
  50. isBootVolume = true;
  51. }
  52. return true;
  53. }
  54. }
  55. return false;
  56. }
  57. private static List<ExtentRecord> GetRetainedExtentsOnDisk(DynamicDisk disk, out long bootPartitionStartLBA)
  58. {
  59. VolumeManagerDatabase database = VolumeManagerDatabase.ReadFromDisk(disk);
  60. DiskRecord diskRecord = database.FindDiskByDiskGuid(disk.DiskGuid);
  61. bootPartitionStartLBA = -1;
  62. List<ExtentRecord> result = new List<ExtentRecord>();
  63. foreach (VolumeRecord volume in database.VolumeRecords)
  64. {
  65. if ((volume.VolumeFlags & VolumeFlags.RetainPartition) > 0)
  66. {
  67. List<ComponentRecord> components = database.FindComponentsByVolumeID(volume.VolumeId);
  68. foreach (ComponentRecord componentRecord in components)
  69. {
  70. if (componentRecord.ExtentLayout == ExtentLayoutName.Concatenated)
  71. {
  72. if (componentRecord.NumberOfExtents == 1)
  73. {
  74. List<ExtentRecord> extents = database.FindExtentsByComponentID(componentRecord.ComponentId);
  75. if (extents.Count == 1)
  76. {
  77. ExtentRecord extent = extents[0];
  78. if (extent.DiskId == diskRecord.DiskId)
  79. {
  80. result.Add(extent);
  81. if ((volume.VolumeFlags & VolumeFlags.BootVolume) > 0)
  82. {
  83. bootPartitionStartLBA = (long)(disk.PrivateHeader.PublicRegionStartLBA + extent.DiskOffsetLBA);
  84. }
  85. }
  86. }
  87. }
  88. }
  89. }
  90. }
  91. }
  92. return result;
  93. }
  94. }
  95. }