Skip to content

Commit f1d0be3

Browse files
committed
Refactor file handling to use SafeFileHandle in Compactor and Uncompactor, and separate NtfsInterop module
1 parent 5083aae commit f1d0be3

File tree

5 files changed

+60
-63
lines changed

5 files changed

+60
-63
lines changed

CompactGUI.Core/Compactor.vb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Imports System.Runtime.InteropServices
33
Imports System.Threading
44

5+
Imports Microsoft.Win32.SafeHandles
6+
57

68
Public Class Compactor : Implements IDisposable, ICompressor
79

@@ -103,8 +105,8 @@ Public Class Compactor : Implements IDisposable, ICompressor
103105
Private Function WOFCompressFile(path As String) As Integer
104106

105107
Try
106-
Using fs As New FileStream(path, FileMode.Open)
107-
Return WofSetFileDataLocation(fs.SafeFileHandle.DangerousGetHandle(), WOF_PROVIDER_FILE, compressionInfoPtr, compressionInfoSize)
108+
Using fs As SafeFileHandle = File.OpenHandle(path)
109+
Return WofSetFileDataLocation(fs, WOF_PROVIDER_FILE, compressionInfoPtr, compressionInfoSize)
108110
End Using
109111
Catch ex As Exception
110112
Debug.WriteLine(ex.Message)

CompactGUI.Core/Estimator.vb

Lines changed: 3 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ Public Class Estimator
200200
Dim bytesReturned As Integer = 0
201201

202202
Try
203-
Dim result = NtfsInterop.DeviceIoControl(
203+
Dim result = WOFHelper.DeviceIoControl(
204204
handle,
205205
NtfsInterop.FSCTL_GET_RETRIEVAL_POINTERS,
206206
inBufferPtr,
@@ -211,6 +211,8 @@ Public Class Estimator
211211
IntPtr.Zero
212212
)
213213

214+
215+
214216
'Probably errors because the file is empty
215217
If Not result Then Return Long.MaxValue
216218

@@ -228,56 +230,3 @@ Public Class Estimator
228230
End Function
229231

230232
End Class
231-
232-
Friend Module NtfsInterop
233-
Public Const FSCTL_GET_RETRIEVAL_POINTERS As UInteger = &H90073
234-
Public Const OPEN_EXISTING As Integer = 3
235-
Public Const FILE_FLAG_BACKUP_SEMANTICS As Integer = &H2000000
236-
Public Const FILE_SHARE_READ As Integer = 1
237-
Public Const FILE_SHARE_WRITE As Integer = 2
238-
Public Const GENERIC_READ As Integer = &H80000000
239-
240-
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
241-
Public Function CreateFile(
242-
lpFileName As String,
243-
dwDesiredAccess As Integer,
244-
dwShareMode As Integer,
245-
lpSecurityAttributes As IntPtr,
246-
dwCreationDisposition As Integer,
247-
dwFlagsAndAttributes As Integer,
248-
hTemplateFile As IntPtr
249-
) As SafeFileHandle
250-
End Function
251-
252-
<DllImport("kernel32.dll", SetLastError:=True)>
253-
Public Function DeviceIoControl(
254-
hDevice As SafeFileHandle,
255-
dwIoControlCode As UInteger,
256-
lpInBuffer As IntPtr,
257-
nInBufferSize As Integer,
258-
lpOutBuffer As IntPtr,
259-
nOutBufferSize As Integer,
260-
ByRef lpBytesReturned As Integer,
261-
lpOverlapped As IntPtr
262-
) As Boolean
263-
End Function
264-
265-
266-
<StructLayout(LayoutKind.Sequential)>
267-
Public Structure STARTING_VCN_INPUT_BUFFER
268-
Public StartingVcn As Long
269-
End Structure
270-
271-
<StructLayout(LayoutKind.Sequential)>
272-
Public Structure RETRIEVAL_POINTERS_BUFFER
273-
Public ExtentCount As Integer
274-
Public StartingVcn As Long
275-
Public Extents As LCN_EXTENT ' This is actually an array, but we only need the first
276-
End Structure
277-
278-
<StructLayout(LayoutKind.Sequential)>
279-
Public Structure LCN_EXTENT
280-
Public NextVcn As Long
281-
Public Lcn As Long
282-
End Structure
283-
End Module

CompactGUI.Core/NtfsInterop.vb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Imports System.Runtime.InteropServices
2+
3+
Imports Microsoft.Win32.SafeHandles
4+
5+
Friend Module NtfsInterop
6+
Public Const FSCTL_GET_RETRIEVAL_POINTERS As UInteger = &H90073
7+
Public Const OPEN_EXISTING As Integer = 3
8+
Public Const FILE_FLAG_BACKUP_SEMANTICS As Integer = &H2000000
9+
Public Const FILE_SHARE_READ As Integer = 1
10+
Public Const FILE_SHARE_WRITE As Integer = 2
11+
Public Const GENERIC_READ As Integer = &H80000000
12+
13+
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
14+
Public Function CreateFile(
15+
lpFileName As String,
16+
dwDesiredAccess As Integer,
17+
dwShareMode As Integer,
18+
lpSecurityAttributes As IntPtr,
19+
dwCreationDisposition As Integer,
20+
dwFlagsAndAttributes As Integer,
21+
hTemplateFile As IntPtr
22+
) As SafeFileHandle
23+
End Function
24+
25+
<StructLayout(LayoutKind.Sequential)>
26+
Public Structure STARTING_VCN_INPUT_BUFFER
27+
Public StartingVcn As Long
28+
End Structure
29+
30+
<StructLayout(LayoutKind.Sequential)>
31+
Public Structure RETRIEVAL_POINTERS_BUFFER
32+
Public ExtentCount As Integer
33+
Public StartingVcn As Long
34+
Public Extents As LCN_EXTENT ' This is actually an array, but we only need the first. ?Perhaps I should get the LCN of the middle cluster in future?
35+
End Structure
36+
37+
<StructLayout(LayoutKind.Sequential)>
38+
Public Structure LCN_EXTENT
39+
Public NextVcn As Long
40+
Public Lcn As Long
41+
End Structure
42+
End Module

CompactGUI.Core/Uncompactor.vb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Imports System.IO
22
Imports System.Threading
33

4+
Imports Microsoft.Win32.SafeHandles
5+
46
Public Class Uncompactor : Implements ICompressor, IDisposable
57

68

@@ -52,9 +54,8 @@ Public Class Uncompactor : Implements ICompressor, IDisposable
5254
Private Function WOFDecompressFile(path As String)
5355

5456
Try
55-
Using fs As FileStream = New FileStream(path, FileMode.Open)
56-
Dim hDevice = fs.SafeFileHandle.DangerousGetHandle
57-
Dim res = WOFHelper.DeviceIoControl(hDevice, FSCTL_DELETE_EXTERNAL_BACKING, IntPtr.Zero, 0, IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero)
57+
Using fs As SafeFileHandle = File.OpenHandle(path)
58+
Dim res = WOFHelper.DeviceIoControl(fs, FSCTL_DELETE_EXTERNAL_BACKING, IntPtr.Zero, 0, IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero)
5859
Return res
5960
End Using
6061
Catch ex As Exception

CompactGUI.Core/WOFHelper.vb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
Imports System.Runtime.InteropServices
22

3+
Imports Microsoft.Win32.SafeHandles
4+
35
Public Module WOFHelper
46

57
Public Const WOF_PROVIDER_FILE As ULong = 2
@@ -40,6 +42,7 @@ Public Module WOFHelper
4042

4143
End Function
4244

45+
<StructLayout(LayoutKind.Sequential)>
4346
Public Structure WOF_FILE_COMPRESSION_INFO_V1
4447
Public Algorithm As UInteger
4548
Public Flags As UInteger
@@ -57,7 +60,7 @@ Public Module WOFHelper
5760

5861
<DllImport("WofUtil.dll")>
5962
Friend Function WofSetFileDataLocation(
60-
FileHandle As IntPtr,
63+
FileHandle As SafeFileHandle,
6164
Provider As ULong,
6265
ExternalFileInfo As IntPtr,
6366
Length As ULong) As Integer
@@ -66,14 +69,14 @@ Public Module WOFHelper
6669
'Most of these should be optional if MS Docs are to be believed -.-
6770
<DllImport("kernel32.dll")>
6871
Friend Function DeviceIoControl(
69-
hDevice As IntPtr,
72+
hDevice As SafeFileHandle,
7073
dwIoControlCode As UInteger,
7174
lpInBuffer As IntPtr,
7275
nInBufferSize As UInteger,
7376
lpOutBuffer As IntPtr,
7477
nOutBufferSize As UInteger,
75-
<Out> lpBytesReturned As IntPtr,
76-
<Out> lpOverlapped As IntPtr) As Integer
78+
<Out> ByRef lpBytesReturned As IntPtr,
79+
<Out> lpOverlapped As IntPtr) As Boolean
7780

7881
End Function
7982

0 commit comments

Comments
 (0)