MSDN Community - Windows API Reference

Exploring the depths of Windows Filesystem Compression APIs

Filesystem Compression API Reference

Introduction to Windows Compression

Windows offers robust support for file and folder compression to save disk space and improve performance on slower storage devices. The Filesystem Compression APIs provide developers with the tools to programmatically manage these compression settings. This section details the core functions and concepts related to filesystem compression in Windows.

Compression is typically handled at the NTFS filesystem level, allowing individual files or entire directories to be marked as compressed. When a file is compressed, data written to it is compressed by the system before being stored on disk, and decompressed automatically when read.

Key Concepts

  • NTFS Compression: The underlying filesystem technology that enables transparent compression of files and directories.
  • Compression Attribute: A file attribute that indicates whether a file or directory should be compressed.
  • Transparency: The compression and decompression process is handled by the operating system and is invisible to applications.
  • Performance Impact: While compression saves space, it can incur a CPU overhead for compression and decompression. This is usually negligible on modern hardware but can be noticeable on very CPU-bound systems or with highly compressible data.

Core API Functions

The following functions are central to managing filesystem compression:

Function Name Description Header File Library
FsRtlCompressFile Compresses or decompresses a file. (Internal/Driver level) ntddk.h Ntoskrnl.exe
FsRtlQueryCompressionInformation Retrieves compression information for a file or directory. (Internal/Driver level) ntddk.h Ntoskrnl.exe
SetCompressedFile Sets the compression attribute for a file or directory. (User-mode emulation/wrapper) windows.h Kernel32.lib
GetCompressedFile Retrieves the compression attribute for a file or directory. (User-mode emulation/wrapper) windows.h Kernel32.lib
DeviceIoControl Can be used with specific IOCTL codes to manage compression for volumes or files. windows.h Kernel32.lib

Example: Setting the Compression Attribute (Conceptual)

While direct user-mode control over the compression attribute is often managed through file explorer or higher-level APIs, lower-level interaction might involve functions like DeviceIoControl. For typical application development, manipulating the attribute is often achieved by setting the file system's internal flags or by leveraging tools that interact with these flags.

A common approach in user-mode is to use File Explorer's properties dialog. Programmatically, one might use the SetCompressedFile and GetCompressedFile (if exposed or emulated) or manage it via DeviceIoControl with appropriate IOCTLs.

Below is a conceptual illustration using pseudo-code and common Win32 function patterns:


// This is a conceptual example and may not be directly callable.
// Actual implementation might involve File System Filter Drivers or specific Win32 APIs.

#include <windows.h>

// Function to set the compression attribute for a file
BOOL EnableFileCompression(HANDLE hFile)
{
    // In a real scenario, this would involve a specific IOCTL to the filesystem driver
    // or a wrapper function that abstracts this complexity.
    // For demonstration, we'll assume a hypothetical function or IOCTL.

    DWORD bytesReturned;
    // Example IOCTL code (hypothetical, specific codes vary and are internal)
    // ULONG IOCTL_SET_COMPRESSION = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 100, METHOD_BUFFERED, FILE_ANY_ACCESS);

    // BOOL success = DeviceIoControl(hFile, IOCTL_SET_COMPRESSION, NULL, 0, NULL, 0, &bytesReturned, NULL);

    // Alternatively, if a high-level API existed:
    // BOOL success = SetCompressedFile(hFile, TRUE);

    // For simplicity in this example, we'll return TRUE, assuming success.
    // In practice, error checking is crucial.
    BOOL success = TRUE; // Placeholder
    if (!success) {
        // Handle error
        // DWORD error = GetLastError();
    }
    return success;
}

// Function to check if a file is compressed
BOOL IsFileCompressed(HANDLE hFile)
{
    // Similar to EnableFileCompression, this would use specific IOCTLs or APIs.
    // For demonstration, we'll assume a hypothetical function or IOCTL.

    DWORD bytesReturned;
    // Example IOCTL code (hypothetical)
    // ULONG IOCTL_GET_COMPRESSION_STATUS = CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 101, METHOD_BUFFERED, FILE_ANY_ACCESS);
    // BOOLEAN compressed = FALSE; // Output buffer

    // BOOL success = DeviceIoControl(hFile, IOCTL_GET_COMPRESSION_STATUS, NULL, 0, &compressed, sizeof(compressed), &bytesReturned, NULL);

    // Alternatively, if a high-level API existed:
    // BOOL compressed = GetCompressedFile(hFile);

    // For simplicity, return FALSE as a placeholder.
    BOOL compressed = FALSE; // Placeholder
    if (!success) {
        // Handle error
        // DWORD error = GetLastError();
    }
    return compressed;
}

int main()
{
    // Obtain a handle to a file
    HANDLE fileHandle = CreateFile(L"C:\\path\\to\\your\\file.txt",
                                   GENERIC_READ | GENERIC_WRITE,
                                   0, NULL, OPEN_ALWAYS,
                                   FILE_ATTRIBUTE_NORMAL, NULL);

    if (fileHandle != INVALID_HANDLE_VALUE)
    {
        if (EnableFileCompression(fileHandle))
        {
            wprintf(L"Compression enabled for file.\n");
        }
        else
        {
            wprintf(L"Failed to enable compression.\n");
        }

        if (IsFileCompressed(fileHandle))
        {
            wprintf(L"File is currently compressed.\n");
        }
        else
        {
            wprintf(L"File is not currently compressed.\n");
        }

        CloseHandle(fileHandle);
    }
    else
    {
        wprintf(L"Failed to open file. Error: %lu\n", GetLastError());
    }

    return 0;
}
                

Compression Algorithms and Levels

NTFS compression uses a form of Lempel-Ziv compression, similar to LZW. The compression is applied on a per-cluster basis. Windows does not offer multiple configurable compression *levels* in the same way that user-level archiving tools (like WinZip or 7-Zip) do. The compression is either on or off for a file or directory.

Considerations

  • Performance Trade-offs: Always consider the balance between disk space savings and potential CPU usage.
  • Fragmentation: Compressed files can become more fragmented over time, which might impact performance on traditional HDDs.
  • Compatibility: NTFS compression is generally transparent and compatible with most applications. However, some low-level disk utilities or file system tools might need specific handling.
  • Network Shares: Compression on network shares (e.g., DFS) might behave differently or be disabled depending on server configuration and protocols.