How to create a sparse file on NTFS? How to create a sparse file on NTFS? windows windows

How to create a sparse file on NTFS?


#include <windows.h>#include <string>#include <iostream>HANDLE CreateSparseFile(LPCTSTR lpSparseFileName){    // Use CreateFile as you would normally - Create file with whatever flags     //and File Share attributes that works for you    DWORD dwTemp;    HANDLE hSparseFile = CreateFile(lpSparseFileName,        GENERIC_READ | GENERIC_WRITE,        FILE_SHARE_READ | FILE_SHARE_WRITE,        NULL,        CREATE_ALWAYS,        FILE_ATTRIBUTE_NORMAL,        NULL);    if (hSparseFile == INVALID_HANDLE_VALUE)        return hSparseFile;    DeviceIoControl(hSparseFile,        FSCTL_SET_SPARSE,        NULL,        0,        NULL,        0,        &dwTemp,        NULL);    return hSparseFile;}DWORD SetSparseRange(HANDLE hSparseFile, LONGLONG start, LONGLONG size){    // Specify the starting and the ending address (not the size) of the     // sparse zero block    FILE_ZERO_DATA_INFORMATION fzdi;    fzdi.FileOffset.QuadPart = start;    fzdi.BeyondFinalZero.QuadPart = start + size;    // Mark the range as sparse zero block    DWORD dwTemp;    SetLastError(0);    BOOL bStatus = DeviceIoControl(hSparseFile,        FSCTL_SET_ZERO_DATA,        &fzdi,        sizeof(fzdi),        NULL,        0,        &dwTemp,        NULL);    if (bStatus) return 0; //Sucess    else {        DWORD e = GetLastError();        return(e); //return the error value    }}int _tmain(int argc, _TCHAR* argv[]){    if (argc < 3) {        std::cerr << "USAGE: SparseFile filename size" << std::endl;        return 1;    }    try {        ULONGLONG size = std::stoull(argv[2]);        HANDLE h = CreateSparseFile(argv[1]);        if (h == INVALID_HANDLE_VALUE) {            std::cerr << "Unable to create file" << std::endl;            return 1;        }        if (SetSparseRange(h, 0, size) != 0) {            std::cerr << "Unable to set sparse range" << std::endl;            return 1;        }        LARGE_INTEGER seek;        seek.QuadPart = size;        if (!SetFilePointerEx(h, seek, 0, 0)) {            std::cerr << "Unable to seek to desired offset" << std::endl;            return 1;        }        SetEndOfFile(h);        CloseHandle(h);    } catch (const std::exception &ex) {        std::cerr << ex.what() << std::endl;    }    return 0;}


You have to create a normal file, then use DeviceIoControl with FSCTL_SET_SPARSE to make it a sparse file.