#include <Windows.h>
#include "CompactLib.h"
#ifndef NativeAPI
#define NativeAPI
#pragma comment(lib,"ntdll.lib")
#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0)
typedef
struct
_IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
PVOID
Pointer;
};
ULONG_PTR
Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef
VOID
(NTAPI *PIO_APC_ROUTINE)(
_In_
PVOID
ApcContext,
_In_ PIO_STATUS_BLOCK IoStatusBlock,
_In_
ULONG
Reserved
);
extern
"C"
{
NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile(
_In_
HANDLE
FileHandle,
_In_opt_
HANDLE
Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_
PVOID
ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_
ULONG
FsControlCode,
_In_reads_bytes_opt_(InputBufferLength)
PVOID
InputBuffer,
_In_
ULONG
InputBufferLength,
_Out_writes_bytes_opt_(OutputBufferLength)
PVOID
OutputBuffer,
_In_
ULONG
OutputBufferLength
);
NTSYSAPI
ULONG
NTAPI RtlNtStatusToDosError(
_In_ NTSTATUS Status
);
}
#endif
#include <winioctl.h>
typedef
struct
_WOF_FILE_EXTERNAL_BACKING_V1
{
WOF_EXTERNAL_INFO WofInfo;
FILE_PROVIDER_EXTERNAL_INFO_V1 FileProviderInfo;
} WOF_FILE_EXTERNAL_BACKING_V1, *PWOF_FILE_EXTERNAL_BACKING_V1;
HRESULT
WINAPI WofCompactFile(
_In_
HANDLE
FileHandle,
_In_
DWORD
CompactAlgorithm
)
{
if
(WofGetFileCompactAlgorithm(FileHandle) == CompactAlgorithm)
return
S_OK;
NTSTATUS status;
IO_STATUS_BLOCK IoStatus = { 0 };
WOF_FILE_EXTERNAL_BACKING_V1 WofFileInfo = { 0 };
WofFileInfo.WofInfo.Version = WOF_CURRENT_VERSION;
WofFileInfo.WofInfo.Provider = WOF_PROVIDER_FILE;
WofFileInfo.FileProviderInfo.Version = FILE_PROVIDER_CURRENT_VERSION;
WofFileInfo.FileProviderInfo.Algorithm = CompactAlgorithm;
WofFileInfo.FileProviderInfo.Flags = 0;
status = NtFsControlFile(
FileHandle, NULL, NULL, NULL, &IoStatus, FSCTL_SET_EXTERNAL_BACKING,
&WofFileInfo,
sizeof
(WofFileInfo), NULL, 0);
return
RtlNtStatusToDosError(status);
}
HRESULT
WINAPI WofUnCompactFile(
_In_
HANDLE
FileHandle
)
{
NTSTATUS status;
IO_STATUS_BLOCK IoStatus = { 0 };
status = NtFsControlFile(
FileHandle, NULL, NULL, NULL, &IoStatus,
FSCTL_DELETE_EXTERNAL_BACKING, NULL, 0, NULL, 0);
return
RtlNtStatusToDosError(status);
}
DWORD
WINAPI WofGetFileCompactAlgorithm(
_In_
HANDLE
FileHandle
)
{
NTSTATUS status;
IO_STATUS_BLOCK IoStatus = { 0 };
WOF_FILE_EXTERNAL_BACKING_V1 WofFileInfo = { 0 };
status = NtFsControlFile(
FileHandle, NULL, NULL, NULL, &IoStatus, FSCTL_GET_EXTERNAL_BACKING,
NULL, 0, &WofFileInfo,
sizeof
(WofFileInfo));
return
!NT_SUCCESS(status) ? -1 : WofFileInfo.FileProviderInfo.Algorithm;
}
HRESULT
WINAPI NTFSCompactFile(
_In_
HANDLE
FileHandle
)
{
NTSTATUS status;
IO_STATUS_BLOCK IoStatus = { 0 };
USHORT
Type = COMPRESSION_FORMAT_DEFAULT;
status = NtFsControlFile(
FileHandle, NULL, NULL, NULL, &IoStatus,
FSCTL_SET_COMPRESSION, &Type,
sizeof
(Type), NULL, 0);
return
RtlNtStatusToDosError(status);
}
HRESULT
WINAPI NTFSUnCompactFile(
_In_
HANDLE
FileHandle
)
{
NTSTATUS status;
IO_STATUS_BLOCK IoStatus = { 0 };
USHORT
Type = COMPRESSION_FORMAT_NONE;
status = NtFsControlFile(
FileHandle, NULL, NULL, NULL, &IoStatus,
FSCTL_SET_COMPRESSION, &Type,
sizeof
(Type), NULL, 0);
return
RtlNtStatusToDosError(status);
}