2

By using the command compact.exe /compactos:query all I get is if compact OS compression is activated or not, but not what compression algorithm is used, such as LZX, XPRESS4K, XPRESS8K or XPRESS16K.

I tried compact.exe /exe:algorithm as suggested at https://renenyffenegger.ch/notes/Windows/dirs/Windows/System32/compact_exe with no luck. it does not understand the switch and returns general explanations for the list of switches like /? does.

FYI I compressed the drive after windows installation using compact.exe /compactos:always command without any additional switches. Performance so far so good.

Another question is, I read in several articles that only system files or executable files are compressed via this method. Can I rest assured that data files like pdf, images, audios, txt, etc. do not be compressed?

phuclv
  • 30,396
  • 15
  • 136
  • 260

3 Answers3

6

Compact.exe already shows you the algorithm by default

PS D:\compressed> compact *.txt

Listing D:\compressed
New files added to this directory will not be compressed.

195634 : 86016 = 2,3 to 1 C LZNT1.txt 195634 : 45056 = 4,3 to 1 l LZX.txt 195634 : 195634 = 1,0 to 1 No_compression.txt 195634 : 69632 = 2,8 to 1 X XPRESS16K.txt 195634 : 81920 = 2,4 to 1 x XPRESS4K.txt 195634 : 73728 = 2,7 to 1 X XPRESS8K.txt ↑ compression algorithm Of 6 files within 1 directories 5 are compressed and 1 are not compressed. 1.173.804 total bytes of data are stored in 551.986 bytes. The compression ratio is 2,1 to 1.

See the second-to-last column, C means the default LZNT1 algorithm, l is LZX, x is XPRESS4K and X is XPRESS8K or XPRESS16K. In fact compact list files just like dir and you can use compact /a to show system/hidden files or compact /s to show files recursively

Unfortunately there isn't a way to differentiate XPRESS8K and XPRESS16K with compact.exe though, but you can do that by calling the Win32 API directly. The new algorithms for CompactOs are handled via Windows Overlay Filter (WOF) and you can use its WofIsExternalFile API to retrieve compression info. I've written a PowerShell script named compression.ps1 do do that. Here's its output for the same files above

PS D:\compressed> .\compression.ps1 (ls *.txt)

FileName Algorithm


D:\compressed\LZNT1.txt LZNT1 D:\compressed\LZX.txt LZX D:\compressed\No_compression.txt NO_COMPRESSION D:\compressed\XPRESS16K.txt XPRESS16K D:\compressed\XPRESS4K.txt XPRESS4K D:\compressed\XPRESS8K.txt XPRESS8K

Here's its source code, just save as *.ps1 and run as above

param(
    [Parameter()]
    [string[]]$fileList
)

Add-Type -Name 'Wof' -Namespace 'Wofutil' -MemberDefinition @' public struct ExternalFileInfo { public uint algorithm; public uint flags; }

[DllImport("Wofutil.dll")]public static extern int WofIsExternalFile(
    [MarshalAs(UnmanagedType.LPWStr)] string Filepath,
    out int IsExternalFile,
    out uint Provider,
    out ExternalFileInfo Info,
    ref uint BufferLength
);

'@

enum Algorithms { NO_COMPRESSION = -2 LZNT1 = -1 XPRESS4K = 0 LZX = 1 XPRESS8K = 2 XPRESS16K = 3 }

class CompressionInfo { [string]$FileName [Algorithms]$Algorithm }

foreach ($fileName in $fileList) { $f = Get-ChildItem -LiteralPath $fileName if (($f.Attributes -band [IO.FileAttributes]::Compressed) -ne 0) { [CompressionInfo]@{ FileName = $f Algorithm = 'LZNT1' } } else { [int]$isExternalFile = 0 [uint32]$provider = 0 $fileInfo = New-Object Wofutil.Wof+ExternalFileInfo [uint32]$length = 8

    [void][Wofutil.Wof]::WofIsExternalFile($f, [ref]$isExternalFile,
        [ref]$provider, [ref]$fileInfo, [ref]$length)
    if ($isExternalFile -ne 0) {
        [CompressionInfo]@{
            FileName = $f
            Algorithm = $fileInfo.algorithm
        }
    } else {
        [CompressionInfo]@{
            FileName = $f
            Algorithm = 'NO_COMPRESSION'
        }
    }
}

}

Note that NTFS compression and CompactOS are completely different features. When MS introduced the new CompactOS feature they merged it into the compact command because of their relation to compression. But CompactOS is purely to compress read-only system files to save the OS footprint. You can clearly see that the option is called /exe because it's meant to compress executable files. That's why the new algorithms aren't designed for editing and writing to the files will decompress them

PS D:\compressed> echo x >.\LZX.txt # Write more data to file

PS D:\compressed> compact .\LZX.txt # Now the file is uncompressed

Listing D:\compressed
New files added to this directory will not be compressed.

    8 :         8 = 1,0 to 1   LZX.txt

Of 1 files within 1 directories 0 are compressed and 1 are not compressed. 8 total bytes of data are stored in 8 bytes. The compression ratio is 1,0 to 1.

OTOH the NTFS compression feature uses the old LZNT1 algorithm and is designed to work with any files. It supports on-the-fly editing where you can write to the files arbitrarily and they're still compressed. You can also mark new files in the folder to be compressed automatically with LZNT1 but not with the new algorithms

Note that the /exe option isn't for checking the algorithm but to specify an algorithm when compressing. compact /C /exe:<algorithm> your_files will compress the specified files with the specified EXE algorithm, whereas compact /C your_files will compress the files using NTFS compression

phuclv
  • 30,396
  • 15
  • 136
  • 260
2

How do I know the compression algorithm used by CompactOs

There doesn't seem to be a way of retrieving the algorithm used.

I tried "compact.exe /exe:algorithm"

algorithm is a place holder. You should replace it with one of the supported compression methods:

/EXE Use compression optimised for executable files which are read frequently and not modified,

Supported algorithms are:

XPRESS4K (fastest) default

XPRESS8K

XPRESS16K

LZX (most compact)

Source: Compact - Compress files - Windows CMD - SS64.com

Example usage:

compact /exe:XPRESS4K

I compressed the drive after windows installation using compact.exe /compactos:always command without any additional switches. I read in several articles that only system files or executable files are compressed via this method

That is almost correct. It will only compress "OS binaries". This will probably include System executable and DLL files but won't include other non-system executable files.

/CompactOs Set or query the systems compression state.

Supported options are:

query - Query the systems compact state.

always - Compress all OS binaries and set the system state to non-compact.

never - Uncompress all OS binaries and set the system state to compact which remains unless an administrator changes it.

(emphasis mine)

Source: Compact - Compress files - Windows CMD - SS64.com

. Can I rest assured that data files like pdf, images, audios, txt, etc. are not compressed?

Yes. The documentation doesn't mention these kinds of file.

DavidPostill
  • 162,382
1

Regarding your primary question - what algorithm does CompactOS use - I can confirm it always uses XPRESS4K. No need to check with the compact command.

In addition, CompactOS does not allow user to choose the algorithm. If you try combining the /CompactOS and /EXE command-line arguments, compact.exe will not recognize them.

Fred Qian
  • 432