diff --git a/reactos/include/rosrtl/sparse.h b/reactos/include/rosrtl/sparse.h new file mode 100644 index 00000000000..a0f27e21345 --- /dev/null +++ b/reactos/include/rosrtl/sparse.h @@ -0,0 +1,28 @@ +/* $Id: sparse.h,v 1.1 2004/09/15 18:57:01 weiden Exp $ + */ + +#ifndef ROSRTL_SPARSE_H__ +#define ROSRTL_SPARSE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +BOOL +STDCALL +SetFileSparse(HANDLE hFile); + +BOOL +STDCALL +ZeroFileData(HANDLE hFile, + PLARGE_INTEGER pliFileOffset, + PLARGE_INTEGER pliBeyondFinalZero); + +#ifdef __cplusplus +} +#endif + +#endif + +/* EOF */ diff --git a/reactos/lib/rosrtl/file/.cvsignore b/reactos/lib/rosrtl/file/.cvsignore new file mode 100644 index 00000000000..31dc3078b3a --- /dev/null +++ b/reactos/lib/rosrtl/file/.cvsignore @@ -0,0 +1,2 @@ +*.d +*.o diff --git a/reactos/lib/rosrtl/file/sparse.c b/reactos/lib/rosrtl/file/sparse.c new file mode 100644 index 00000000000..1228e3ff6a2 --- /dev/null +++ b/reactos/lib/rosrtl/file/sparse.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include + +/* + * Utility to convert a file to a sparse file + * + * IN HANDLE hFile -> Handle to the file to be converted + * + * Returns TRUE on success. + * Returns FALSE on failure, use GetLastError() to get extended error information. + */ +BOOL +STDCALL +SetFileSparse(HANDLE hFile) +{ + DWORD BytesRet; + return DeviceIoControl(hFile, + FSCTL_SET_SPARSE, + NULL, + 0, + NULL, + 0, + &BytesRet, + NULL) != 0; +} + + +/* + * Utility to fill a specified range of a file with zeroes. + * + * IN HANDLE hFile -> Handle to the file. + * IN PLARGE_INTEGER pliFileOffset -> Points to a LARGE_INTEGER structure that indicates the file offset of the start of the range in bytes. + * IN PLARGE_INTEGER pliBeyondFinalZero -> Points to a LARGE_INTEGER structure that indicates the the offset to the first byte beyond the last zeroed byte. + * + * Returns TRUE on success. + * Returns FALSE on failure, use GetLastError() to get extended error information. + */ +BOOL +STDCALL +ZeroFileData(HANDLE hFile, + PLARGE_INTEGER pliFileOffset, + PLARGE_INTEGER pliBeyondFinalZero) +{ + DWORD BytesRet; + FILE_ZERO_DATA_INFORMATION fzdi; + + if(!pliFileOffset || !pliBeyondFinalZero) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + fzdi.FileOffset = *pliFileOffset; + fzdi.BeyondFinalZero = *pliBeyondFinalZero; + + return DeviceIoControl(hFile, + FSCTL_SET_ZERO_DATA, + &fzdi, + sizeof(FILE_ZERO_DATA_INFORMATION), + NULL, + 0, + &BytesRet, + NULL) != 0; +} + + +/* + * Utility to determine the allocated ranges of a sparse file + * + * IN HANDLE hFile -> Handle to the file. + * IN PLARGE_INTEGER pliFileOffset -> Points to a LARGE_INTEGER structure that indicates the portion of the file to search for allocated ranges. + * IN PLARGE_INTEGER pliLength -> Points to a LARGE_INTEGER structure that indicates it's size. + * OUT PFILE_ALLOCATED_RANGE_BUFFER lpAllocatedRanges -> Points to a buffer that receives an array of FILE_ALLOCATED_RANGE_BUFFER structures. + * IN DWORD dwBufferSize -> Size of the output buffer. + * + * Returns a nonzero value on success. + * Returns zero on failure, use GetLastError() to get extended error information. + */ +DWORD +STDCALL +QueryAllocatedFileRanges(HANDLE hFile, + PLARGE_INTEGER pliFileOffset, + PLARGE_INTEGER pliLength, + PFILE_ALLOCATED_RANGE_BUFFER lpAllocatedRanges, + DWORD dwBufferSize) +{ + DWORD BytesRet; + FILE_ALLOCATED_RANGE_BUFFER farb; + + if(!pliFileOffset || !pliLength || !lpAllocatedRanges || !dwBufferSize) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + farb.FileOffset = *pliFileOffset; + farb.Length = *pliLength; + + if(DeviceIoControl(hFile, + FSCTL_QUERY_ALLOCATED_RANGES, + &farb, + sizeof(FILE_ALLOCATED_RANGE_BUFFER), + lpAllocatedRanges, + dwBufferSize, + &BytesRet, + NULL)) + { + return BytesRet; + } + + return 0; +} + diff --git a/reactos/lib/rosrtl/makefile b/reactos/lib/rosrtl/makefile index 9e2f86f5f9a..79bbb9a049e 100644 --- a/reactos/lib/rosrtl/makefile +++ b/reactos/lib/rosrtl/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.15 2004/09/10 23:29:07 sedwards Exp $ +# $Id: makefile,v 1.16 2004/09/15 18:57:01 weiden Exp $ PATH_TO_TOP = ../.. @@ -29,6 +29,9 @@ MISC_OBJECTS = \ misc/logfont.o \ misc/qsort.o +FILE_OBJECTS = \ + file/sparse.o + include $(PATH_TO_TOP)/config include makefile.$(ARCH) @@ -40,7 +43,7 @@ TARGET_NAME = rosrtl TARGET_CFLAGS = -D__USE_W32API -Wall -Werror TARGET_OBJECTS = $(THREAD_OBJECTS) $(MISC_OBJECTS) $(STRING_OBJECTS) \ - $(REGISTRY_OBJECTS) + $(REGISTRY_OBJECTS) $(FILE_OBJECTS) DEP_OBJECTS = $(TARGET_OBJECTS) diff --git a/reactos/w32api/include/ddk/ntifs.h b/reactos/w32api/include/ddk/ntifs.h index 3b1de2b1085..d38d9a3129e 100644 --- a/reactos/w32api/include/ddk/ntifs.h +++ b/reactos/w32api/include/ddk/ntifs.h @@ -1274,6 +1274,18 @@ typedef struct _FILE_TRACKING_INFORMATION { CHAR ObjectInformation[1]; } FILE_TRACKING_INFORMATION, *PFILE_TRACKING_INFORMATION; +#if (VER_PRODUCTBUILD >= 2195) +typedef struct _FILE_ZERO_DATA_INFORMATION { + LARGE_INTEGER FileOffset; + LARGE_INTEGER BeyondFinalZero; +} FILE_ZERO_DATA_INFORMATION, *PFILE_ZERO_DATA_INFORMATION; + +typedef struct FILE_ALLOCATED_RANGE_BUFFER { + LARGE_INTEGER FileOffset; + LARGE_INTEGER Length; +} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER; +#endif /* (VER_PRODUCTBUILD >= 2195) */ + typedef struct _FSRTL_COMMON_FCB_HEADER { CSHORT NodeTypeCode; CSHORT NodeByteSize;