Skip to content

Commit f130bd1

Browse files
committed
Switch from using compact.exe to WOFUtil.dll for compression. Much faster
Uncompressing still uses compact.exe for now
1 parent f108cb8 commit f130bd1

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

CompactGUI/Compactor.vb

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
Imports System.Threading
1+
Imports System.IO
2+
Imports System.Runtime.InteropServices
3+
Imports System.Threading
24
Imports MethodTimer
35

46
Public Class Compactor
@@ -13,6 +15,10 @@ Public Class Compactor
1315
Private _workingDir As String
1416
Private _compressionLevel As String
1517
Private _excludedFileTypes As List(Of String)
18+
Private _WOFcompressionLevel As ULong
19+
20+
Private _EFInfo As _WOF_FILE_COMPRESSION_INFO_V1
21+
Private _EFInfoPtr As IntPtr
1622

1723
Sub New(folder As String, cLevelIndex As Integer, excludedfiletypes As List(Of String))
1824

@@ -21,6 +27,10 @@ Public Class Compactor
2127
_workingDir = folder
2228
_excludedFileTypes = excludedfiletypes
2329
_compressionLevel = CompressionLevel(cLevelIndex)
30+
_WOFcompressionLevel = WOFConvertCompressionLevel(cLevelIndex)
31+
_EFInfo = New _WOF_FILE_COMPRESSION_INFO_V1 With {.Algorithm = _WOFcompressionLevel, .Flags = 0}
32+
_EFInfoPtr = Marshal.AllocHGlobal(Marshal.SizeOf(_EFInfo))
33+
Marshal.StructureToPtr(_EFInfo, _EFInfoPtr, True)
2434

2535
End Sub
2636

@@ -53,6 +63,36 @@ Public Class Compactor
5363

5464
End Sub
5565

66+
67+
Shared Function DetectCompression(path As String)
68+
69+
Dim isextFile As Integer
70+
Dim prov As ULong
71+
Dim info As _WOF_FILE_COMPRESSION_INFO_V1
72+
Dim buf As UInt16 = 8
73+
Dim ret = WofIsExternalFile(path, isextFile, prov, info, buf)
74+
75+
End Function
76+
77+
78+
Sub WOFCompressFile(path As String)
79+
80+
Dim length As ULong = Marshal.SizeOf(_EFInfoPtr)
81+
82+
Using fs As FileStream = New FileStream(path, FileMode.Open)
83+
Dim hFile = fs.SafeFileHandle.DangerousGetHandle()
84+
Dim res = WofSetFileDataLocation(hFile, WOF_PROVIDER_FILE, _EFInfoPtr, length)
85+
If res <> 0 Then
86+
If res <> -2147024552 Then
87+
Debug.WriteLine("spaghetti")
88+
End If
89+
90+
End If
91+
End Using
92+
93+
End Sub
94+
95+
5696
<Time>
5797
Async Function RunCompactAsync(progress As IProgress(Of (percentageProgress As Integer, currentFile As String))) As Task(Of Boolean)
5898

@@ -64,7 +104,8 @@ Public Class Compactor
64104

65105
Await Parallel.ForEachAsync(_filesList,
66106
Function(file, _ctx)
67-
GenerateThread(_workingDir, compactArgs & " " & """" & file & """")
107+
WOFCompressFile(file)
108+
'GenerateThread(_workingDir, compactArgs & " " & """" & file & """")
68109
Dim result = Interlocked.Increment(count)
69110
progress.Report((CInt(((result / totalFiles) * 100)), file))
70111
End Function).ConfigureAwait(False)

CompactGUI/WOFHelper.vb

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Imports System.Runtime.InteropServices
2+
3+
Module WOFHelper
4+
5+
Public Const WOF_PROVIDER_FILE As ULong = 2
6+
Public Const FILE_PROVIDER_COMPRESSION_XPRESS4K As ULong = 0
7+
Public Const FILE_PROVIDER_COMPRESSION_LZX As ULong = 1
8+
Public Const FILE_PROVIDER_COMPRESSION_XPRESS8K As ULong = 2
9+
Public Const FILE_PROVIDER_COMPRESSION_XPRESS16K As ULong = 3
10+
11+
12+
Public Function WOFConvertCompressionLevel(compressionlevel As Integer) As ULong
13+
14+
Select Case compressionlevel
15+
Case 0 : Return FILE_PROVIDER_COMPRESSION_XPRESS4K
16+
Case 1 : Return FILE_PROVIDER_COMPRESSION_XPRESS8K
17+
Case 2 : Return FILE_PROVIDER_COMPRESSION_XPRESS16K
18+
Case 3 : Return FILE_PROVIDER_COMPRESSION_LZX
19+
End Select
20+
21+
End Function
22+
23+
24+
25+
Public Structure _WOF_FILE_COMPRESSION_INFO_V1
26+
Public Algorithm As ULong
27+
Public Flags As ULong
28+
End Structure
29+
30+
<DllImport("WofUtil.dll")>
31+
Public Function WofIsExternalFile(
32+
<MarshalAs(UnmanagedType.LPWStr)> ByVal Filepath As String,
33+
<Out> ByRef IsExternalFile As Integer,
34+
<Out> ByRef Provider As UInteger,
35+
<Out> ByRef Info As _WOF_FILE_COMPRESSION_INFO_V1,
36+
ByRef BufferLength As UInteger) As Integer
37+
End Function
38+
39+
<DllImport("WofUtil.dll")>
40+
Public Function WofSetFileDataLocation(
41+
FileHandle As IntPtr,
42+
Provider As ULong,
43+
ExternalFileInfo As IntPtr,
44+
Length As ULong) As Integer
45+
End Function
46+
End Module

0 commit comments

Comments
 (0)