ReactOS 0.4.17-dev-1133-gc25e4fd
ntfslib.h File Reference
#include <stdlib.h>
#include <ndk/iofuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/rtlfuncs.h>
#include <ndk/umtypes.h>
#include <fmifs/fmifs.h>
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for ntfslib.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _NTFS_LAYOUT
 
struct  _NTFS_FORMAT_DATA
 
struct  _BIOS_PARAMETERS_BLOCK
 
struct  _EXTENDED_BIOS_PARAMETERS_BLOCK
 
struct  _BOOT_SECTOR
 
struct  _RECORD_HEADER
 
struct  _FILE_RECORD_HEADER
 
struct  _ATTR_RECORD
 
struct  _STANDARD_INFORMATION
 
struct  _FILENAME_ATTRIBUTE
 
struct  _VOLUME_INFORMATION_ATTRIBUTE
 
struct  _INDEX_NODE_HEADER
 
struct  _INDEX_ROOT_ATTRIBUTE
 
struct  _INDEX_ENTRY_HEADER
 

Macros

#define KeQuerySystemTime(t)   NtfsGetSystemTimeAsFileTime((LPFILETIME)(t));
 
#define FREE(p)   if (p) RtlFreeHeap(RtlGetProcessHeap(), 0, p);
 
#define FIRST_ATTRIBUTE(fr)   ((PATTR_RECORD)((ULONG_PTR)fr + fr->FirstAttributeOffset))
 
#define NEXT_ATTRIBUTE(attr)   ((PATTR_RECORD)((ULONG_PTR)(attr) + (attr)->Length))
 
#define ARR_SIZE(arr)   (sizeof(arr) / sizeof(arr[0]))
 
#define MB_TO_B(x)   (x * 1024)
 
#define GET_BYTE(val, n)   (((val) >> (8*(n))) & 0xFF)
 
#define GET_BYTE_FROM_END(val, n)   (((val) >> (8*(sizeof((val)) - 1 - (n)))) & 0xFF)
 
#define BSWAP16(val)    ( (((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00) )
 
#define BSWAP32(val)
 
#define BSWAP64(val)
 
#define DISK_HANDLE   (NtfsFormatData.DiskHandle)
 
#define DISK_GEO   (NtfsFormatData.DiskGeometry)
 
#define DISK_LEN   (NtfsFormatData.LengthInformation)
 
#define LABEL   (NtfsFormatData.Label)
 
#define LAYOUT   (NtfsFormatData.Layout)
 
#define BYTES_PER_SECTOR   ((ULONG)DISK_GEO->BytesPerSector)
 
#define SECTORS_PER_TRACK   ((ULONG)DISK_GEO->SectorsPerTrack)
 
#define SECTORS_PER_CLUSTER   (LAYOUT.SectorsPerCluster)
 
#define BYTES_PER_CLUSTER   (LAYOUT.BytesPerCluster)
 
#define CLUSTER_COUNT   (LAYOUT.ClusterCount)
 
#define TOTAL_SECTORS   (LAYOUT.TotalSectors)
 
#define IS_HARD_DRIVE   (DISK_GEO->MediaType == FixedMedia)
 
#define DISK_HEADS   0xFF
 
#define OEM_ID   BSWAP64(0x4E54465320202020)
 
#define EBPB_HEADER   BSWAP32(0x80008000)
 
#define BOOT_SECTOR_END   BSWAP16(0x55AA)
 
#define MFT_RECORD_SIZE   1024
 
#define INDEX_RECORD_SIZE   4096
 
#define MFT_RESERVED_RECORDS   16
 
#define MFT_MIRR_COUNT   4
 
#define NTFS_MAJOR_VERSION   3
 
#define NTFS_MINOR_VERSION   1
 
#define NTFS_SECURITY_ID   0x100
 
#define FILE_RECORD_MAGIC   BSWAP32(0x46494C45)
 
#define INDX_RECORD_MAGIC   BSWAP32(0x494E4458)
 
#define ATTR_RECORD_ALIGNMENT   8
 
#define VALUE_OFFSET_ALIGNMENT   4
 
#define DATA_RUN_ALIGNMENT   4
 
#define FILE_RECORD_END   0x11477982
 
#define FILE_NAME_POSIX   0
 
#define FILE_NAME_WIN32   1
 
#define FILE_NAME_DOS   2
 
#define FILE_NAME_WIN32_AND_DOS   3
 
#define FILE_TYPE_READ_ONLY   0x1
 
#define FILE_TYPE_HIDDEN   0x2
 
#define FILE_TYPE_SYSTEM   0x4
 
#define FILE_TYPE_ARCHIVE   0x20
 
#define FILE_TYPE_REPARSE   0x400
 
#define FILE_TYPE_COMPRESSED   0x800
 
#define FILE_TYPE_DIRECTORY   0x10000000
 
#define RA_INDEXED   0x01
 
#define RA_METAFILES_ATTRIBUTES   (FILE_TYPE_SYSTEM | FILE_TYPE_HIDDEN)
 
#define RA_HEADER_LENGTH   (FIELD_OFFSET(ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR))
 
#define COLLATION_BINARY   0x00
 
#define COLLATION_FILE_NAME   0x01
 
#define COLLATION_NTOFS_ULONG   0x10
 
#define COLLATION_NTOFS_SECURITY_HASH   0x12
 
#define NONRES_HEADER_SIZE   0x40
 
#define NONRES_HEADER_SIZE_SPARSE   0x48
 
#define INDEX_ENTRY_NODE   0x01
 
#define INDEX_ENTRY_END   0x02
 
#define INDEX_NODE_LARGE   0x01
 
#define RECORD_SEQUENCE(rec)   ((USHORT)(((rec) >= 1 && (rec) <= 15) ? (rec) : 1))
 
#define MFT_REFERENCE(rec)   (((ULONGLONG)(rec)) | ((ULONGLONG)RECORD_SEQUENCE(rec) << 48))
 
#define METAFILE_MFT   0
 
#define METAFILE_MFTMIRR   1
 
#define METAFILE_LOGFILE   2
 
#define METAFILE_VOLUME   3
 
#define METAFILE_ATTRDEF   4
 
#define METAFILE_ROOT   5
 
#define METAFILE_BITMAP   6
 
#define METAFILE_BOOT   7
 
#define METAFILE_BADCLUS   8
 
#define METAFILE_SECURE   9
 
#define METAFILE_UPCASE   10
 
#define METAFILE_EXTEND   11
 
#define METAFILE_FIRST_USER_FILE   16
 
#define RUN_LIST_ENTRY_HEADER_SIZE   1
 
#define RUN_LIST_ENTRY_SIZE   8
 
#define NTFS_SDS_MIRROR   0x40000
 
#define HIDDEN_SECTORS   (NtfsFormatData.HiddenSectors)
 
#define FORMAT_TIME   (NtfsFormatData.FormatTime)
 

Typedefs

typedef struct _NTFS_LAYOUT NTFS_LAYOUT
 
typedef struct _NTFS_LAYOUT * PNTFS_LAYOUT
 
typedef struct _NTFS_FORMAT_DATA NTFS_FORMAT_DATA
 
typedef struct _BIOS_PARAMETERS_BLOCK BIOS_PARAMETERS_BLOCK
 
typedef struct _BIOS_PARAMETERS_BLOCK * PBIOS_PARAMETERS_BLOCK
 
typedef struct _EXTENDED_BIOS_PARAMETERS_BLOCK EXTENDED_BIOS_PARAMETERS_BLOCK
 
typedef struct _EXTENDED_BIOS_PARAMETERS_BLOCK * PEXTENDED_BIOS_PARAMETERS_BLOCK
 
typedef struct _BOOT_SECTOR BOOT_SECTOR
 
typedef struct _BOOT_SECTOR * PBOOT_SECTOR
 
typedef struct _RECORD_HEADER RECORD_HEADER
 
typedef struct _RECORD_HEADER * PRECORD_HEADER
 
typedef enum _MFT_RECORD_FLAGS MFT_RECORD_FLAGS
 
typedef enum _MFT_RECORD_FLAGS * PMFT_RECORD_FLAGS
 
typedef struct _FILE_RECORD_HEADER FILE_RECORD_HEADER
 
typedef struct _FILE_RECORD_HEADER * PFILE_RECORD_HEADER
 
typedef enum _ATTR_FLAGS ATTR_FLAGS
 
typedef enum _ATTR_FLAGS * PATTR_FLAGS
 
typedef enum _ATTRIBUTE_TYPE ATTRIBUTE_TYPE
 
typedef enum _ATTRIBUTE_TYPE * PATTRIBUTE_TYPE
 
typedef struct _ATTR_RECORD ATTR_RECORD
 
typedef struct _ATTR_RECORD * PATTR_RECORD
 
typedef struct _STANDARD_INFORMATION STANDARD_INFORMATION
 
typedef struct _STANDARD_INFORMATION * PSTANDARD_INFORMATION
 
typedef struct _FILENAME_ATTRIBUTE FILENAME_ATTRIBUTE
 
typedef struct _FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
 
typedef struct _VOLUME_INFORMATION_ATTRIBUTE VOLUME_INFORMATION_ATTRIBUTE
 
typedef struct _VOLUME_INFORMATION_ATTRIBUTE * PVOLUME_INFORMATION_ATTRIBUTE
 
typedef struct _INDEX_NODE_HEADER INDEX_NODE_HEADER
 
typedef struct _INDEX_NODE_HEADER * PINDEX_NODE_HEADER
 
typedef struct _INDEX_ROOT_ATTRIBUTE INDEX_ROOT_ATTRIBUTE
 
typedef struct _INDEX_ROOT_ATTRIBUTE * PINDEX_ROOT_ATTRIBUTE
 
typedef struct _INDEX_ENTRY_HEADER INDEX_ENTRY_HEADER
 
typedef struct _INDEX_ENTRY_HEADER * PINDEX_ENTRY_HEADER
 

Enumerations

enum  _MFT_RECORD_FLAGS {
  MFT_RECORD_NOT_USED = 0x0000 , MFT_RECORD_IN_USE = 0x0001 , MFT_RECORD_IS_DIRECTORY = 0x0002 , MFT_RECORD_UNKNOWN1 = 0x0004 ,
  MFT_RECORD_VIEW_INDEX = 0x0008
}
 
enum  _ATTR_FLAGS { ATTR_IS_COMPRESSED = 0x1 , ATTR_IS_ENCRYPTED = 0x4000 , ATTR_IS_SPARSE = 0x8000 }
 
enum  _ATTRIBUTE_TYPE {
  AttributeStandardInformation = 0x10 , AttributeAttributeList = 0x20 , AttributeFileName = 0x30 , AttributeObjectId = 0x40 ,
  AttributeSecurityDescriptor = 0x50 , AttributeVolumeName = 0x60 , AttributeVolumeInformation = 0x70 , AttributeData = 0x80 ,
  AttributeIndexRoot = 0x90 , AttributeIndexAllocation = 0xA0 , AttributeBitmap = 0xB0 , AttributeReparsePoint = 0xC0 ,
  AttributeEAInformation = 0xD0 , AttributeEA = 0xE0 , AttributePropertySet = 0xF0 , AttributeLoggedUtilityStream = 0x100 ,
  AttributeEnd = 0xFFFFFFFF
}
 

Functions

ULONG NTAPI NtGetTickCount (VOID)
 
VOID NtfsGetSystemTimeAsFileTime (OUT PFILETIME lpFileTime)
 
BYTE GetSectorsPerCluster (VOID)
 
NTSTATUS ComputeLayout (IN ULONG ClusterSize)
 
NTSTATUS WriteBootSector (VOID)
 
NTSTATUS WriteMetafiles (VOID)
 

Variables

NTFS_FORMAT_DATA NtfsFormatData
 

Macro Definition Documentation

◆ ARR_SIZE

#define ARR_SIZE (   arr)    (sizeof(arr) / sizeof(arr[0]))

Definition at line 34 of file ntfslib.h.

◆ ATTR_RECORD_ALIGNMENT

#define ATTR_RECORD_ALIGNMENT   8

Definition at line 117 of file ntfslib.h.

◆ BOOT_SECTOR_END

#define BOOT_SECTOR_END   BSWAP16(0x55AA)

Definition at line 88 of file ntfslib.h.

◆ BSWAP16

#define BSWAP16 (   val)     ( (((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00) )

Definition at line 45 of file ntfslib.h.

◆ BSWAP32

#define BSWAP32 (   val)
Value:
( (((val) >> 24) & 0x000000FF) | (((val) >> 8) & 0x0000FF00) | \
(((val) << 8) & 0x00FF0000) | (((val) << 24) & 0xFF000000) )
GLuint GLfloat * val
Definition: glext.h:7180

Definition at line 48 of file ntfslib.h.

◆ BSWAP64

#define BSWAP64 (   val)
Value:
( (((val) >> 56) & 0x00000000000000FF) | (((val) >> 40) & 0x000000000000FF00) | \
(((val) >> 24) & 0x0000000000FF0000) | (((val) >> 8) & 0x00000000FF000000) | \
(((val) << 8) & 0x000000FF00000000) | (((val) << 24) & 0x0000FF0000000000) | \
(((val) << 40) & 0x00FF000000000000) | (((val) << 56) & 0xFF00000000000000) )

Definition at line 52 of file ntfslib.h.

◆ BYTES_PER_CLUSTER

#define BYTES_PER_CLUSTER   (LAYOUT.BytesPerCluster)

Definition at line 72 of file ntfslib.h.

◆ BYTES_PER_SECTOR

#define BYTES_PER_SECTOR   ((ULONG)DISK_GEO->BytesPerSector)

Definition at line 67 of file ntfslib.h.

◆ CLUSTER_COUNT

#define CLUSTER_COUNT   (LAYOUT.ClusterCount)

Definition at line 73 of file ntfslib.h.

◆ COLLATION_BINARY

#define COLLATION_BINARY   0x00

Definition at line 151 of file ntfslib.h.

◆ COLLATION_FILE_NAME

#define COLLATION_FILE_NAME   0x01

Definition at line 152 of file ntfslib.h.

◆ COLLATION_NTOFS_SECURITY_HASH

#define COLLATION_NTOFS_SECURITY_HASH   0x12

Definition at line 154 of file ntfslib.h.

◆ COLLATION_NTOFS_ULONG

#define COLLATION_NTOFS_ULONG   0x10

Definition at line 153 of file ntfslib.h.

◆ DATA_RUN_ALIGNMENT

#define DATA_RUN_ALIGNMENT   4

Definition at line 125 of file ntfslib.h.

◆ DISK_GEO

#define DISK_GEO   (NtfsFormatData.DiskGeometry)

Definition at line 62 of file ntfslib.h.

◆ DISK_HANDLE

#define DISK_HANDLE   (NtfsFormatData.DiskHandle)

Definition at line 61 of file ntfslib.h.

◆ DISK_HEADS

#define DISK_HEADS   0xFF

Definition at line 81 of file ntfslib.h.

◆ DISK_LEN

#define DISK_LEN   (NtfsFormatData.LengthInformation)

Definition at line 63 of file ntfslib.h.

◆ EBPB_HEADER

#define EBPB_HEADER   BSWAP32(0x80008000)

Definition at line 87 of file ntfslib.h.

◆ FILE_NAME_DOS

#define FILE_NAME_DOS   2

Definition at line 133 of file ntfslib.h.

◆ FILE_NAME_POSIX

#define FILE_NAME_POSIX   0

Definition at line 131 of file ntfslib.h.

◆ FILE_NAME_WIN32

#define FILE_NAME_WIN32   1

Definition at line 132 of file ntfslib.h.

◆ FILE_NAME_WIN32_AND_DOS

#define FILE_NAME_WIN32_AND_DOS   3

Definition at line 134 of file ntfslib.h.

◆ FILE_RECORD_END

#define FILE_RECORD_END   0x11477982

Definition at line 129 of file ntfslib.h.

◆ FILE_RECORD_MAGIC

#define FILE_RECORD_MAGIC   BSWAP32(0x46494C45)

Definition at line 112 of file ntfslib.h.

◆ FILE_TYPE_ARCHIVE

#define FILE_TYPE_ARCHIVE   0x20

Definition at line 139 of file ntfslib.h.

◆ FILE_TYPE_COMPRESSED

#define FILE_TYPE_COMPRESSED   0x800

Definition at line 141 of file ntfslib.h.

◆ FILE_TYPE_DIRECTORY

#define FILE_TYPE_DIRECTORY   0x10000000

Definition at line 142 of file ntfslib.h.

◆ FILE_TYPE_HIDDEN

#define FILE_TYPE_HIDDEN   0x2

Definition at line 137 of file ntfslib.h.

◆ FILE_TYPE_READ_ONLY

#define FILE_TYPE_READ_ONLY   0x1

Definition at line 136 of file ntfslib.h.

◆ FILE_TYPE_REPARSE

#define FILE_TYPE_REPARSE   0x400

Definition at line 140 of file ntfslib.h.

◆ FILE_TYPE_SYSTEM

#define FILE_TYPE_SYSTEM   0x4

Definition at line 138 of file ntfslib.h.

◆ FIRST_ATTRIBUTE

#define FIRST_ATTRIBUTE (   fr)    ((PATTR_RECORD)((ULONG_PTR)fr + fr->FirstAttributeOffset))

Definition at line 31 of file ntfslib.h.

◆ FORMAT_TIME

#define FORMAT_TIME   (NtfsFormatData.FormatTime)

Definition at line 264 of file ntfslib.h.

◆ FREE

#define FREE (   p)    if (p) RtlFreeHeap(RtlGetProcessHeap(), 0, p);

Definition at line 29 of file ntfslib.h.

◆ GET_BYTE

#define GET_BYTE (   val,
  n 
)    (((val) >> (8*(n))) & 0xFF)

Definition at line 41 of file ntfslib.h.

◆ GET_BYTE_FROM_END

#define GET_BYTE_FROM_END (   val,
  n 
)    (((val) >> (8*(sizeof((val)) - 1 - (n)))) & 0xFF)

Definition at line 43 of file ntfslib.h.

◆ HIDDEN_SECTORS

#define HIDDEN_SECTORS   (NtfsFormatData.HiddenSectors)

Definition at line 262 of file ntfslib.h.

◆ INDEX_ENTRY_END

#define INDEX_ENTRY_END   0x02

Definition at line 164 of file ntfslib.h.

◆ INDEX_ENTRY_NODE

#define INDEX_ENTRY_NODE   0x01

Definition at line 163 of file ntfslib.h.

◆ INDEX_NODE_LARGE

#define INDEX_NODE_LARGE   0x01

Definition at line 166 of file ntfslib.h.

◆ INDEX_RECORD_SIZE

#define INDEX_RECORD_SIZE   4096

Definition at line 94 of file ntfslib.h.

◆ INDX_RECORD_MAGIC

#define INDX_RECORD_MAGIC   BSWAP32(0x494E4458)

Definition at line 113 of file ntfslib.h.

◆ IS_HARD_DRIVE

#define IS_HARD_DRIVE   (DISK_GEO->MediaType == FixedMedia)

Definition at line 76 of file ntfslib.h.

◆ KeQuerySystemTime

#define KeQuerySystemTime (   t)    NtfsGetSystemTimeAsFileTime((LPFILETIME)(t));

Definition at line 27 of file ntfslib.h.

◆ LABEL

Definition at line 64 of file ntfslib.h.

◆ LAYOUT

#define LAYOUT   (NtfsFormatData.Layout)

Definition at line 65 of file ntfslib.h.

◆ MB_TO_B

#define MB_TO_B (   x)    (x * 1024)

Definition at line 39 of file ntfslib.h.

◆ METAFILE_ATTRDEF

#define METAFILE_ATTRDEF   4

Definition at line 184 of file ntfslib.h.

◆ METAFILE_BADCLUS

#define METAFILE_BADCLUS   8

Definition at line 188 of file ntfslib.h.

◆ METAFILE_BITMAP

#define METAFILE_BITMAP   6

Definition at line 186 of file ntfslib.h.

◆ METAFILE_BOOT

#define METAFILE_BOOT   7

Definition at line 187 of file ntfslib.h.

◆ METAFILE_EXTEND

#define METAFILE_EXTEND   11

Definition at line 191 of file ntfslib.h.

◆ METAFILE_FIRST_USER_FILE

#define METAFILE_FIRST_USER_FILE   16

Definition at line 192 of file ntfslib.h.

◆ METAFILE_LOGFILE

#define METAFILE_LOGFILE   2

Definition at line 182 of file ntfslib.h.

◆ METAFILE_MFT

#define METAFILE_MFT   0

Definition at line 180 of file ntfslib.h.

◆ METAFILE_MFTMIRR

#define METAFILE_MFTMIRR   1

Definition at line 181 of file ntfslib.h.

◆ METAFILE_ROOT

#define METAFILE_ROOT   5

Definition at line 185 of file ntfslib.h.

◆ METAFILE_SECURE

#define METAFILE_SECURE   9

Definition at line 189 of file ntfslib.h.

◆ METAFILE_UPCASE

#define METAFILE_UPCASE   10

Definition at line 190 of file ntfslib.h.

◆ METAFILE_VOLUME

#define METAFILE_VOLUME   3

Definition at line 183 of file ntfslib.h.

◆ MFT_MIRR_COUNT

#define MFT_MIRR_COUNT   4

Definition at line 101 of file ntfslib.h.

◆ MFT_RECORD_SIZE

#define MFT_RECORD_SIZE   1024

Definition at line 93 of file ntfslib.h.

◆ MFT_REFERENCE

#define MFT_REFERENCE (   rec)    (((ULONGLONG)(rec)) | ((ULONGLONG)RECORD_SEQUENCE(rec) << 48))

Definition at line 177 of file ntfslib.h.

◆ MFT_RESERVED_RECORDS

#define MFT_RESERVED_RECORDS   16

Definition at line 97 of file ntfslib.h.

◆ NEXT_ATTRIBUTE

#define NEXT_ATTRIBUTE (   attr)    ((PATTR_RECORD)((ULONG_PTR)(attr) + (attr)->Length))

Definition at line 32 of file ntfslib.h.

◆ NONRES_HEADER_SIZE

#define NONRES_HEADER_SIZE   0x40

Definition at line 159 of file ntfslib.h.

◆ NONRES_HEADER_SIZE_SPARSE

#define NONRES_HEADER_SIZE_SPARSE   0x48

Definition at line 160 of file ntfslib.h.

◆ NTFS_MAJOR_VERSION

#define NTFS_MAJOR_VERSION   3

Definition at line 106 of file ntfslib.h.

◆ NTFS_MINOR_VERSION

#define NTFS_MINOR_VERSION   1

Definition at line 107 of file ntfslib.h.

◆ NTFS_SDS_MIRROR

#define NTFS_SDS_MIRROR   0x40000

Definition at line 245 of file ntfslib.h.

◆ NTFS_SECURITY_ID

#define NTFS_SECURITY_ID   0x100

Definition at line 110 of file ntfslib.h.

◆ OEM_ID

#define OEM_ID   BSWAP64(0x4E54465320202020)

Definition at line 86 of file ntfslib.h.

◆ RA_HEADER_LENGTH

Definition at line 148 of file ntfslib.h.

◆ RA_INDEXED

#define RA_INDEXED   0x01

Definition at line 145 of file ntfslib.h.

◆ RA_METAFILES_ATTRIBUTES

#define RA_METAFILES_ATTRIBUTES   (FILE_TYPE_SYSTEM | FILE_TYPE_HIDDEN)

Definition at line 147 of file ntfslib.h.

◆ RECORD_SEQUENCE

#define RECORD_SEQUENCE (   rec)    ((USHORT)(((rec) >= 1 && (rec) <= 15) ? (rec) : 1))

Definition at line 173 of file ntfslib.h.

◆ RUN_LIST_ENTRY_HEADER_SIZE

#define RUN_LIST_ENTRY_HEADER_SIZE   1

Definition at line 194 of file ntfslib.h.

◆ RUN_LIST_ENTRY_SIZE

#define RUN_LIST_ENTRY_SIZE   8

Definition at line 195 of file ntfslib.h.

◆ SECTORS_PER_CLUSTER

#define SECTORS_PER_CLUSTER   (LAYOUT.SectorsPerCluster)

Definition at line 71 of file ntfslib.h.

◆ SECTORS_PER_TRACK

#define SECTORS_PER_TRACK   ((ULONG)DISK_GEO->SectorsPerTrack)

Definition at line 68 of file ntfslib.h.

◆ TOTAL_SECTORS

#define TOTAL_SECTORS   (LAYOUT.TotalSectors)

Definition at line 74 of file ntfslib.h.

◆ VALUE_OFFSET_ALIGNMENT

#define VALUE_OFFSET_ALIGNMENT   4

Definition at line 121 of file ntfslib.h.

Typedef Documentation

◆ ATTR_FLAGS

◆ ATTR_RECORD

◆ ATTRIBUTE_TYPE

◆ BIOS_PARAMETERS_BLOCK

◆ BOOT_SECTOR

◆ EXTENDED_BIOS_PARAMETERS_BLOCK

◆ FILE_RECORD_HEADER

◆ FILENAME_ATTRIBUTE

◆ INDEX_ENTRY_HEADER

◆ INDEX_NODE_HEADER

◆ INDEX_ROOT_ATTRIBUTE

◆ MFT_RECORD_FLAGS

◆ NTFS_FORMAT_DATA

◆ NTFS_LAYOUT

◆ PATTR_FLAGS

◆ PATTR_RECORD

◆ PATTRIBUTE_TYPE

◆ PBIOS_PARAMETERS_BLOCK

◆ PBOOT_SECTOR

◆ PEXTENDED_BIOS_PARAMETERS_BLOCK

◆ PFILE_RECORD_HEADER

◆ PFILENAME_ATTRIBUTE

◆ PINDEX_ENTRY_HEADER

◆ PINDEX_NODE_HEADER

◆ PINDEX_ROOT_ATTRIBUTE

◆ PMFT_RECORD_FLAGS

◆ PNTFS_LAYOUT

◆ PRECORD_HEADER

◆ PSTANDARD_INFORMATION

◆ PVOLUME_INFORMATION_ATTRIBUTE

◆ RECORD_HEADER

◆ STANDARD_INFORMATION

◆ VOLUME_INFORMATION_ATTRIBUTE

Enumeration Type Documentation

◆ _ATTR_FLAGS

Enumerator
ATTR_IS_COMPRESSED 
ATTR_IS_ENCRYPTED 
ATTR_IS_SPARSE 

Definition at line 348 of file ntfslib.h.

349{
350 ATTR_IS_COMPRESSED = 0x1,
351 ATTR_IS_ENCRYPTED = 0x4000,
352 ATTR_IS_SPARSE = 0x8000
enum _ATTR_FLAGS ATTR_FLAGS
@ ATTR_IS_ENCRYPTED
Definition: ntfslib.h:351
@ ATTR_IS_COMPRESSED
Definition: ntfslib.h:350
@ ATTR_IS_SPARSE
Definition: ntfslib.h:352
enum _ATTR_FLAGS * PATTR_FLAGS

◆ _ATTRIBUTE_TYPE

Enumerator
AttributeStandardInformation 
AttributeAttributeList 
AttributeFileName 
AttributeObjectId 
AttributeSecurityDescriptor 
AttributeVolumeName 
AttributeVolumeInformation 
AttributeData 
AttributeIndexRoot 
AttributeIndexAllocation 
AttributeBitmap 
AttributeReparsePoint 
AttributeEAInformation 
AttributeEA 
AttributePropertySet 
AttributeLoggedUtilityStream 
AttributeEnd 

Definition at line 355 of file ntfslib.h.

356{
359 AttributeFileName = 0x30,
360 AttributeObjectId = 0x40,
362 AttributeVolumeName = 0x60,
364 AttributeData = 0x80,
365 AttributeIndexRoot = 0x90,
367 AttributeBitmap = 0xB0,
370 AttributeEA = 0xE0,
373 AttributeEnd = 0xFFFFFFFF
@ AttributeVolumeName
Definition: ntfslib.h:362
@ AttributeEnd
Definition: ntfslib.h:373
@ AttributeIndexRoot
Definition: ntfslib.h:365
@ AttributePropertySet
Definition: ntfslib.h:371
@ AttributeReparsePoint
Definition: ntfslib.h:368
@ AttributeFileName
Definition: ntfslib.h:359
@ AttributeEAInformation
Definition: ntfslib.h:369
@ AttributeStandardInformation
Definition: ntfslib.h:357
@ AttributeEA
Definition: ntfslib.h:370
@ AttributeAttributeList
Definition: ntfslib.h:358
@ AttributeVolumeInformation
Definition: ntfslib.h:363
@ AttributeSecurityDescriptor
Definition: ntfslib.h:361
@ AttributeIndexAllocation
Definition: ntfslib.h:366
@ AttributeObjectId
Definition: ntfslib.h:360
@ AttributeLoggedUtilityStream
Definition: ntfslib.h:372
@ AttributeData
Definition: ntfslib.h:364
@ AttributeBitmap
Definition: ntfslib.h:367
enum _ATTRIBUTE_TYPE * PATTRIBUTE_TYPE
enum _ATTRIBUTE_TYPE ATTRIBUTE_TYPE

◆ _MFT_RECORD_FLAGS

Enumerator
MFT_RECORD_NOT_USED 
MFT_RECORD_IN_USE 
MFT_RECORD_IS_DIRECTORY 
MFT_RECORD_UNKNOWN1 
MFT_RECORD_VIEW_INDEX 

Definition at line 321 of file ntfslib.h.

322{
323 MFT_RECORD_NOT_USED = 0x0000,
324 MFT_RECORD_IN_USE = 0x0001,
326 MFT_RECORD_UNKNOWN1 = 0x0004, // Set on $Extend children by Windows
327 MFT_RECORD_VIEW_INDEX = 0x0008 // File carries a view index (e.g. $Secure)
enum _MFT_RECORD_FLAGS * PMFT_RECORD_FLAGS
@ MFT_RECORD_NOT_USED
Definition: ntfslib.h:323
@ MFT_RECORD_VIEW_INDEX
Definition: ntfslib.h:327
@ MFT_RECORD_IS_DIRECTORY
Definition: ntfslib.h:325
@ MFT_RECORD_IN_USE
Definition: ntfslib.h:324
@ MFT_RECORD_UNKNOWN1
Definition: ntfslib.h:326
enum _MFT_RECORD_FLAGS MFT_RECORD_FLAGS

Function Documentation

◆ ComputeLayout()

NTSTATUS ComputeLayout ( IN ULONG  ClusterSize)

Definition at line 99 of file ntfslib.c.

100{
102 ULONGLONG VolumeBytes;
103 ULONGLONG VolumeSectors;
104 ULONG Spc;
105 ULONG C;
106 ULONGLONG Lcn;
107
108 if (Bps == 0)
110
111 VolumeBytes = DISK_LEN->Length.QuadPart;
112 VolumeSectors = VolumeBytes / Bps;
113
114 // Need at least the backup boot sector plus something to format.
115 if (VolumeSectors < 2)
117
118 // Sectors per cluster
119 if (ClusterSize != 0)
120 {
121 Spc = ClusterSize / Bps;
122 if (Spc == 0)
123 Spc = 1;
124 }
125 else
126 {
127 Spc = GetSectorsPerCluster();
128 }
129
130 LAYOUT.SectorsPerCluster = Spc;
131 LAYOUT.BytesPerCluster = Spc * Bps;
132 C = LAYOUT.BytesPerCluster;
133
134 // The last sector holds the backup boot sector and is not addressable.
135 LAYOUT.TotalSectors = VolumeSectors - 1;
136 LAYOUT.ClusterCount = LAYOUT.TotalSectors / Spc;
137 if (LAYOUT.ClusterCount == 0)
139
140 LAYOUT.ClustersPerMftRecord = EncodeRecordSize(MFT_RECORD_SIZE, C);
141 LAYOUT.ClustersPerIndexRecord = EncodeRecordSize(INDEX_RECORD_SIZE, C);
142
143 //
144 // Metadata sizes (in clusters)
145 //
146
147 // $Boot is exactly the first 8192 bytes of the volume.
148 LAYOUT.BootClusters = (ULONG)CEIL_DIV(8192ULL, (ULONGLONG)C);
149
150 // $MFT: reserve a large MFT.
151 ULONGLONG MftBytes = VolumeBytes / 128;
152
153 if (MftBytes < (4ULL * 1024 * 1024))
154 MftBytes = 4ULL * 1024 * 1024; // 4 MB min (~4096 records)
155 if (MftBytes > (32ULL * 1024 * 1024))
156 MftBytes = 32ULL * 1024 * 1024; // 32 MB cap (~32768 records)
157
158 LAYOUT.MftAllocRecords = (ULONG)(MftBytes / MFT_RECORD_SIZE);
159 LAYOUT.MftClusters = (ULONG)CEIL_DIV((ULONGLONG)LAYOUT.MftAllocRecords * MFT_RECORD_SIZE, (ULONGLONG)C);
160
161 // $MFTMirr: the first four system records.
163
164 // $LogFile: ~0.78% of the volume, clamped to [256 KB, 64 MB].
165 {
166 ULONGLONG LogBytes = VolumeBytes / 128;
167
168 if (LogBytes < (256ULL * 1024))
169 LogBytes = 256ULL * 1024;
170 if (LogBytes > (64ULL * 1024 * 1024))
171 LogBytes = 64ULL * 1024 * 1024;
172
173 LAYOUT.LogFileClusters = (ULONG)CEIL_DIV(LogBytes, (ULONGLONG)C);
174 }
175
176 // $Bitmap: one bit per cluster. The stream length must be a multiple of
177 // 8 bytes (NTFS tracks the bitmap in 64-bit groups). If it isn't, the OS
178 // rounds it up on first write and zero-fills the gap, leaving phantom
179 // trailing clusters marked free. Round up here; WriteMetafiles matches.
180 {
181 ULONGLONG BitmapBytes = CEIL_DIV(LAYOUT.ClusterCount, 8ULL);
182 BitmapBytes = (BitmapBytes + 7) & ~7ULL;
183 LAYOUT.BitmapClusters = (ULONG)CEIL_DIV(BitmapBytes, (ULONGLONG)C);
184 }
185
186 // $UpCase: 128 KB (65536 UTF-16 entries).
187 LAYOUT.UpCaseClusters = (ULONG)CEIL_DIV(128ULL * 1024, (ULONGLONG)C);
188
189 // $AttrDef: reserve 4 KB (the attribute-definition table is ~2.5 KB).
190 LAYOUT.AttrDefClusters = (ULONG)CEIL_DIV(4096ULL, (ULONGLONG)C);
191
192 // $MFT's own allocation bitmap: one bit per reserved MFT record.
193 {
194 ULONGLONG MftBmpBytes = CEIL_DIV((ULONGLONG)LAYOUT.MftAllocRecords, 8ULL);
195 LAYOUT.MftBitmapClusters = (ULONG)CEIL_DIV(MftBmpBytes, (ULONGLONG)C);
196 }
197
198 // Root directory $I30 index: one INDX block.
200
201 // $Secure:$SDS: the 8 default descriptors plus their mirror 256 KiB later.
203
204 // $Secure:$SDH: one INDX block (large view index).
206
207 // $Extend / TxF payload streams (contents zero-initialized on a fresh volume;
208 // chkdsk validates the metadata, not the CLFS log data).
209 LAYOUT.TopsTClusters = (ULONG)CEIL_DIV(1024ULL * 1024, (ULONGLONG)C); // 1 MiB
210 LAYOUT.BlfClusters = (ULONG)CEIL_DIV(64ULL * 1024, (ULONGLONG)C); // 64 KiB
211 LAYOUT.Cont1Clusters = (ULONG)CEIL_DIV(2ULL * 1024 * 1024, (ULONGLONG)C); // 2 MiB
212 LAYOUT.Cont2Clusters = (ULONG)CEIL_DIV(2ULL * 1024 * 1024, (ULONGLONG)C); // 2 MiB
213 LAYOUT.DeletedIdxClusters = (ULONG)CEIL_DIV(64ULL * 1024, (ULONGLONG)C); // 64 KiB
214
215 //
216 // Placement: everything contiguous from the start of the volume.
217 //
218 Lcn = 0;
219 LAYOUT.BootLcn = Lcn; Lcn += LAYOUT.BootClusters;
220 LAYOUT.MftLcn = Lcn; Lcn += LAYOUT.MftClusters;
221 LAYOUT.MftMirrLcn = Lcn; Lcn += LAYOUT.MftMirrClusters;
222 LAYOUT.LogFileLcn = Lcn; Lcn += LAYOUT.LogFileClusters;
223 LAYOUT.BitmapLcn = Lcn; Lcn += LAYOUT.BitmapClusters;
224 LAYOUT.UpCaseLcn = Lcn; Lcn += LAYOUT.UpCaseClusters;
225 LAYOUT.AttrDefLcn = Lcn; Lcn += LAYOUT.AttrDefClusters;
226 LAYOUT.MftBitmapLcn = Lcn; Lcn += LAYOUT.MftBitmapClusters;
227 LAYOUT.RootIdxLcn = Lcn; Lcn += LAYOUT.RootIdxClusters;
228 LAYOUT.SdsLcn = Lcn; Lcn += LAYOUT.SdsClusters;
229 LAYOUT.SdhIdxLcn = Lcn; Lcn += LAYOUT.SdhIdxClusters;
230 LAYOUT.TopsTLcn = Lcn; Lcn += LAYOUT.TopsTClusters;
231 LAYOUT.BlfLcn = Lcn; Lcn += LAYOUT.BlfClusters;
232 LAYOUT.Cont1Lcn = Lcn; Lcn += LAYOUT.Cont1Clusters;
233 LAYOUT.Cont2Lcn = Lcn; Lcn += LAYOUT.Cont2Clusters;
234 LAYOUT.DeletedIdxLcn = Lcn; Lcn += LAYOUT.DeletedIdxClusters;
235 LAYOUT.FirstFreeLcn = Lcn;
236
237 // The volume must be large enough to hold the metadata (plus slack).
238 if (LAYOUT.FirstFreeLcn + 16 >= LAYOUT.ClusterCount)
239 {
240 DPRINT1("Volume too small for NTFS: need %I64u clusters, have %I64u\n",
241 LAYOUT.FirstFreeLcn + 16, LAYOUT.ClusterCount);
242 return STATUS_DISK_FULL;
243 }
244
245 // Volume serial number
246 {
248 ULONG Hi = RtlRandom(&Seed);
249 ULONG Lo = RtlRandom(&Seed);
250 LAYOUT.SerialNumber = ((ULONGLONG)Hi << 32) | (ULONGLONG)Lo;
251 }
252
253 return STATUS_SUCCESS;
254}
#define DPRINT1
Definition: precomp.h:8
#define BYTES_PER_SECTOR
Definition: volume.c:37
DWORD ClusterSize
Definition: format.c:66
#define C(c)
Definition: builtin.c:4556
Definition: terminate.cpp:24
#define DISK_LEN
Definition: ntfslib.h:63
#define MFT_MIRR_COUNT
Definition: ntfslib.h:101
#define NTFS_SDS_MIRROR
Definition: ntfslib.h:245
#define MFT_RECORD_SIZE
Definition: ntfslib.h:93
#define INDEX_RECORD_SIZE
Definition: ntfslib.h:94
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
#define CEIL_DIV(a, b)
Definition: ntfslib.c:96
BYTE GetSectorsPerCluster(VOID)
Definition: ntfslib.c:42
static CHAR EncodeRecordSize(IN ULONG RecordBytes, IN ULONG ClusterBytes)
Definition: ntfslib.c:74
#define NtGetTickCount
Definition: rtlp.h:163
BYTE Seed[SYMCRYPT_HASH_MAX_RESULT_SIZE]
Definition: sc_lib.h:4529
#define STATUS_SUCCESS
Definition: shellext.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155

Referenced by NtfsFormat().

◆ GetSectorsPerCluster()

BYTE GetSectorsPerCluster ( VOID  )

Definition at line 42 of file ntfslib.c.

43{
44 // Default NTFS cluster size selection based on the volume size,
45 // mirroring the classic Windows defaults (for 512-byte sectors):
46 // <= 512 MB : 512 B, <= 1 GB : 1 KB, <= 2 GB : 2 KB, else 4 KB.
47 ULONGLONG Size = DISK_LEN->Length.QuadPart;
49 ULONG ClusterBytes;
50
51 if (Size <= (512ULL * 1024 * 1024))
52 ClusterBytes = 512;
53 else if (Size <= (1024ULL * 1024 * 1024))
54 ClusterBytes = 1024;
55 else if (Size <= (2048ULL * 1024 * 1024))
56 ClusterBytes = 2048;
57 else
58 ClusterBytes = 4096;
59
60 if (ClusterBytes < Bps)
61 ClusterBytes = Bps;
62
63 return (BYTE)(ClusterBytes / Bps);
64}
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
unsigned char BYTE
Definition: xxhash.c:193

Referenced by ComputeLayout().

◆ NtfsGetSystemTimeAsFileTime()

VOID NtfsGetSystemTimeAsFileTime ( OUT PFILETIME  lpFileTime)

Definition at line 26 of file ntfslib.c.

27{
28 LARGE_INTEGER SystemTime;
29
30 do
31 {
32 SystemTime.HighPart = SharedUserData->SystemTime.High1Time;
33 SystemTime.LowPart = SharedUserData->SystemTime.LowPart;
34 }
35 while (SystemTime.HighPart != SharedUserData->SystemTime.High2Time);
36
37 lpFileTime->dwLowDateTime = SystemTime.LowPart;
38 lpFileTime->dwHighDateTime = SystemTime.HighPart;
39}
#define SharedUserData
ULONG LowPart
Definition: typedefs.h:106

◆ NtGetTickCount()

ULONG NTAPI NtGetTickCount ( VOID  )

◆ WriteBootSector()

NTSTATUS WriteBootSector ( VOID  )

Definition at line 112 of file bootsect.c.

113{
117 PBYTE BootRegion;
120
121 // The whole $Boot region (8192 bytes rounded up to clusters). Only the
122 // first sector carries the BPB; the rest is zeroed bootstrap area.
123 RegionSize = LAYOUT.BootClusters * BYTES_PER_CLUSTER;
124
125 BootRegion = RtlAllocateHeap(RtlGetProcessHeap(), 0, RegionSize);
126 if (!BootRegion)
127 {
129 }
130
131 RtlZeroMemory(BootRegion, RegionSize);
132
133 BootSector = (PBOOT_SECTOR)BootRegion;
134
137
140
141 BootSector->EndSector = BOOT_SECTOR_END;
142
143 // Write the $Boot region at LCN 0.
144 Offset.QuadPart = 0LL;
146 NULL,
147 NULL,
148 NULL,
150 BootRegion,
152 &Offset,
153 NULL);
154 if (!NT_SUCCESS(Status))
155 {
156 DPRINT1("BootSector write failed. NtWriteFile() failed (Status %lx)\n", Status);
157 FREE(BootRegion);
158 return Status;
159 }
160
161 // Write the backup boot sector at the very end of the volume.
163
164 FREE(BootRegion);
165
166 return Status;
167}
#define FREE(ptr, size)
Definition: auth_des.c:64
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
static VOID FillExBiosParametersBlock(OUT PEXTENDED_BIOS_PARAMETERS_BLOCK ExBiosParametersBlock)
Definition: bootsect.c:53
static VOID FillBiosParametersBlock(OUT PBIOS_PARAMETERS_BLOCK BiosParametersBlock)
Definition: bootsect.c:37
static NTSTATUS WriteBackupBootSector(IN PBOOT_SECTOR BootSector)
Definition: bootsect.c:75
static VOID FillJumpInstruction(OUT PBOOT_SECTOR BootSector)
Definition: bootsect.c:21
static VOID FillOemId(OUT PBOOT_SECTOR BootSector)
Definition: bootsect.c:30
_In_ PIO_STATUS_BLOCK IoStatusBlock
Definition: dispmprt.h:608
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
struct _BOOT_SECTOR * PBOOT_SECTOR
Status
Definition: gdiplustypes.h:24
#define BYTES_PER_CLUSTER
Definition: ntfslib.h:72
#define DISK_HANDLE
Definition: ntfslib.h:61
#define BOOT_SECTOR_END
Definition: ntfslib.h:88
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:176
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BYTE * PBYTE
Definition: pedump.c:66
#define LL
Definition: tui.h:167
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _BootSector BootSector
Definition: vfat.h:108

Referenced by NtfsFormat().

◆ WriteMetafiles()

NTSTATUS WriteMetafiles ( VOID  )

Definition at line 872 of file files.c.

873{
875 PBYTE Mft;
876 PBYTE Val;
879 ULONGLONG ClusterCount = LAYOUT.ClusterCount;
880
881 /* --- $Secure descriptor precompute (blob/$SDS offsets + hashes) ------ */
882 ULONG SdBlobOff[NTFS_DEFAULT_SD_COUNT];
885 ULONG SdsContentLen;
886
887 /* $SDH hash-sorted order of the 8 default descriptors (index i = id 0x100+i). */
888 static const BYTE SdhOrder[NTFS_DEFAULT_SD_COUNT] = { 4, 6, 2, 3, 7, 5, 0, 1 };
889
890 ULONG Blob = 0;
891 ULONG Sds = 0;
892 ULONG i;
893
894 for (i = 0; i < NTFS_DEFAULT_SD_COUNT; i++)
895 {
896 SdBlobOff[i] = Blob;
897 SdSdsOff[i] = Sds;
898 SdHash[i] = MkSecHash(DefaultSds + Blob, DefaultSdLen[i]);
899 Blob += DefaultSdLen[i];
900 Sds = ALIGN_UP_BY(Sds + 0x14 + DefaultSdLen[i], 16);
901 }
902 SdsContentLen = SdSdsOff[NTFS_DEFAULT_SD_COUNT - 1] + 0x14 +
904
905 /* --- Build the MFT in memory (records 0..35) ------------------------ */
906 Mft = RtlAllocateHeap(RtlGetProcessHeap(), 0, MREC_COUNT * MFT_RECORD_SIZE);
907 if (!Mft)
908 {
909 DPRINT1("ERROR: Unable to allocate MFT build buffer!\n");
911 }
913
914 Val = RtlAllocateHeap(RtlGetProcessHeap(), 0, 2048);
915 if (!Val)
916 {
917 DPRINT1("ERROR: Unable to allocate attribute scratch buffer!\n");
918 FREE(Mft);
920 }
921
922 {
923 MK_REC Rec;
924 ULONG Len;
925 MK_RUN Runs[1];
926
927 #define REC_BUF(n) (Mft + (ULONG_PTR)(n) * MFT_RECORD_SIZE)
928
929 /* Record 0: $MFT (large, contiguous $DATA run). */
932 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
934 (ULONGLONG)LAYOUT.MftClusters * C,
935 (ULONGLONG)LAYOUT.MftAllocRecords * MFT_RECORD_SIZE,
938 Runs[0].Lcn = LAYOUT.MftLcn; Runs[0].Len = LAYOUT.MftClusters;
939 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.MftClusters - 1,
940 (ULONGLONG)LAYOUT.MftClusters * C,
941 (ULONGLONG)LAYOUT.MftAllocRecords * MFT_RECORD_SIZE,
942 (ULONGLONG)LAYOUT.MftAllocRecords * MFT_RECORD_SIZE);
943 /* $BITMAP (non-resident): one bit per reserved MFT record. */
944 {
945 ULONGLONG MftBmpBytes = ((ULONGLONG)LAYOUT.MftAllocRecords + 7) / 8;
946 Runs[0].Lcn = LAYOUT.MftBitmapLcn; Runs[0].Len = LAYOUT.MftBitmapClusters;
947 MkAddNonResident(&Rec, AttributeBitmap, NULL, 0, 0, Runs, 1, LAYOUT.MftBitmapClusters - 1,
948 (ULONGLONG)LAYOUT.MftBitmapClusters * C, MftBmpBytes, MftBmpBytes);
949 }
950 MkFinalize(&Rec);
951
952 /* Record 1: $MFTMirr. */
955 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
958 Now, L"$MFTMirr", FILE_NAME_WIN32_AND_DOS);
960 Runs[0].Lcn = LAYOUT.MftMirrLcn; Runs[0].Len = LAYOUT.MftMirrClusters;
961 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.MftMirrClusters - 1,
962 (ULONGLONG)LAYOUT.MftMirrClusters * C,
965 MkFinalize(&Rec);
966
967 /* Record 2: $LogFile. */
970 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
972 (ULONGLONG)LAYOUT.LogFileClusters * C, (ULONGLONG)LAYOUT.LogFileClusters * C,
973 Now, L"$LogFile", FILE_NAME_WIN32_AND_DOS);
975 Runs[0].Lcn = LAYOUT.LogFileLcn; Runs[0].Len = LAYOUT.LogFileClusters;
976 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.LogFileClusters - 1,
977 (ULONGLONG)LAYOUT.LogFileClusters * C, (ULONGLONG)LAYOUT.LogFileClusters * C,
978 (ULONGLONG)LAYOUT.LogFileClusters * C);
979 MkFinalize(&Rec);
980
981 /* Record 3: $Volume. */
983 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x101);
984 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
986 0, 0, Now, L"$Volume", FILE_NAME_WIN32_AND_DOS);
988 {
989 BYTE VName[128];
990 ULONG VLen = 0;
991 if (LABEL && LABEL->Buffer && LABEL->Length > 0)
992 {
993 VLen = LABEL->Length;
994 if (VLen > 128)
995 VLen = 128;
996 RtlCopyMemory(VName, LABEL->Buffer, VLen);
997 }
998 MkAddResident(&Rec, AttributeVolumeName, NULL, 0, 0, VName, VLen);
999 }
1000 /* $VOLUME_INFORMATION: version 3.1, flags 0 (the 0x80 dirty bit left clear). */
1001 RtlZeroMemory(Val, 12);
1002 Val[0x08] = NTFS_MAJOR_VERSION;
1003 Val[0x09] = NTFS_MINOR_VERSION;
1004 MkAddResident(&Rec, AttributeVolumeInformation, NULL, 0, 0, Val, 12);
1005 MkAddResident(&Rec, AttributeData, NULL, 0, 0, NULL, 0); /* empty $DATA */
1006 MkFinalize(&Rec);
1007
1008 /* Record 4: $AttrDef. */
1011 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1013 (ULONGLONG)LAYOUT.AttrDefClusters * C,
1014 sizeof(ATTRIBUTES_TABLE) - sizeof(ATTRIBUTES_TABLE[0]),
1015 Now, L"$AttrDef", FILE_NAME_WIN32_AND_DOS);
1017 Runs[0].Lcn = LAYOUT.AttrDefLcn; Runs[0].Len = LAYOUT.AttrDefClusters;
1018 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.AttrDefClusters - 1,
1019 (ULONGLONG)LAYOUT.AttrDefClusters * C,
1020 sizeof(ATTRIBUTES_TABLE), sizeof(ATTRIBUTES_TABLE));
1021 MkFinalize(&Rec);
1022
1023 /* Record 6: $Bitmap. The stream length must be a multiple of 8 bytes
1024 * (NTFS tracks the cluster bitmap in 64-bit groups); an unaligned length
1025 * gets rounded up and zero-filled by the OS, freeing phantom clusters. */
1026 {
1027 ULONGLONG BitmapBytes = (((ClusterCount + 7) / 8) + 7) & ~7ULL;
1030 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1032 (ULONGLONG)LAYOUT.BitmapClusters * C, BitmapBytes,
1033 Now, L"$Bitmap", FILE_NAME_WIN32_AND_DOS);
1035 Runs[0].Lcn = LAYOUT.BitmapLcn; Runs[0].Len = LAYOUT.BitmapClusters;
1036 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.BitmapClusters - 1,
1037 (ULONGLONG)LAYOUT.BitmapClusters * C, BitmapBytes, BitmapBytes);
1038 MkFinalize(&Rec);
1039 }
1040
1041 /* Record 7: $Boot (short STD_INFO + embedded default descriptor 0x100). */
1044 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 48);
1046 (ULONGLONG)LAYOUT.BootClusters * C, 0x2000,
1047 Now, L"$Boot", FILE_NAME_WIN32_AND_DOS);
1050 DefaultSds + SdBlobOff[0], DefaultSdLen[0]);
1051 Runs[0].Lcn = LAYOUT.BootLcn; Runs[0].Len = LAYOUT.BootClusters;
1052 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.BootClusters - 1,
1053 (ULONGLONG)LAYOUT.BootClusters * C, 0x2000, 0x2000);
1054 MkFinalize(&Rec);
1055
1056 /* Record 8: $BadClus (empty $DATA + sparse whole-volume $Bad hole). */
1059 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1061 0, 0, Now, L"$BadClus", FILE_NAME_WIN32_AND_DOS);
1063 MkAddResident(&Rec, AttributeData, NULL, 0, 0, NULL, 0);
1064 /* $Bad is a plain (non-sparse) non-resident attribute whose single
1065 * mapping-pair is a hole; alloc/real = whole volume, init = 0. */
1066 Runs[0].Lcn = HOLE_LCN; Runs[0].Len = ClusterCount;
1067 MkAddNonResident(&Rec, AttributeData, L"$Bad", 4, 0, Runs, 1, ClusterCount - 1,
1068 ClusterCount * C, ClusterCount * C, 0);
1069 MkFinalize(&Rec);
1070
1071 /* Record 9: $Secure ($SDS + large $SDH + resident $SII). */
1072 {
1073 BYTE SdsHdr[NTFS_DEFAULT_SD_COUNT][0x14];
1074 BYTE SiiKeys[NTFS_DEFAULT_SD_COUNT][4];
1075 BYTE SdhKeys[NTFS_DEFAULT_SD_COUNT][8];
1077 BYTE ViewRoot[512];
1078
1079 for (i = 0; i < NTFS_DEFAULT_SD_COUNT; i++)
1080 {
1081 ULONG Id = 0x100 + i;
1082 WR32(SdsHdr[i], 0x00, SdHash[i]);
1083 WR32(SdsHdr[i], 0x04, Id);
1084 WR64(SdsHdr[i], 0x08, SdSdsOff[i]);
1085 WR32(SdsHdr[i], 0x10, 0x14 + DefaultSdLen[i]);
1086 WR32(SiiKeys[i], 0, Id);
1087 WR32(SdhKeys[i], 0, SdHash[i]);
1088 WR32(SdhKeys[i], 4, Id);
1089 SiiEnt[i].Key = SiiKeys[i]; SiiEnt[i].KeyLen = 4;
1090 SiiEnt[i].Data = SdsHdr[i]; SiiEnt[i].DataLen = 0x14;
1091 }
1092
1094 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM | FA_VIEW, Now, 0x101);
1095 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1097 0, 0, Now, L"$Secure", FILE_NAME_WIN32_AND_DOS);
1099 /* $DATA:$SDS (non-resident: 8 descriptors + a 256 KiB-offset mirror). */
1100 Runs[0].Lcn = LAYOUT.SdsLcn; Runs[0].Len = LAYOUT.SdsClusters;
1101 MkAddNonResident(&Rec, AttributeData, L"$SDS", 4, 0, Runs, 1, LAYOUT.SdsClusters - 1,
1102 (ULONGLONG)LAYOUT.SdsClusters * C,
1103 (ULONGLONG)NTFS_SDS_MIRROR + SdsContentLen,
1104 (ULONGLONG)NTFS_SDS_MIRROR + SdsContentLen);
1105 /* Attribute order (type, name): $SDH root, $SII root, then $SDH alloc, $SDH bitmap. */
1107 MkAddResident(&Rec, AttributeIndexRoot, L"$SDH", 4, 0, ViewRoot, Len);
1109 MkAddResident(&Rec, AttributeIndexRoot, L"$SII", 4, 0, ViewRoot, Len);
1110 Runs[0].Lcn = LAYOUT.SdhIdxLcn; Runs[0].Len = LAYOUT.SdhIdxClusters;
1111 MkAddNonResident(&Rec, AttributeIndexAllocation, L"$SDH", 4, 0, Runs, 1,
1112 LAYOUT.SdhIdxClusters - 1, (ULONGLONG)LAYOUT.SdhIdxClusters * C,
1114 RtlZeroMemory(Val, 8);
1115 Val[0] = 0x01;
1116 MkAddResident(&Rec, AttributeBitmap, L"$SDH", 4, 0, Val, 8);
1117 MkFinalize(&Rec);
1118 }
1119
1120 /* Record 10: $UpCase (+ $Info CRC stream). */
1123 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1125 sizeof(UPCASE_TABLE), sizeof(UPCASE_TABLE),
1126 Now, L"$UpCase", FILE_NAME_WIN32_AND_DOS);
1128 Runs[0].Lcn = LAYOUT.UpCaseLcn; Runs[0].Len = LAYOUT.UpCaseClusters;
1129 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.UpCaseClusters - 1,
1130 (ULONGLONG)LAYOUT.UpCaseClusters * C, sizeof(UPCASE_TABLE), sizeof(UPCASE_TABLE));
1131 MkAddResident(&Rec, AttributeData, L"$Info", 5, 0, UpCaseInfo, sizeof(UpCaseInfo));
1132 MkFinalize(&Rec);
1133
1134 /* ---- $Extend children (build children before their index parents) --- */
1135
1136 /* Record 24: $Quota (default quota entries). */
1137 {
1138 BYTE Qce[64];
1139 BYTE QKey1[4];
1140 BYTE QKey256[4];
1141 BYTE OData[4];
1142 BYTE QIdx[256];
1143 BYTE OIdx[128];
1144 MK_VIEW_ENTRY QEnt[2];
1145 MK_VIEW_ENTRY OEnt[1];
1146
1147 RtlZeroMemory(Qce, sizeof(Qce));
1148 WR32(Qce, 0x00, 2); /* version */
1149 WR32(Qce, 0x04, 1); /* flags */
1150 WR64(Qce, 0x08, 0); /* bytes used */
1151 WR64(Qce, 0x10, Now); /* change time */
1152 WR64(Qce, 0x18, 0xFFFFFFFFFFFFFFFFULL); /* threshold */
1153 WR64(Qce, 0x20, 0xFFFFFFFFFFFFFFFFULL); /* limit */
1154 WR64(Qce, 0x28, 0); /* exceeded time */
1155 RtlCopyMemory(Qce + 48, SidAdmins, 16); /* id 0x100 carries the SID */
1156
1157 WR32(QKey1, 0, 1);
1158 WR32(QKey256, 0, 0x100);
1159 WR32(OData, 0, 0x100);
1160
1161 QEnt[0].Key = QKey1; QEnt[0].KeyLen = 4; QEnt[0].Data = Qce; QEnt[0].DataLen = 48;
1162 QEnt[1].Key = QKey256; QEnt[1].KeyLen = 4; QEnt[1].Data = Qce; QEnt[1].DataLen = 64;
1163 OEnt[0].Key = SidAdmins; OEnt[0].KeyLen = 16; OEnt[0].Data = OData; OEnt[0].DataLen = 4;
1164
1167 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM | FA_VIEW, Now, 0x101);
1168 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1170 0, 0, Now, L"$Quota", FILE_NAME_POSIX);
1172 Len = MkViewRootN(OIdx, COLL_SID, OEnt, 1);
1173 MkAddResident(&Rec, AttributeIndexRoot, L"$O", 2, 0, OIdx, Len);
1174 Len = MkViewRootN(QIdx, COLLATION_NTOFS_ULONG, QEnt, 2);
1175 MkAddResident(&Rec, AttributeIndexRoot, L"$Q", 2, 0, QIdx, Len);
1176 MkFinalize(&Rec);
1177 }
1178
1179 /* Record 25: $ObjId (empty $O). */
1182 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM | FA_VIEW, Now, 0x101);
1183 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1185 0, 0, Now, L"$ObjId", FILE_NAME_POSIX);
1188 MkAddResident(&Rec, AttributeIndexRoot, L"$O", 2, 0, Val, Len);
1189 MkFinalize(&Rec);
1190
1191 /* Record 26: $Reparse (empty $R). */
1194 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM | FA_VIEW, Now, 0x101);
1195 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1197 0, 0, Now, L"$Reparse", FILE_NAME_POSIX);
1200 MkAddResident(&Rec, AttributeIndexRoot, L"$R", 2, 0, Val, Len);
1201 MkFinalize(&Rec);
1202
1203 /* Records 12..15: reserved stubs - in use, 0 hard links, short STD_INFO,
1204 * embedded default descriptor 0x101, empty resident unnamed $DATA. */
1205 for (i = 12; i <= 15; i++)
1206 {
1208 MkSetHardLinks(&Rec, 0);
1210 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 48);
1212 DefaultSds + SdBlobOff[1], DefaultSdLen[1]);
1213 MkAddResident(&Rec, AttributeData, NULL, 0, 0, NULL, 0);
1214 MkFinalize(&Rec);
1215 }
1216
1217 /* ---- $Extend/$RmMetadata TxF subtree ------------------------------ */
1218
1219 /* Record 28: $Repair - empty non-resident $DATA + $DATA:$Config. */
1221 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x101);
1222 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1224 0, 0, Now, L"$Repair", FILE_NAME_POSIX);
1226 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, NULL, 0, (ULONGLONG)-1, 0, 0, 0);
1227 MkAddResident(&Rec, AttributeData, L"$Config", 7, 0, RepairCfg, sizeof(RepairCfg));
1228 MkFinalize(&Rec);
1229
1230 /* Record 29: $Deleted - empty dir with a pre-allocated (unused) 64 KiB index. */
1233 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x101);
1234 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1236 0, 0, Now, L"$Deleted", FILE_NAME_POSIX);
1238 Len = MkEmptyI30Root(Val);
1239 MkAddResident(&Rec, AttributeIndexRoot, L"$I30", 4, 0, Val, Len);
1240 Runs[0].Lcn = LAYOUT.DeletedIdxLcn; Runs[0].Len = LAYOUT.DeletedIdxClusters;
1241 MkAddNonResident(&Rec, AttributeIndexAllocation, L"$I30", 4, 0, Runs, 1,
1242 LAYOUT.DeletedIdxClusters - 1, (ULONGLONG)LAYOUT.DeletedIdxClusters * C, 0, 0);
1243 RtlZeroMemory(Val, 8);
1244 MkAddResident(&Rec, AttributeBitmap, L"$I30", 4, 0, Val, 8);
1245 MkFinalize(&Rec);
1246
1247 /* Record 31: $Txf - empty dir + $TXF_DATA. */
1249 MkStdInfo(Val, 0x80000006, Now, 0x102);
1250 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1252 0, 0, Now, L"$Txf", FILE_NAME_POSIX);
1254 Len = MkEmptyI30Root(Val);
1255 MkAddResident(&Rec, AttributeIndexRoot, L"$I30", 4, 0, Val, Len);
1256 MkAddResident(&Rec, AttributeLoggedUtilityStream, L"$TXF_DATA", 9, 0, TxfInfo, sizeof(TxfInfo));
1257 MkFinalize(&Rec);
1258
1259 /* Record 32: $Tops - resident $DATA + $DATA:$T (1 MiB). */
1261 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x102);
1262 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1264 0, 0, Now, L"$Tops", FILE_NAME_POSIX);
1266 MkAddResident(&Rec, AttributeData, NULL, 0, 0, TopsData, sizeof(TopsData));
1267 Runs[0].Lcn = LAYOUT.TopsTLcn; Runs[0].Len = LAYOUT.TopsTClusters;
1268 MkAddNonResident(&Rec, AttributeData, L"$T", 2, 0, Runs, 1, LAYOUT.TopsTClusters - 1,
1269 (ULONGLONG)LAYOUT.TopsTClusters * C,
1270 (ULONGLONG)LAYOUT.TopsTClusters * C, (ULONGLONG)LAYOUT.TopsTClusters * C);
1271 MkFinalize(&Rec);
1272
1273 /* Record 33: $TxfLog.blf (64 KiB). */
1275 MkStdInfo(Val, FA_ARCHIVE, Now, 0x103);
1276 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1278 (ULONGLONG)LAYOUT.BlfClusters * C, 0, Now, L"$TxfLog.blf", FILE_NAME_POSIX);
1280 Runs[0].Lcn = LAYOUT.BlfLcn; Runs[0].Len = LAYOUT.BlfClusters;
1281 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.BlfClusters - 1,
1282 (ULONGLONG)LAYOUT.BlfClusters * C,
1283 (ULONGLONG)LAYOUT.BlfClusters * C, (ULONGLONG)LAYOUT.BlfClusters * C);
1284 MkFinalize(&Rec);
1285
1286 /* Records 34/35: $TxfLogContainer...0001 / ...0002 (2 MiB each). */
1288 MkStdInfo(Val, FA_ARCHIVE, Now, 0x104);
1289 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1291 (ULONGLONG)LAYOUT.Cont1Clusters * C, 0, Now,
1292 L"$TxfLogContainer00000000000000000001", FILE_NAME_POSIX);
1294 Runs[0].Lcn = LAYOUT.Cont1Lcn; Runs[0].Len = LAYOUT.Cont1Clusters;
1295 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.Cont1Clusters - 1,
1296 (ULONGLONG)LAYOUT.Cont1Clusters * C,
1297 (ULONGLONG)LAYOUT.Cont1Clusters * C, (ULONGLONG)LAYOUT.Cont1Clusters * C);
1298 MkFinalize(&Rec);
1299
1301 MkStdInfo(Val, FA_ARCHIVE, Now, 0x104);
1302 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1304 (ULONGLONG)LAYOUT.Cont2Clusters * C, 0, Now,
1305 L"$TxfLogContainer00000000000000000002", FILE_NAME_POSIX);
1307 Runs[0].Lcn = LAYOUT.Cont2Lcn; Runs[0].Len = LAYOUT.Cont2Clusters;
1308 MkAddNonResident(&Rec, AttributeData, NULL, 0, 0, Runs, 1, LAYOUT.Cont2Clusters - 1,
1309 (ULONGLONG)LAYOUT.Cont2Clusters * C,
1310 (ULONGLONG)LAYOUT.Cont2Clusters * C, (ULONGLONG)LAYOUT.Cont2Clusters * C);
1311 MkFinalize(&Rec);
1312
1313 /* Record 30: $TxfLog directory, indexing $Tops/$TxfLog.blf/containers. */
1314 {
1315 static const ULONG TxfLogOrder[] = { MREC_TOPS, MREC_TXFBLF, MREC_CONT1, MREC_CONT2 };
1316
1318 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x102);
1319 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1321 0, 0, Now, L"$TxfLog", FILE_NAME_POSIX);
1323 Len = MkI30RootWithEntries(Val, Mft, TxfLogOrder, ARR_SIZE(TxfLogOrder));
1324 MkAddResident(&Rec, AttributeIndexRoot, L"$I30", 4, 0, Val, Len);
1325 MkFinalize(&Rec);
1326 }
1327
1328 /* Record 27: $RmMetadata directory, indexing $Repair/$Txf/$TxfLog. */
1329 {
1330 static const ULONG RmOrder[] = { MREC_REPAIR, MREC_TXF, MREC_TXFLOG };
1331
1333 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x102);
1334 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1336 0, 0, Now, L"$RmMetadata", FILE_NAME_POSIX);
1338 Len = MkI30RootWithEntries(Val, Mft, RmOrder, ARR_SIZE(RmOrder));
1339 MkAddResident(&Rec, AttributeIndexRoot, L"$I30", 4, 0, Val, Len);
1340 MkFinalize(&Rec);
1341 }
1342
1343 /* Record 11: $Extend directory, indexing all children (collation order
1344 * $Deleted < $ObjId < $Quota < $Reparse < $RmMetadata). The directory
1345 * bit is set in FILE_NAME but not in STD_INFO. */
1346 {
1347 static const ULONG ExtendOrder[] =
1349
1351 MkStdInfo(Val, FA_HIDDEN | FA_SYSTEM, Now, 0x101);
1352 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 72);
1354 0, 0, Now, L"$Extend", FILE_NAME_WIN32_AND_DOS);
1356 Len = MkI30RootWithEntries(Val, Mft, ExtendOrder, ARR_SIZE(ExtendOrder));
1357 MkAddResident(&Rec, AttributeIndexRoot, L"$I30", 4, 0, Val, Len);
1358 MkFinalize(&Rec);
1359 }
1360
1361 /* Record 5: root "." - large $I30 index + embedded (unique) SD + $TXF_DATA. */
1364 MkAddResident(&Rec, AttributeStandardInformation, NULL, 0, 0, Val, 48);
1366 0, 0, Now, L".", FILE_NAME_WIN32_AND_DOS);
1369 Len = MkLargeI30Root(Val);
1370 MkAddResident(&Rec, AttributeIndexRoot, L"$I30", 4, 0, Val, Len);
1371 Runs[0].Lcn = LAYOUT.RootIdxLcn; Runs[0].Len = LAYOUT.RootIdxClusters;
1372 MkAddNonResident(&Rec, AttributeIndexAllocation, L"$I30", 4, 0, Runs, 1,
1373 LAYOUT.RootIdxClusters - 1, (ULONGLONG)LAYOUT.RootIdxClusters * C,
1375 RtlZeroMemory(Val, 8);
1376 Val[0] = 0x01; /* INDX VCN 0 allocated */
1377 MkAddResident(&Rec, AttributeBitmap, L"$I30", 4, 0, Val, 8);
1378 MkAddResident(&Rec, AttributeLoggedUtilityStream, L"$TXF_DATA", 9, 0,
1379 TxfDataValue, sizeof(TxfDataValue));
1380 MkFinalize(&Rec);
1381
1382 #undef REC_BUF
1383 }
1384
1385 /* --- Emit everything to disk ---------------------------------------- */
1386
1387 /* Zero the whole reserved $MFT region, then lay the 36 built records over
1388 * the start of it. Records 16..23 and 36+ are left zero (no FILE record). */
1389 Status = WriteZerosToClusters(LAYOUT.MftLcn, LAYOUT.MftClusters);
1390 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: clear $MFT (Status %lx)\n", Status); goto done; }
1391
1393 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $MFT (Status %lx)\n", Status); goto done; }
1394
1395 /* $MFTMirr = the first four records. */
1396 Status = WriteRegion(LAYOUT.MftMirrLcn, LAYOUT.MftMirrClusters, Mft, MFT_MIRR_COUNT * MFT_RECORD_SIZE);
1397 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $MFTMirr (Status %lx)\n", Status); goto done; }
1398
1399 /* $LogFile: fill 0xFF (a driver treats an all-0xFF log as uninitialized). */
1400 Status = WritePatternToClusters(LAYOUT.LogFileLcn, LAYOUT.LogFileClusters, 0xFF);
1401 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $LogFile (Status %lx)\n", Status); goto done; }
1402
1403 /* $AttrDef. */
1404 Status = WriteRegion(LAYOUT.AttrDefLcn, LAYOUT.AttrDefClusters, &ATTRIBUTES_TABLE, sizeof(ATTRIBUTES_TABLE));
1405 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $AttrDef (Status %lx)\n", Status); goto done; }
1406
1407 /* $UpCase. */
1408 Status = WriteRegion(LAYOUT.UpCaseLcn, LAYOUT.UpCaseClusters, &UPCASE_TABLE, sizeof(UPCASE_TABLE));
1409 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $UpCase (Status %lx)\n", Status); goto done; }
1410
1411 /* $Secure:$SDS - the 8 descriptors (16-byte aligned) with a duplicate copy
1412 * of the whole set placed 256 KiB further on. */
1413 {
1414 ULONG Size = LAYOUT.SdsClusters * BYTES_PER_CLUSTER;
1415 PBYTE Buf = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
1416 if (!Buf) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; }
1417 RtlZeroMemory(Buf, Size);
1418 for (i = 0; i < NTFS_DEFAULT_SD_COUNT; i++)
1419 {
1420 ULONG EntryLen = 0x14 + DefaultSdLen[i];
1421 PBYTE E = Buf + SdSdsOff[i];
1422 WR32(E, 0x00, SdHash[i]);
1423 WR32(E, 0x04, 0x100 + i);
1424 WR64(E, 0x08, SdSdsOff[i]);
1425 WR32(E, 0x10, EntryLen);
1426 RtlCopyMemory(E + 0x14, DefaultSds + SdBlobOff[i], DefaultSdLen[i]);
1427 /* The copy is identical to the primary, offset field included (it
1428 * keeps pointing at the primary, not at the copy). */
1429 RtlCopyMemory(Buf + NTFS_SDS_MIRROR + SdSdsOff[i], E, EntryLen);
1430 }
1431 Status = WriteAt(LAYOUT.SdsLcn, Buf, Size);
1432 FREE(Buf);
1433 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $SDS (Status %lx)\n", Status); goto done; }
1434 }
1435
1436 /* $Secure:$SDH INDX block (8 entries keyed by {hash,id}, hash order). */
1437 {
1438 BYTE SdsHdr[NTFS_DEFAULT_SD_COUNT][0x14];
1439 BYTE SdhKeys[NTFS_DEFAULT_SD_COUNT][8];
1441 PBYTE Indx;
1442
1443 for (i = 0; i < NTFS_DEFAULT_SD_COUNT; i++)
1444 {
1445 ULONG Id = 0x100 + i;
1446 WR32(SdsHdr[i], 0x00, SdHash[i]);
1447 WR32(SdsHdr[i], 0x04, Id);
1448 WR64(SdsHdr[i], 0x08, SdSdsOff[i]);
1449 WR32(SdsHdr[i], 0x10, 0x14 + DefaultSdLen[i]);
1450 WR32(SdhKeys[i], 0, SdHash[i]);
1451 WR32(SdhKeys[i], 4, Id);
1452 }
1453 for (i = 0; i < NTFS_DEFAULT_SD_COUNT; i++)
1454 {
1455 BYTE J = SdhOrder[i];
1456 SdhEnt[i].Key = SdhKeys[J]; SdhEnt[i].KeyLen = 8;
1457 SdhEnt[i].Data = SdsHdr[J]; SdhEnt[i].DataLen = 0x14;
1458 }
1459
1460 Indx = RtlAllocateHeap(RtlGetProcessHeap(), 0, INDEX_RECORD_SIZE);
1461 if (!Indx) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; }
1463 Status = WriteRegion(LAYOUT.SdhIdxLcn, LAYOUT.SdhIdxClusters, Indx, INDEX_RECORD_SIZE);
1464 FREE(Indx);
1465 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $SDH (Status %lx)\n", Status); goto done; }
1466 }
1467
1468 /* $MFT:$BITMAP - records 0..15 and 24..35 in use. */
1469 {
1470 ULONG Size = LAYOUT.MftBitmapClusters * BYTES_PER_CLUSTER;
1471 PBYTE Buf = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
1472 if (!Buf) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; }
1473 RtlZeroMemory(Buf, Size);
1474 Buf[0] = 0xFF; Buf[1] = 0xFF; /* records 0..15 */
1475 Buf[3] = 0xFF; Buf[4] = 0x0F; /* records 24..35 */
1476 Status = WriteAt(LAYOUT.MftBitmapLcn, Buf, Size);
1477 FREE(Buf);
1478 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $MFT:$BITMAP (Status %lx)\n", Status); goto done; }
1479 }
1480
1481 /* Cluster $Bitmap: metadata clusters [0, FirstFreeLcn) used, the rest free,
1482 * and the bits past ClusterCount (up to the 8-byte-aligned end) set. */
1483 {
1484 ULONG Size = LAYOUT.BitmapClusters * BYTES_PER_CLUSTER;
1485 ULONGLONG BitmapBytes = (((ClusterCount + 7) / 8) + 7) & ~7ULL;
1486 ULONGLONG BitmapBits = BitmapBytes * 8;
1487 ULONGLONG c;
1488 PBYTE Buf = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
1489 if (!Buf) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; }
1490 RtlZeroMemory(Buf, Size);
1491 for (c = 0; c < LAYOUT.FirstFreeLcn; c++)
1492 Buf[c / 8] |= (1 << (c % 8));
1493 for (c = ClusterCount; c < BitmapBits; c++)
1494 Buf[c / 8] |= (1 << (c % 8));
1495 Status = WriteAt(LAYOUT.BitmapLcn, Buf, Size);
1496 FREE(Buf);
1497 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write $Bitmap (Status %lx)\n", Status); goto done; }
1498 }
1499
1500 /* Root $I30 INDX block: the system files in collation (uppercased-name)
1501 * order. "$" names (0x24) sort before root's own "." (0x2E), which is last. */
1502 {
1503 static const ULONG RootOrder[] =
1504 {
1508 };
1509 PBYTE Indx = RtlAllocateHeap(RtlGetProcessHeap(), 0, INDEX_RECORD_SIZE);
1510 if (!Indx) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; }
1511 MkRootIndxBlock(Indx, Mft, RootOrder, ARR_SIZE(RootOrder));
1512 Status = WriteRegion(LAYOUT.RootIdxLcn, LAYOUT.RootIdxClusters, Indx, INDEX_RECORD_SIZE);
1513 FREE(Indx);
1514 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: write root index (Status %lx)\n", Status); goto done; }
1515 }
1516
1517 /* Zero the TxF payload streams (CLFS logs are empty on a fresh volume). */
1518 Status = WriteZerosToClusters(LAYOUT.TopsTLcn, LAYOUT.TopsTClusters);
1519 if (NT_SUCCESS(Status)) Status = WriteZerosToClusters(LAYOUT.BlfLcn, LAYOUT.BlfClusters);
1520 if (NT_SUCCESS(Status)) Status = WriteZerosToClusters(LAYOUT.Cont1Lcn, LAYOUT.Cont1Clusters);
1521 if (NT_SUCCESS(Status)) Status = WriteZerosToClusters(LAYOUT.Cont2Lcn, LAYOUT.Cont2Clusters);
1522 if (NT_SUCCESS(Status)) Status = WriteZerosToClusters(LAYOUT.DeletedIdxLcn, LAYOUT.DeletedIdxClusters);
1523 if (!NT_SUCCESS(Status)) { DPRINT1("ERROR: zero TxF payloads (Status %lx)\n", Status); goto done; }
1524
1525done:
1526 FREE(Val);
1527 FREE(Mft);
1528 return Status;
1529}
DWORD Id
#define ALIGN_UP_BY(size, align)
const BYTE UPCASE_TABLE[]
Definition: data.h:62
const ATTR_DEF ATTRIBUTES_TABLE[]
Definition: data.h:41
#define Len
Definition: deflate.h:82
#define L(x)
Definition: resources.c:13
#define COLLATION_NTOFS_ULONG
Definition: ntfs.h:230
@ AttributeVolumeName
Definition: ntfs.h:193
@ AttributeIndexRoot
Definition: ntfs.h:196
@ AttributeFileName
Definition: ntfs.h:190
@ AttributeStandardInformation
Definition: ntfs.h:188
@ AttributeVolumeInformation
Definition: ntfs.h:194
@ AttributeSecurityDescriptor
Definition: ntfs.h:192
@ AttributeIndexAllocation
Definition: ntfs.h:197
@ AttributeLoggedUtilityStream
Definition: ntfs.h:203
@ AttributeData
Definition: ntfs.h:195
@ AttributeBitmap
Definition: ntfs.h:198
#define COLLATION_NTOFS_SECURITY_HASH
Definition: ntfs.h:232
#define RA_INDEXED
Definition: ntfs.h:266
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define c
Definition: ke_i.h:80
#define LABEL
Definition: ntfslib.h:64
#define ARR_SIZE(arr)
Definition: ntfslib.h:34
#define FILE_NAME_POSIX
Definition: ntfslib.h:131
#define NTFS_MINOR_VERSION
Definition: ntfslib.h:107
#define FILE_NAME_WIN32_AND_DOS
Definition: ntfslib.h:134
#define NTFS_SECURITY_ID
Definition: ntfslib.h:110
#define MFT_REFERENCE(rec)
Definition: ntfslib.h:177
#define FORMAT_TIME
Definition: ntfslib.h:264
#define NTFS_MAJOR_VERSION
Definition: ntfslib.h:106
static const BYTE TopsData[100]
Definition: refdata.h:93
static const BYTE TxfDataValue[56]
Definition: refdata.h:86
#define NTFS_DEFAULT_SD_COUNT
Definition: refdata.h:11
static const BYTE UpCaseInfo[32]
Definition: refdata.h:117
static const BYTE RepairCfg[8]
Definition: refdata.h:110
static const BYTE SidAdmins[16]
Definition: refdata.h:112
static const BYTE DefaultSds[716]
Definition: refdata.h:20
static const USHORT DefaultSdLen[NTFS_DEFAULT_SD_COUNT]
Definition: refdata.h:18
static const BYTE RootSdValue[228]
Definition: refdata.h:68
static const BYTE TxfInfo[56]
Definition: refdata.h:103
#define MREC_COUNT
Definition: files.c:56
#define MREC_VOLUME
Definition: files.c:35
#define MREC_DELETED
Definition: files.c:49
#define COLL_SID
Definition: files.c:66
#define MREC_TXF
Definition: files.c:51
#define MREC_SECURE
Definition: files.c:41
static VOID MkStdInfoShort(OUT PBYTE Out, IN ULONG FileAttributes, IN ULONGLONG Now)
Definition: files.c:377
#define MREC_UPCASE
Definition: files.c:42
#define WR32(p, o, v)
Definition: files.c:78
#define MREC_CONT1
Definition: files.c:54
#define MREC_BADCLUS
Definition: files.c:40
#define MREC_BITMAP
Definition: files.c:38
#define MREC_TXFLOG
Definition: files.c:50
static ULONG MkViewRootN(OUT PBYTE Out, IN ULONG CollationRule, IN const MK_VIEW_ENTRY *Entries, IN ULONG Count)
Definition: files.c:591
static VOID MkRootIndxBlock(OUT PBYTE Blk, IN const BYTE *Mft, IN const ULONG *Order, IN ULONG Count)
Definition: files.c:725
static NTSTATUS WritePatternToClusters(IN ULONGLONG Address, IN ULONG ClustersCount, IN BYTE Pattern)
Definition: files.c:789
#define MREC_MFTMIRR
Definition: files.c:33
#define MREC_ROOT
Definition: files.c:37
static VOID MkStdInfo(OUT PBYTE Out, IN ULONG FileAttributes, IN ULONGLONG Now, IN ULONG SecurityId)
Definition: files.c:359
#define MREC_BOOT
Definition: files.c:39
#define MREC_TXFBLF
Definition: files.c:53
#define MREC_RMMETA
Definition: files.c:47
#define MREC_OBJID
Definition: files.c:45
static ULONG MkI30RootWithEntries(OUT PBYTE Out, IN const BYTE *Mft, IN const ULONG *Order, IN ULONG Count)
Definition: files.c:499
#define WR64(p, o, v)
Definition: files.c:79
#define MREC_LOGFILE
Definition: files.c:34
#define MREC_REPAIR
Definition: files.c:48
static ULONG MkSecHash(IN const BYTE *Sd, IN ULONG Len)
Definition: files.c:639
#define FA_DIR
Definition: files.c:62
static NTSTATUS WriteAt(IN ULONGLONG Lcn, IN PVOID Buffer, IN ULONG Length)
Definition: files.c:774
#define FA_ARCHIVE
Definition: files.c:61
static ULONG MkLargeI30Root(OUT PBYTE Out)
Definition: files.c:478
#define HOLE_LCN
Definition: files.c:72
#define MREC_REPARSE
Definition: files.c:46
static VOID MkSetHardLinks(IN MK_REC *Rec, IN USHORT Count)
Definition: files.c:222
#define REC_BUF(n)
static ULONG MkLargeViewRoot(OUT PBYTE Out, IN ULONG CollationRule)
Definition: files.c:568
#define FA_SYSTEM
Definition: files.c:60
static ULONG MkEmptyViewRoot(OUT PBYTE Out, IN ULONG CollationRule)
Definition: files.c:548
#define MREC_CONT2
Definition: files.c:55
static ULONG MkEmptyI30Root(OUT PBYTE Out)
Definition: files.c:458
#define MREC_ATTRDEF
Definition: files.c:36
static VOID MkAddResident(IN OUT MK_REC *Rec, IN ULONG Type, IN LPCWSTR Name, IN BYTE NameChars, IN BYTE ResidentFlags, IN const VOID *Value, IN ULONG ValueLen)
Definition: files.c:231
#define MREC_QUOTA
Definition: files.c:44
#define FA_HIDDEN
Definition: files.c:59
static NTSTATUS WriteZerosToClusters(IN ULONGLONG Address, IN ULONG ClustersCount)
Definition: files.c:836
static VOID MkFinalize(IN MK_REC *Rec)
Definition: files.c:327
static VOID MkInit(OUT MK_REC *Rec, IN PBYTE Buf, IN ULONG RecordNumber, IN USHORT Flags)
Definition: files.c:193
#define COLL_ULONGS
Definition: files.c:67
static VOID MkViewIndxBlock(OUT PBYTE Blk, IN const MK_VIEW_ENTRY *Entries, IN ULONG Count)
Definition: files.c:675
#define MREC_MFT
Definition: files.c:32
#define MREC_TOPS
Definition: files.c:52
#define FA_VIEW
Definition: files.c:63
static ULONG MkFileName(OUT PBYTE Out, IN ULONGLONG ParentRef, IN ULONG FileAttributes, IN ULONGLONG AllocSize, IN ULONGLONG RealSize, IN ULONGLONG Now, IN LPCWSTR Name, IN BYTE Namespace)
Definition: files.c:391
#define MREC_EXTEND
Definition: files.c:43
static NTSTATUS WriteRegion(IN ULONGLONG Lcn, IN ULONG Clusters, IN const VOID *Content, IN ULONG ContentLen)
Definition: files.c:845
static VOID MkAddNonResident(IN OUT MK_REC *Rec, IN ULONG Type, IN LPCWSTR Name, IN BYTE NameChars, IN USHORT Flags, IN const MK_RUN *Runs, IN ULONG RunCount, IN ULONGLONG HighVcn, IN ULONGLONG AllocSize, IN ULONGLONG RealSize, IN ULONGLONG InitSize)
Definition: files.c:267
struct tm * Now
Definition: output.c:19
Definition: files.c:95
Definition: files.c:89
Definition: files.c:102
USHORT DataLen
Definition: files.c:106
USHORT KeyLen
Definition: files.c:104
const BYTE * Key
Definition: files.c:103
const BYTE * Data
Definition: files.c:105
ULONG Runs
Definition: symtest.c:7
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by NtfsFormat().

Variable Documentation

◆ NtfsFormatData

NTFS_FORMAT_DATA NtfsFormatData
extern

Definition at line 20 of file ntfslib.c.

Referenced by NtfsFormat().