|
18 | 18 | Private ReadOnly _FilePath As String |
19 | 19 | Private _Modified As Boolean |
20 | 20 | Private ReadOnly _Modifications As Hashtable |
| 21 | + Private ReadOnly _OriginalData As Hashtable |
21 | 22 |
|
22 | 23 | Sub New(FilePath As String) |
23 | 24 | _Modifications = New Hashtable() |
| 25 | + _OriginalData = New Hashtable() |
24 | 26 | _Modified = False |
25 | 27 | _FilePath = FilePath |
26 | 28 | _FileBytes = System.IO.File.ReadAllBytes(FilePath) |
|
104 | 106 | End Function |
105 | 107 |
|
106 | 108 | Public Sub SetBytes(Value As UShort, Offset As UInteger) |
| 109 | + If Not _OriginalData.ContainsKey(Offset) Then |
| 110 | + _OriginalData.Item(Offset) = GetBytesShort(Offset) |
| 111 | + End If |
| 112 | + |
107 | 113 | Array.Copy(BitConverter.GetBytes(Value), 0, _FileBytes, Offset, 2) |
| 114 | + |
108 | 115 | _Modified = True |
109 | 116 | _Modifications.Item(Offset) = Value |
110 | 117 | End Sub |
111 | 118 |
|
112 | 119 | Public Sub SetBytes(Value As UInteger, Offset As UInteger) |
| 120 | + If Not _OriginalData.ContainsKey(Offset) Then |
| 121 | + _OriginalData.Item(Offset) = GetBytesInteger(Offset) |
| 122 | + End If |
| 123 | + |
113 | 124 | Array.Copy(BitConverter.GetBytes(Value), 0, _FileBytes, Offset, 4) |
| 125 | + |
114 | 126 | _Modified = True |
115 | 127 | _Modifications.Item(Offset) = Value |
116 | 128 | End Sub |
117 | 129 |
|
118 | 130 | Public Sub SetBytes(Value As Byte, Offset As UInteger) |
| 131 | + If Not _OriginalData.ContainsKey(Offset) Then |
| 132 | + _OriginalData.Item(Offset) = GetByte(Offset) |
| 133 | + End If |
| 134 | + |
119 | 135 | _FileBytes(Offset) = Value |
| 136 | + |
120 | 137 | _Modified = True |
121 | 138 | _Modifications.Item(Offset) = Value |
122 | 139 | End Sub |
123 | 140 |
|
124 | 141 | Public Sub SetBytes(Value() As Byte, Offset As UInteger) |
| 142 | + If Not _OriginalData.ContainsKey(Offset) Then |
| 143 | + _OriginalData.Item(Offset) = GetBytes(Offset, Value.Length) |
| 144 | + End If |
| 145 | + |
125 | 146 | Array.Copy(Value, 0, _FileBytes, Offset, Value.Length) |
| 147 | + |
126 | 148 | _Modified = True |
127 | 149 | _Modifications.Item(Offset) = Value |
128 | 150 | End Sub |
129 | 151 |
|
130 | 152 | Public Sub SetBytes(Value() As Byte, Offset As UInteger, Size As UInteger, Padding As Byte) |
131 | | - Disk.ResizeArray(Value, Size, Padding) |
| 153 | + If Not _OriginalData.ContainsKey(Offset) Then |
| 154 | + _OriginalData.Item(Offset) = GetBytes(Offset, Size) |
| 155 | + End If |
| 156 | + |
| 157 | + If Value.Length <> Size Then |
| 158 | + Disk.ResizeArray(Value, Size, Padding) |
| 159 | + End If |
132 | 160 | Array.Copy(Value, 0, _FileBytes, Offset, Size) |
| 161 | + |
133 | 162 | _Modified = True |
134 | 163 | _Modifications.Item(Offset) = Value |
135 | 164 | End Sub |
|
192 | 221 | Return Count |
193 | 222 | End Function |
194 | 223 |
|
| 224 | + Public Function GetFillCharacter() As Byte |
| 225 | + Dim Offset = Math.Min(_FileBytes.Length, _BootSector.ImageSize) |
| 226 | + Dim FillChar = _FileBytes(Offset - 1) |
| 227 | + If FillChar = &H0 Then |
| 228 | + For Counter As Integer = Offset - 1 To Offset - _BootSector.BytesPerSector Step -1 |
| 229 | + If _FileBytes(Counter) <> &H0 Then |
| 230 | + FillChar = &HFF |
| 231 | + Exit For |
| 232 | + End If |
| 233 | + Next |
| 234 | + ElseIf FillChar <> &HF6 Then |
| 235 | + FillChar = &HFF |
| 236 | + End If |
| 237 | + |
| 238 | + Return FillChar |
| 239 | + End Function |
| 240 | + |
195 | 241 | Public Function HasUnusedClustersWithData() As Boolean |
196 | 242 | If _FreeSpaceClusterStart > 0 Then |
197 | 243 | Dim ClusterCount As UInteger = _BootSector.NumberOfFATEntries + 1 |
198 | 244 |
|
199 | | - For Counter = _FreeSpaceClusterStart To ClusterCount |
200 | | - Dim Data = GetBytes(ClusterToOffset(Counter), _BootSector.BytesPerCluster) |
201 | | - For Each B In Data |
202 | | - If B <> &HF6 And B <> &H0 Then |
| 245 | + For Cluster = _FreeSpaceClusterStart To ClusterCount |
| 246 | + Dim Offset = ClusterToOffset(Cluster) |
| 247 | + Dim Length = _BootSector.BytesPerCluster |
| 248 | + If _FileBytes.Length >= Offset + Length Then |
| 249 | + Dim Data = GetBytes(Offset, Length) |
| 250 | + Dim EmptyByte As Byte = Data(0) |
| 251 | + If EmptyByte <> &HF6 And EmptyByte <> &H0 Then |
203 | 252 | Return True |
204 | 253 | End If |
205 | | - Next |
| 254 | + For Each B In Data |
| 255 | + If B <> EmptyByte Then |
| 256 | + Return True |
| 257 | + End If |
| 258 | + Next |
| 259 | + Else |
| 260 | + Exit For |
| 261 | + End If |
206 | 262 | Next |
207 | 263 | End If |
208 | 264 |
|
|
214 | 270 | Dim Found As Boolean |
215 | 271 |
|
216 | 272 | If _FreeSpaceClusterStart > 0 Then |
217 | | - Dim SectorStart As UInteger = ClusterToSector(_FreeSpaceClusterStart) |
218 | | - Dim SectorCount As UInteger = _BootSector.SectorCount - 1 |
219 | | - |
220 | | - For Counter = SectorStart To SectorCount |
221 | | - Dim Block As DataBlock |
222 | | - With Block |
223 | | - .Cluster = SectorToCluster(Counter) |
224 | | - .Sector = Counter |
225 | | - .Offset = SectorToOffset(Counter) |
226 | | - .Data = GetBytes(.Offset, _BootSector.BytesPerSector) |
227 | | - End With |
| 273 | + Dim ClusterCount As UInteger = _BootSector.NumberOfFATEntries + 1 |
| 274 | + For Cluster = _FreeSpaceClusterStart To ClusterCount |
228 | 275 | Found = False |
229 | | - For Each B In Block.Data |
230 | | - If B <> &HF6 And B <> &H0 Then |
231 | | - Found = True |
232 | | - Exit For |
| 276 | + Dim Sector = ClusterToSector(Cluster) |
| 277 | + For Counter = 0 To _BootSector.SectorsPerCluster - 1 |
| 278 | + Dim Offset = SectorToOffset(Sector + Counter) |
| 279 | + Dim Length = _BootSector.BytesPerSector |
| 280 | + If _FileBytes.Length >= Offset + Length Then |
| 281 | + Dim Block As DataBlock |
| 282 | + With Block |
| 283 | + .Cluster = Cluster |
| 284 | + .Sector = Sector + Counter |
| 285 | + .Offset = Offset |
| 286 | + .Data = GetBytes(.Offset, Length) |
| 287 | + End With |
| 288 | + If Not Found Then |
| 289 | + Dim EmptyByte As Byte = Block.Data(0) |
| 290 | + If EmptyByte <> &HF6 And EmptyByte <> &H0 Then |
| 291 | + Found = True |
| 292 | + Else |
| 293 | + For Each B In Block.Data |
| 294 | + If B <> EmptyByte Then |
| 295 | + Found = True |
| 296 | + Exit For |
| 297 | + End If |
| 298 | + Next |
| 299 | + End If |
| 300 | + End If |
| 301 | + If Found Then |
| 302 | + Result.Add(Block) |
| 303 | + End If |
233 | 304 | End If |
234 | 305 | Next |
235 | | - If Found Then |
236 | | - Result.Add(Block) |
237 | | - End If |
238 | 306 | Next |
239 | 307 | End If |
240 | 308 |
|
|
295 | 363 |
|
296 | 364 | Public Sub SaveFile(FilePath As String) |
297 | 365 | System.IO.File.WriteAllBytes(FilePath, _FileBytes) |
298 | | - _Modified = False |
| 366 | + _OriginalData.Clear() |
299 | 367 | _Modifications.Clear() |
| 368 | + _Modified = False |
300 | 369 | End Sub |
| 370 | + |
| 371 | + Public Function RevertChanges() As Boolean |
| 372 | + Dim Result As Boolean = False |
| 373 | + |
| 374 | + If _OriginalData.Count > 0 Then |
| 375 | + ApplyModifications(_OriginalData) |
| 376 | + _OriginalData.Clear() |
| 377 | + _Modifications.Clear() |
| 378 | + _Modified = False |
| 379 | + End If |
| 380 | + |
| 381 | + Return Result |
| 382 | + End Function |
301 | 383 | End Class |
302 | 384 | End Namespace |
0 commit comments