Skip to content

Commit 1fa8eda

Browse files
committed
Improvements to Hex Viewer
1 parent 36010df commit 1fa8eda

13 files changed

+505
-192
lines changed

DiskImageTool/AdvancedListView.Designer.vb

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

DiskImageTool/AdvancedListView.vb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
Imports System.Runtime.InteropServices
2+
3+
Friend Class AdvancedListView
4+
Inherits ListView
5+
6+
Public Event Scroll As EventHandler
7+
8+
Public Sub ScrollToGroup(key As String, height As Integer)
9+
ScrollToGroup(Groups.Item(key), height)
10+
End Sub
11+
12+
Public Sub ScrollToGroup(index As Integer, height As Integer)
13+
ScrollToGroup(Groups.Item(index), height)
14+
End Sub
15+
16+
Private Sub ScrollToGroup(lvg As ListViewGroup, height As Integer)
17+
If lvg.Items.Count > 0 Then
18+
ScrollV(lvg.Items(0).Position.Y, height)
19+
End If
20+
End Sub
21+
22+
Protected Sub ScrollV(scrollPos As Integer, height As Integer)
23+
scrollPos -= height
24+
25+
Dim prevScrollPos As Integer = (Me.Items(0).Position.Y - height) * -1
26+
Dim WhereToScroll As Integer = prevScrollPos + scrollPos
27+
28+
Call AdvancedListView.SendMessage(New HandleRef(Nothing, Me.Handle), ListViewMessages.LVM_SCROLL, CType(0, IntPtr), CType(scrollPos, IntPtr))
29+
30+
prevScrollPos = (Me.Items(0).Position.Y - height) * -1
31+
32+
If WhereToScroll <> prevScrollPos Then
33+
scrollPos = WhereToScroll - prevScrollPos
34+
Call AdvancedListView.SendMessage(New HandleRef(Nothing, Me.Handle), ListViewMessages.LVM_SCROLL, CType(0, IntPtr), CType(scrollPos, IntPtr))
35+
End If
36+
End Sub
37+
Protected Overridable Sub OnScroll()
38+
Dim handler As EventHandler = ScrollEvent
39+
If handler IsNot Nothing Then
40+
handler(Me, EventArgs.Empty)
41+
End If
42+
End Sub
43+
Protected Overrides Sub WndProc(ByRef m As Message)
44+
MyBase.WndProc(m)
45+
46+
If m.Msg = &H115 Or m.Msg = &H20A Then
47+
OnScroll()
48+
ElseIf m.Msg = &H100 Then
49+
If m.WParam = 33 Or m.WParam = 34 Or m.WParam = 35 Or m.WParam = 36 Or m.WParam = 38 Or m.WParam = 40 Then
50+
OnScroll()
51+
End If
52+
End If
53+
End Sub
54+
55+
Private Enum ListViewMessages As UInteger
56+
LVM_FIRST = &H1000
57+
LVM_SCROLL = LVM_FIRST + 20
58+
End Enum
59+
60+
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=False)>
61+
Private Shared Function SendMessage(ByVal hWnd As HandleRef, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
62+
End Function
63+
End Class

DiskImageTool/DiskImage/BootSector.vb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,12 @@
4040
_Parent = Parent
4141
End Sub
4242

43-
Public Function DataRegionSize() As UInteger
44-
Dim TotalNumberOfSectors = SmallNumberOfSectors
45-
If TotalNumberOfSectors = 0 Then
46-
TotalNumberOfSectors = LargeNumberOfSectors
47-
End If
43+
Public Function BytesPerCluster() As UInteger
44+
Return SectorsPerCluster * BytesPerSector
45+
End Function
4846

49-
Return TotalNumberOfSectors - (ReservedSectors + FatRegionSize() + RootDirectoryRegionSize())
47+
Public Function DataRegionSize() As UInteger
48+
Return SectorCount() - (ReservedSectors + FatRegionSize() + RootDirectoryRegionSize())
5049
End Function
5150

5251
Public Function DataRegionStart() As UInteger
@@ -73,6 +72,14 @@
7372
Return FatRegionStart() + FatRegionSize()
7473
End Function
7574

75+
Public Function SectorCount() As UInteger
76+
If SmallNumberOfSectors > 0 Then
77+
Return SmallNumberOfSectors
78+
Else
79+
Return LargeNumberOfSectors
80+
End If
81+
End Function
82+
7683
Public Property BootStrapCode() As Byte()
7784
Get
7885
Return _Parent.GetBytes(BootSectorOffset.BootStrapCode, BootSectorSize.BootStrapCode)

DiskImageTool/DiskImage/Directory.vb

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,22 @@
88
_FatChain = FatChain
99
End Sub
1010

11-
Private Function GetDataRoot() As DataBlock
12-
Dim Result As DataBlock
11+
Private Function GetDataRoot() As List(Of DataBlock)
12+
Dim Result As New List(Of DataBlock)
1313

14-
Result.Offset = _Parent.BootSector.RootDirectoryRegionStart * _Parent.BootSector.BytesPerSector
15-
Dim OffsetEnd As UInteger = _Parent.BootSector.DataRegionStart * _Parent.BootSector.BytesPerSector
14+
Dim SectorStart = _Parent.BootSector.RootDirectoryRegionStart
15+
Dim SectorEnd = _Parent.BootSector.DataRegionStart
1616

17-
Result.Data = _Parent.GetBytes(Result.Offset, OffsetEnd - Result.Offset)
17+
For Sector = SectorStart To SectorEnd - 1
18+
Dim Block As DataBlock
19+
With Block
20+
.Cluster = 0
21+
.Sector = Sector
22+
.Offset = _Parent.SectorToOffset(Sector)
23+
.Data = _Parent.GetBytes(.Offset, _Parent.BootSector.BytesPerSector)
24+
End With
25+
Result.Add(Block)
26+
Next
1827

1928
Return Result
2029
End Function
@@ -23,15 +32,17 @@
2332
Dim Result As New List(Of DataBlock)
2433

2534
For Each Cluster In _FatChain
26-
Dim Block As DataBlock
27-
28-
Block.Offset = _Parent.BootSector.DataRegionStart + ((Cluster - 2) * _Parent.BootSector.SectorsPerCluster)
29-
Block.Offset *= _Parent.BootSector.BytesPerSector
30-
31-
Dim Length As UInteger = _Parent.BootSector.SectorsPerCluster * _Parent.BootSector.BytesPerSector
32-
33-
Block.Data = _Parent.GetBytes(Block.Offset, Length)
34-
Result.Add(Block)
35+
Dim Sector = _Parent.ClusterToSector(Cluster)
36+
For Counter = 0 To _Parent.BootSector.SectorsPerCluster - 1
37+
Dim Block As DataBlock
38+
With Block
39+
.Cluster = Cluster
40+
.Sector = Sector + Counter
41+
.Offset = _Parent.SectorToOffset(Sector + Counter)
42+
.Data = _Parent.GetBytes(.Offset, _Parent.BootSector.BytesPerSector)
43+
End With
44+
Result.Add(Block)
45+
Next
3546
Next
3647

3748
Return Result
@@ -41,39 +52,34 @@
4152
Dim Count As UInteger = 0
4253

4354
For Each Cluster In _FatChain
44-
Dim OffsetStart As UInteger = _Parent.BootSector.DataRegionStart + ((Cluster - 2) * _Parent.BootSector.SectorsPerCluster)
45-
Dim OffsetEnd As UInteger = OffsetStart + _Parent.BootSector.SectorsPerCluster
55+
Dim OffsetStart As UInteger = _Parent.ClusterToOffset(Cluster)
56+
Dim OffsetLength As UInteger = _Parent.BootSector.BytesPerCluster
4657

47-
OffsetStart *= _Parent.BootSector.BytesPerSector
48-
OffsetEnd *= _Parent.BootSector.BytesPerSector
4958

50-
Count += _Parent.GetDirectoryLength(OffsetStart, OffsetEnd, FileCountOnly)
59+
Count += _Parent.GetDirectoryLength(OffsetStart, OffsetStart + OffsetLength, FileCountOnly)
5160
Next
5261

5362
Return Count
5463
End Function
5564

5665
Private Function GetDirectoryLengthRoot(FileCountOnly As Boolean) As UInteger
57-
Dim OffsetStart As UInteger = _Parent.BootSector.RootDirectoryRegionStart * _Parent.BootSector.BytesPerSector
58-
Dim OffsetEnd As UInteger = _Parent.BootSector.DataRegionStart * _Parent.BootSector.BytesPerSector
66+
Dim OffsetStart As UInteger = _Parent.SectorToOffset(_Parent.BootSector.RootDirectoryRegionStart)
67+
Dim OffsetEnd As UInteger = _Parent.SectorToOffset(_Parent.BootSector.DataRegionStart)
5968

6069
Return _Parent.GetDirectoryLength(OffsetStart, OffsetEnd, FileCountOnly)
6170
End Function
6271

6372
Private Function GetFileSubDirectory(Index As UInteger) As DiskImage.DirectoryEntry
64-
Dim EntriesPerCluster As UInteger = _Parent.BootSector.BytesPerSector * _Parent.BootSector.SectorsPerCluster / 32
73+
Dim EntriesPerCluster As UInteger = _Parent.BootSector.BytesPerCluster / 32
6574
Dim ChainIndex As UInteger = (Index - 1) \ EntriesPerCluster
6675
Dim ClusterIndex As UInteger = (Index - 1) Mod EntriesPerCluster
67-
Dim Offset As UInteger = _Parent.BootSector.DataRegionStart + ((_FatChain.Item(ChainIndex) - 2) * _Parent.BootSector.SectorsPerCluster)
68-
Offset *= _Parent.BootSector.BytesPerSector
69-
Offset += ClusterIndex * 32
76+
Dim Offset As UInteger = _Parent.ClusterToOffset(_FatChain.Item(ChainIndex)) + ClusterIndex * 32
7077

7178
Return New DiskImage.DirectoryEntry(_Parent, Offset)
7279
End Function
7380

7481
Private Function GetFileRoot(Index As Integer) As DiskImage.DirectoryEntry
75-
Dim Offset As UInteger = _Parent.BootSector.RootDirectoryRegionStart * _Parent.BootSector.BytesPerSector
76-
Offset += (Index - 1) * 32
82+
Dim Offset As UInteger = _Parent.SectorToOffset(_Parent.BootSector.RootDirectoryRegionStart) + (Index - 1) * 32
7783

7884
Return New DiskImage.DirectoryEntry(_Parent, Offset)
7985
End Function
@@ -104,9 +110,7 @@
104110

105111
Public Function GetData() As List(Of DataBlock)
106112
If _FatChain Is Nothing Then
107-
Return New List(Of DataBlock) From {
108-
GetDataRoot()
109-
}
113+
Return GetDataRoot()
110114
Else
111115
Return GetDataSubDirectory()
112116
End If

DiskImageTool/DiskImage/DirectoryEntry.vb

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,8 @@ Namespace DiskImage
212212
Dim FileBytes = _Parent.Data
213213

214214
For Each Cluster In _FatChain
215-
Dim Offset As UInteger = _Parent.BootSector.DataRegionStart + ((Cluster - 2) * _Parent.BootSector.SectorsPerCluster)
216-
Offset *= _Parent.BootSector.BytesPerSector
217-
BytesToCopy = _Parent.BootSector.BytesPerSector * _Parent.BootSector.SectorsPerCluster
215+
Dim Offset As UInteger = _Parent.ClusterToOffset(Cluster)
216+
BytesToCopy = _Parent.BootSector.BytesPerCluster
218217
If BytesToCopy > BytesRemaining Then
219218
BytesToCopy = BytesRemaining
220219
End If
@@ -353,15 +352,7 @@ Namespace DiskImage
353352
End Function
354353

355354
Public Function HasInvalidFileSize() As Boolean
356-
Dim SectorCount As UInteger
357-
358-
If _Parent.BootSector.SmallNumberOfSectors > 0 Then
359-
SectorCount = _Parent.BootSector.SmallNumberOfSectors
360-
Else
361-
SectorCount = _Parent.BootSector.LargeNumberOfSectors
362-
End If
363-
364-
Return FileSize > SectorCount * _Parent.BootSector.BytesPerSector
355+
Return FileSize > _Parent.BootSector.SectorCount * _Parent.BootSector.BytesPerSector
365356
End Function
366357

367358
Public Function HasLastAccessDate() As Boolean

0 commit comments

Comments
 (0)