(Das Binary benötigt MSVC Runtime 8.0.50727.762, ihr könnt's aber auch trivial selbstkompilieren da nicht plattformgebunden.)
Ein entsprechendes Tool zum Setzen von Valid- und Zero-Bereichen liefere ich noch nach. Generell geht das aber auch mit einem Komprimieren-Dekomprimieren-Zyklus.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define maxErrorMsgSize 256
#define hasFlag &
#define AND &&
__inline void PrintErrorMessageAndExit(wchar_t* msg) {
wprintf_s( L"Error: %s\n",
msg, maxErrorMsgSize
);
exit(EXIT_FAILURE);
}
__inline void PrintFormattedErrorMessageAndExit() {
wchar_t szMsg[maxErrorMsgSize]; // the size a guarantee by FormatMessage()
if ( ::FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
::GetLastError(),
0,
szMsg, sizeof(szMsg),
NULL)
)
PrintErrorMessageAndExit(szMsg);
}
int _tmain(const int argc, const _TCHAR* argv[]) {
if (argc == 2) {
HANDLE hFile;
BY_HANDLE_FILE_INFORMATION fileInformation;
wchar_t szPath[MAX_PATH],
szDrive[_MAX_DRIVE],
szDir[_MAX_DIR],
szFName[_MAX_FNAME],
szExt[_MAX_EXT],
szVolName[MAX_PATH],
szFSName[MAX_PATH];
LPWSTR pszName;
DWORD dwSN,
dwMaxLen,
dwVolFlags;
if (! ::GetFullPathName( argv[1],
MAX_PATH,
szPath,
&pszName)
)
PrintFormattedErrorMessageAndExit();
_wsplitpath_s(szPath,
szDrive, _MAX_DRIVE,
szDir, _MAX_DIR,
szFName, _MAX_FNAME,
szExt, _MAX_EXT);
size_t szDriveLen = wcsnlen_s(szDrive,_MAX_DRIVE);
if ( (szDriveLen > 0) AND (szDriveLen < _MAX_DRIVE) )
wcscat_s(szDrive, _MAX_DRIVE+1, L"\\"); // see the check above!
if (! ::GetVolumeInformation( szDrive,
szVolName,
MAX_PATH,
&dwSN,
&dwMaxLen,
&dwVolFlags,
szFSName,
MAX_PATH)
)
PrintFormattedErrorMessageAndExit();
if (! (dwVolFlags hasFlag FILE_SUPPORTS_SPARSE_FILES) )
PrintErrorMessageAndExit(L"This volume doesn't support sparse files.");
hFile = ::CreateFile( argv[1],
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
PrintFormattedErrorMessageAndExit();
if (! ::GetFileInformationByHandle( hFile,
&fileInformation)
)
PrintFormattedErrorMessageAndExit();
if (fileInformation.dwFileAttributes hasFlag FILE_ATTRIBUTE_SPARSE_FILE)
PrintErrorMessageAndExit(L"This file is sparse. Nothing to do.");
DWORD dwTemp;
if (! ::DeviceIoControl( hFile,
FSCTL_SET_SPARSE,
NULL,
0,
NULL,
0,
&dwTemp,
NULL)
)
PrintFormattedErrorMessageAndExit();
::CloseHandle(hFile);
} else
puts("Sets the sparse attribute on files\nUsage: SPARSE filename\n");
exit(EXIT_SUCCESS);
}

Hilfe
Neues Thema
Antworten


Nach oben

