ReactOS  0.4.14-dev-317-g96040ec
ntfs.h File Reference
#include <ntifs.h>
#include <pseh/pseh2.h>
#include <section_attribs.h>
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for ntfs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _BIOS_PARAMETERS_BLOCK
 
struct  _EXTENDED_BIOS_PARAMETERS_BLOCK
 
struct  _BOOT_SECTOR
 
struct  _NTFS_INFO
 
struct  NTFSIDENTIFIER
 
struct  DEVICE_EXTENSION
 
struct  NTFS_CCB
 
struct  NTFS_GLOBAL_DATA
 
struct  NTFS_RECORD_HEADER
 
struct  _FILE_RECORD_HEADER
 
struct  NTFS_ATTR_RECORD
 
struct  NTFS_ATTRIBUTE_LIST_ITEM
 
struct  STANDARD_INFORMATION
 
struct  ATTRIBUTE_LIST
 
struct  FILENAME_ATTRIBUTE
 
struct  INDEX_HEADER_ATTRIBUTE
 
struct  INDEX_ROOT_ATTRIBUTE
 
struct  INDEX_BUFFER
 
struct  INDEX_ENTRY_ATTRIBUTE
 
struct  _B_TREE_KEY
 
struct  _B_TREE_FILENAME_NODE
 
struct  B_TREE
 
struct  VOLINFO_ATTRIBUTE
 
struct  REPARSE_POINT_ATTRIBUTE
 
struct  NTFS_IRP_CONTEXT
 
struct  _NTFS_ATTR_CONTEXT
 
struct  _FCB
 
struct  _FIND_ATTR_CONTXT
 
struct  FIXUP_ARRAY
 

Macros

#define CACHEPAGESIZE(pDeviceExt)
 
#define TAG_NTFS   '0ftN'
 
#define TAG_CCB   'CftN'
 
#define TAG_FCB   'FftN'
 
#define TAG_IRP_CTXT   'iftN'
 
#define TAG_ATT_CTXT   'aftN'
 
#define TAG_FILE_REC   'rftN'
 
#define ROUND_UP(N, S)   ((((N) + (S) - 1) / (S)) * (S))
 
#define ROUND_DOWN(N, S)   ((N) - ((N) % (S)))
 
#define DEVICE_NAME   L"\\Ntfs"
 
#define NTFS_TYPE_CCB   '20SF'
 
#define NTFS_TYPE_FCB   '30SF'
 
#define NTFS_TYPE_VCB   '50SF'
 
#define NTFS_TYPE_IRP_CONTEXT   '60SF'
 
#define NTFS_TYPE_GLOBAL_DATA   '70SF'
 
#define VCB_VOLUME_LOCKED   0x0001
 
#define FILE_RECORD_END   0x11477982
 
#define NTFS_FILE_MFT   0
 
#define NTFS_FILE_MFTMIRR   1
 
#define NTFS_FILE_LOGFILE   2
 
#define NTFS_FILE_VOLUME   3
 
#define NTFS_FILE_ATTRDEF   4
 
#define NTFS_FILE_ROOT   5
 
#define NTFS_FILE_BITMAP   6
 
#define NTFS_FILE_BOOT   7
 
#define NTFS_FILE_BADCLUS   8
 
#define NTFS_FILE_QUOTA   9
 
#define NTFS_FILE_UPCASE   10
 
#define NTFS_FILE_EXTEND   11
 
#define NTFS_FILE_FIRST_USER_FILE   16
 
#define NTFS_MFT_MASK   0x0000FFFFFFFFFFFFULL
 
#define COLLATION_BINARY   0x00
 
#define COLLATION_FILE_NAME   0x01
 
#define COLLATION_UNICODE_STRING   0x02
 
#define COLLATION_NTOFS_ULONG   0x10
 
#define COLLATION_NTOFS_SID   0x11
 
#define COLLATION_NTOFS_SECURITY_HASH   0x12
 
#define COLLATION_NTOFS_ULONGS   0x13
 
#define INDEX_ROOT_SMALL   0x0
 
#define INDEX_ROOT_LARGE   0x1
 
#define INDEX_NODE_SMALL   0x0
 
#define INDEX_NODE_LARGE   0x1
 
#define NTFS_INDEX_ENTRY_NODE   1
 
#define NTFS_INDEX_ENTRY_END   2
 
#define NTFS_FILE_NAME_POSIX   0
 
#define NTFS_FILE_NAME_WIN32   1
 
#define NTFS_FILE_NAME_DOS   2
 
#define NTFS_FILE_NAME_WIN32_AND_DOS   3
 
#define NTFS_FILE_TYPE_READ_ONLY   0x1
 
#define NTFS_FILE_TYPE_HIDDEN   0x2
 
#define NTFS_FILE_TYPE_SYSTEM   0x4
 
#define NTFS_FILE_TYPE_ARCHIVE   0x20
 
#define NTFS_FILE_TYPE_REPARSE   0x400
 
#define NTFS_FILE_TYPE_COMPRESSED   0x800
 
#define NTFS_FILE_TYPE_DIRECTORY   0x10000000
 
#define RA_INDEXED   0x01
 
#define NRH_FILE_TYPE   0x454C4946 /* 'FILE' */
 
#define NRH_INDX_TYPE   0x58444E49 /* 'INDX' */
 
#define FRH_IN_USE   0x0001 /* Record is in use */
 
#define FRH_DIRECTORY   0x0002 /* Record is a directory */
 
#define FRH_UNKNOWN1   0x0004 /* Don't know */
 
#define FRH_UNKNOWN2   0x0008 /* Don't know */
 
#define ATTR_RECORD_ALIGNMENT   8
 
#define DATA_RUN_ALIGNMENT   4
 
#define VALUE_OFFSET_ALIGNMENT   4
 
#define IRPCONTEXT_CANWAIT   0x1
 
#define IRPCONTEXT_COMPLETE   0x2
 
#define IRPCONTEXT_QUEUE   0x4
 
#define FCB_CACHE_INITIALIZED   0x0001
 
#define FCB_IS_VOLUME_STREAM   0x0002
 
#define FCB_IS_VOLUME   0x0004
 
#define MAX_PATH   260
 

Typedefs

typedef struct _BIOS_PARAMETERS_BLOCK BIOS_PARAMETERS_BLOCK
 
typedef struct _BIOS_PARAMETERS_BLOCKPBIOS_PARAMETERS_BLOCK
 
typedef struct _EXTENDED_BIOS_PARAMETERS_BLOCK EXTENDED_BIOS_PARAMETERS_BLOCK
 
typedef struct _EXTENDED_BIOS_PARAMETERS_BLOCKPEXTENDED_BIOS_PARAMETERS_BLOCK
 
typedef struct _BOOT_SECTOR BOOT_SECTOR
 
typedef struct _BOOT_SECTORPBOOT_SECTOR
 
typedef struct _NTFS_INFO NTFS_INFO
 
typedef struct _NTFS_INFOPNTFS_INFO
 
typedef struct NTFSIDENTIFIERPNTFSIDENTIFIER
 
typedef struct DEVICE_EXTENSIONPDEVICE_EXTENSION
 
typedef struct DEVICE_EXTENSION NTFS_VCB
 
typedef struct DEVICE_EXTENSIONPNTFS_VCB
 
typedef struct NTFS_CCBPNTFS_CCB
 
typedef struct NTFS_GLOBAL_DATAPNTFS_GLOBAL_DATA
 
typedef enum ATTRIBUTE_TYPEPATTRIBUTE_TYPE
 
typedef struct NTFS_RECORD_HEADERPNTFS_RECORD_HEADER
 
typedef struct _FILE_RECORD_HEADER FILE_RECORD_HEADER
 
typedef struct _FILE_RECORD_HEADERPFILE_RECORD_HEADER
 
typedef struct NTFS_ATTR_RECORDPNTFS_ATTR_RECORD
 
typedef struct NTFS_ATTRIBUTE_LIST_ITEMPNTFS_ATTRIBUTE_LIST_ITEM
 
typedef struct STANDARD_INFORMATIONPSTANDARD_INFORMATION
 
typedef struct ATTRIBUTE_LISTPATTRIBUTE_LIST
 
typedef struct FILENAME_ATTRIBUTEPFILENAME_ATTRIBUTE
 
typedef struct INDEX_HEADER_ATTRIBUTEPINDEX_HEADER_ATTRIBUTE
 
typedef struct INDEX_ROOT_ATTRIBUTEPINDEX_ROOT_ATTRIBUTE
 
typedef struct INDEX_BUFFERPINDEX_BUFFER
 
typedef struct INDEX_ENTRY_ATTRIBUTEPINDEX_ENTRY_ATTRIBUTE
 
typedef struct _B_TREE_FILENAME_NODE B_TREE_FILENAME_NODE
 
typedef struct _B_TREE_KEY B_TREE_KEY
 
typedef struct _B_TREE_KEYPB_TREE_KEY
 
typedef struct _B_TREE_FILENAME_NODEPB_TREE_FILENAME_NODE
 
typedef struct B_TREEPB_TREE
 
typedef struct VOLINFO_ATTRIBUTEPVOLINFO_ATTRIBUTE
 
typedef struct REPARSE_POINT_ATTRIBUTEPREPARSE_POINT_ATTRIBUTE
 
typedef struct NTFS_IRP_CONTEXTPNTFS_IRP_CONTEXT
 
typedef struct _NTFS_ATTR_CONTEXT NTFS_ATTR_CONTEXT
 
typedef struct _NTFS_ATTR_CONTEXTPNTFS_ATTR_CONTEXT
 
typedef struct _FCB NTFS_FCB
 
typedef struct _FCBPNTFS_FCB
 
typedef struct _FIND_ATTR_CONTXT FIND_ATTR_CONTXT
 
typedef struct _FIND_ATTR_CONTXTPFIND_ATTR_CONTXT
 
typedef struct FIXUP_ARRAYPFIXUP_ARRAY
 

Enumerations

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, 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

FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS AddBitmap (PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PCWSTR Name, USHORT NameLength)
 
NTSTATUS AddData (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
 
NTSTATUS AddRun (PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONGLONG NextAssignedCluster, ULONG RunLength)
 
NTSTATUS AddIndexAllocation (PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PCWSTR Name, USHORT NameLength)
 
NTSTATUS AddIndexRoot (PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PINDEX_ROOT_ATTRIBUTE NewIndexRoot, ULONG RootLength, PCWSTR Name, USHORT NameLength)
 
NTSTATUS AddFileName (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PULONGLONG ParentMftIndex)
 
NTSTATUS AddStandardInformation (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
 
NTSTATUS ConvertDataRunsToLargeMCB (PUCHAR DataRun, PLARGE_MCB DataRunsMCB, PULONGLONG pNextVBN)
 
NTSTATUS ConvertLargeMCBToDataRuns (PLARGE_MCB DataRunsMCB, PUCHAR RunBuffer, ULONG MaxBufferSize, PULONG UsedBufferSize)
 
PUCHAR DecodeRun (PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
 
ULONG GetFileNameAttributeLength (PFILENAME_ATTRIBUTE FileNameAttribute)
 
VOID NtfsDumpDataRuns (PVOID StartOfRun, ULONGLONG CurrentLCN)
 
VOID NtfsDumpFileAttributes (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
 
PSTANDARD_INFORMATION GetStandardInformationFromRecord (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
 
PFILENAME_ATTRIBUTE GetFileNameFromRecord (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, UCHAR NameType)
 
UCHAR GetPackedByteCount (LONGLONG NumberToPack, BOOLEAN IsSigned)
 
NTSTATUS GetLastClusterInDataRun (PDEVICE_EXTENSION Vcb, PNTFS_ATTR_RECORD Attribute, PULONGLONG LastCluster)
 
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
 
NTSTATUS FindFirstAttributeListItem (PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
 
NTSTATUS FindNextAttributeListItem (PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
 
NTSTATUS FindFirstAttribute (PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
 
NTSTATUS FindNextAttribute (PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
 
VOID FindCloseAttribute (PFIND_ATTR_CONTXT Context)
 
NTSTATUS FreeClusters (PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONG ClustersToFree)
 
NTSTATUS NtfsReadDisk (IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
 
NTSTATUS NtfsWriteDisk (IN PDEVICE_OBJECT DeviceObject, IN LONGLONG StartingOffset, IN ULONG Length, IN ULONG SectorSize, IN const PUCHAR Buffer)
 
NTSTATUS NtfsReadSectors (IN PDEVICE_OBJECT DeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
 
NTSTATUS NtfsDeviceIoControl (IN PDEVICE_OBJECT DeviceObject, IN ULONG ControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer, IN OUT PULONG OutputBufferSize, IN BOOLEAN Override)
 
LONG CompareTreeKeys (PB_TREE_KEY Key1, PB_TREE_KEY Key2, BOOLEAN CaseSensitive)
 
NTSTATUS CreateBTreeFromIndex (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecordWithIndex, PNTFS_ATTR_CONTEXT IndexRootContext, PINDEX_ROOT_ATTRIBUTE IndexRoot, PB_TREE *NewTree)
 
NTSTATUS CreateIndexRootFromBTree (PDEVICE_EXTENSION DeviceExt, PB_TREE Tree, ULONG MaxIndexSize, PINDEX_ROOT_ATTRIBUTE *IndexRoot, ULONG *Length)
 
NTSTATUS DemoteBTreeRoot (PB_TREE Tree)
 
VOID DestroyBTree (PB_TREE Tree)
 
VOID DestroyBTreeNode (PB_TREE_FILENAME_NODE Node)
 
VOID DumpBTree (PB_TREE Tree)
 
VOID DumpBTreeKey (PB_TREE Tree, PB_TREE_KEY Key, ULONG Number, ULONG Depth)
 
VOID DumpBTreeNode (PB_TREE Tree, PB_TREE_FILENAME_NODE Node, ULONG Number, ULONG Depth)
 
NTSTATUS CreateEmptyBTree (PB_TREE *NewTree)
 
ULONGLONG GetAllocationOffsetFromVCN (PDEVICE_EXTENSION DeviceExt, ULONG IndexBufferSize, ULONGLONG Vcn)
 
ULONGLONG GetIndexEntryVCN (PINDEX_ENTRY_ATTRIBUTE IndexEntry)
 
ULONG GetSizeOfIndexEntries (PB_TREE_FILENAME_NODE Node)
 
NTSTATUS NtfsInsertKey (PB_TREE Tree, ULONGLONG FileReference, PFILENAME_ATTRIBUTE FileNameAttribute, PB_TREE_FILENAME_NODE Node, BOOLEAN CaseSensitive, ULONG MaxIndexRootSize, ULONG IndexRecordSize, PB_TREE_KEY *MedianKey, PB_TREE_FILENAME_NODE *NewRightHandSibling)
 
NTSTATUS SplitBTreeNode (PB_TREE Tree, PB_TREE_FILENAME_NODE Node, PB_TREE_KEY *MedianKey, PB_TREE_FILENAME_NODE *NewRightHandSibling, BOOLEAN CaseSensitive)
 
NTSTATUS UpdateIndexAllocation (PDEVICE_EXTENSION DeviceExt, PB_TREE Tree, ULONG IndexBufferSize, PFILE_RECORD_HEADER FileRecord)
 
NTSTATUS UpdateIndexNode (PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, PB_TREE_FILENAME_NODE Node, ULONG IndexBufferSize, PNTFS_ATTR_CONTEXT IndexAllocationContext, ULONG IndexAllocationOffset)
 
NTSTATUS NtfsCleanup (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
 
NTSTATUS NtfsClose (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsCreate (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsCreateDirectory (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, BOOLEAN CanWait)
 
PFILE_RECORD_HEADER NtfsCreateEmptyFileRecord (PDEVICE_EXTENSION DeviceExt)
 
NTSTATUS NtfsCreateFileRecord (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, BOOLEAN CanWait)
 
NTSTATUS NtfsDeviceControl (PNTFS_IRP_CONTEXT IrpContext)
 
ULONGLONG NtfsGetFileSize (PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, PCWSTR Stream, ULONG StreamLength, PULONGLONG AllocatedSize)
 
NTSTATUS NtfsDirectoryControl (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NTAPI NtfsFsdDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
BOOLEAN NTAPI NtfsAcqLazyWrite (PVOID Context, BOOLEAN Wait)
 
VOID NTAPI NtfsRelLazyWrite (PVOID Context)
 
BOOLEAN NTAPI NtfsAcqReadAhead (PVOID Context, BOOLEAN Wait)
 
VOID NTAPI NtfsRelReadAhead (PVOID Context)
 
PNTFS_FCB NtfsCreateFCB (PCWSTR FileName, PCWSTR Stream, PNTFS_VCB Vcb)
 
VOID NtfsDestroyFCB (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsDirectory (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsReparsePoint (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsCompressed (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsRoot (PNTFS_FCB Fcb)
 
VOID NtfsGrabFCB (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
VOID NtfsReleaseFCB (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
VOID NtfsAddFCBToTable (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
PNTFS_FCB NtfsGrabFCBFromTable (PNTFS_VCB Vcb, PCWSTR FileName)
 
NTSTATUS NtfsFCBInitializeCache (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
PNTFS_FCB NtfsMakeRootFCB (PNTFS_VCB Vcb)
 
PNTFS_FCB NtfsOpenRootFCB (PNTFS_VCB Vcb)
 
NTSTATUS NtfsAttachFCBToFileObject (PNTFS_VCB Vcb, PNTFS_FCB Fcb, PFILE_OBJECT FileObject)
 
NTSTATUS NtfsGetFCBForFile (PNTFS_VCB Vcb, PNTFS_FCB *pParentFCB, PNTFS_FCB *pFCB, PCWSTR pFileName, BOOLEAN CaseSensitive)
 
NTSTATUS NtfsReadFCBAttribute (PNTFS_VCB Vcb, PNTFS_FCB pFCB, ULONG Type, PCWSTR Name, ULONG NameLength, PVOID *Data)
 
NTSTATUS NtfsMakeFCBFromDirEntry (PNTFS_VCB Vcb, PNTFS_FCB DirectoryFCB, PUNICODE_STRING Name, PCWSTR Stream, PFILE_RECORD_HEADER Record, ULONGLONG MFTIndex, PNTFS_FCB *fileFCB)
 
NTSTATUS NtfsQueryInformation (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsSetEndOfFile (PNTFS_FCB Fcb, PFILE_OBJECT FileObject, PDEVICE_EXTENSION DeviceExt, ULONG IrpFlags, BOOLEAN CaseSensitive, PLARGE_INTEGER NewFileSize)
 
NTSTATUS NtfsSetInformation (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsFileSystemControl (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsAddFilenameToDirectory (PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
 
NTSTATUS AddNewMftEntry (PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, PULONGLONG DestinationIndex, BOOLEAN CanWait)
 
VOID NtfsDumpData (ULONG_PTR Buffer, ULONG Length)
 
PNTFS_ATTR_CONTEXT PrepareAttributeContext (PNTFS_ATTR_RECORD AttrRecord)
 
VOID ReleaseAttributeContext (PNTFS_ATTR_CONTEXT Context)
 
ULONG ReadAttribute (PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
 
NTSTATUS WriteAttribute (PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG LengthWritten, PFILE_RECORD_HEADER FileRecord)
 
ULONGLONG AttributeDataLength (PNTFS_ATTR_RECORD AttrRecord)
 
NTSTATUS InternalSetResidentAttributeLength (PDEVICE_EXTENSION DeviceExt, PNTFS_ATTR_CONTEXT AttrContext, PFILE_RECORD_HEADER FileRecord, ULONG AttrOffset, ULONG DataSize)
 
PNTFS_ATTR_RECORD MoveAttributes (PDEVICE_EXTENSION DeviceExt, PNTFS_ATTR_RECORD FirstAttributeToMove, ULONG FirstAttributeOffset, ULONG_PTR MoveTo)
 
NTSTATUS SetAttributeDataLength (PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
 
VOID SetFileRecordEnd (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
 
NTSTATUS SetNonResidentAttributeDataLength (PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
 
NTSTATUS SetResidentAttributeDataLength (PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
 
ULONGLONG AttributeAllocatedLength (PNTFS_ATTR_RECORD AttrRecord)
 
BOOLEAN CompareFileName (PUNICODE_STRING FileName, PINDEX_ENTRY_ATTRIBUTE IndexEntry, BOOLEAN DirSearch, BOOLEAN CaseSensitive)
 
NTSTATUS UpdateMftMirror (PNTFS_VCB Vcb)
 
NTSTATUS ReadFileRecord (PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
 
NTSTATUS UpdateIndexEntryFileNameSize (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, PCHAR IndexRecord, ULONG IndexBlockSize, PINDEX_ENTRY_ATTRIBUTE FirstEntry, PINDEX_ENTRY_ATTRIBUTE LastEntry, PUNICODE_STRING FileName, PULONG StartEntry, PULONG CurrentEntry, BOOLEAN DirSearch, ULONGLONG NewDataSize, ULONGLONG NewAllocatedSize, BOOLEAN CaseSensitive)
 
NTSTATUS UpdateFileNameRecord (PDEVICE_EXTENSION Vcb, ULONGLONG ParentMFTIndex, PUNICODE_STRING FileName, BOOLEAN DirSearch, ULONGLONG NewDataSize, ULONGLONG NewAllocationSize, BOOLEAN CaseSensitive)
 
NTSTATUS UpdateFileRecord (PDEVICE_EXTENSION Vcb, ULONGLONG MftIndex, PFILE_RECORD_HEADER FileRecord)
 
NTSTATUS FindAttribute (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
 
VOID ReadVCN (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER file, ATTRIBUTE_TYPE type, ULONGLONG vcn, ULONG count, PVOID buffer)
 
NTSTATUS FixupUpdateSequenceArray (PDEVICE_EXTENSION Vcb, PNTFS_RECORD_HEADER Record)
 
NTSTATUS AddFixupArray (PDEVICE_EXTENSION Vcb, PNTFS_RECORD_HEADER Record)
 
NTSTATUS ReadLCN (PDEVICE_EXTENSION Vcb, ULONGLONG lcn, ULONG count, PVOID buffer)
 
VOID EnumerAttribute (PFILE_RECORD_HEADER file, PDEVICE_EXTENSION Vcb, PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NtfsLookupFile (PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, BOOLEAN CaseSensitive, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex)
 
NTSTATUS NtfsLookupFileAt (PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, BOOLEAN CaseSensitive, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex)
 
VOID NtfsDumpFileRecord (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
 
NTSTATUS NtfsFindFileAt (PDEVICE_EXTENSION Vcb, PUNICODE_STRING SearchPattern, PULONG FirstEntry, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex, BOOLEAN CaseSensitive)
 
NTSTATUS NtfsFindMftRecord (PDEVICE_EXTENSION Vcb, ULONGLONG MFTIndex, PUNICODE_STRING FileName, PULONG FirstEntry, BOOLEAN DirSearch, BOOLEAN CaseSensitive, ULONGLONG *OutMFTIndex)
 
BOOLEAN NtfsIsIrpTopLevel (PIRP Irp)
 
PNTFS_IRP_CONTEXT NtfsAllocateIrpContext (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
PVOID NtfsGetUserBuffer (PIRP Irp, BOOLEAN Paging)
 
NTSTATUS NtfsLockUserBuffer (IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
 
VOID NtfsFileFlagsToAttributes (ULONG NtfsAttributes, PULONG FileAttributes)
 
NTSTATUS NtfsRead (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsWrite (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsAllocateClusters (PDEVICE_EXTENSION DeviceExt, ULONG FirstDesiredCluster, ULONG DesiredClusters, PULONG FirstAssignedCluster, PULONG AssignedClusters)
 
ULONGLONG NtfsGetFreeClusters (PDEVICE_EXTENSION DeviceExt)
 
NTSTATUS NtfsQueryVolumeInformation (PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsSetVolumeInformation (PNTFS_IRP_CONTEXT IrpContext)
 
INIT_FUNCTION VOID NTAPI NtfsInitializeFunctionPointers (PDRIVER_OBJECT DriverObject)
 

Variables

PNTFS_GLOBAL_DATA NtfsGlobalData
 
DRIVER_DISPATCH NtfsFsdDispatch
 
FAST_IO_CHECK_IF_POSSIBLE NtfsFastIoCheckIfPossible
 
FAST_IO_READ NtfsFastIoRead
 
FAST_IO_WRITE NtfsFastIoWrite
 
INIT_FUNCTION DRIVER_INITIALIZE DriverEntry
 

Macro Definition Documentation

◆ ATTR_RECORD_ALIGNMENT

#define ATTR_RECORD_ALIGNMENT   8

Definition at line 316 of file ntfs.h.

◆ CACHEPAGESIZE

#define CACHEPAGESIZE (   pDeviceExt)
Value:
((pDeviceExt)->NtfsInfo.UCHARsPerCluster > PAGE_SIZE ? \
(pDeviceExt)->NtfsInfo.UCHARsPerCluster : PAGE_SIZE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49

Definition at line 8 of file ntfs.h.

◆ COLLATION_BINARY

#define COLLATION_BINARY   0x00

Definition at line 200 of file ntfs.h.

◆ COLLATION_FILE_NAME

#define COLLATION_FILE_NAME   0x01

Definition at line 201 of file ntfs.h.

◆ COLLATION_NTOFS_SECURITY_HASH

#define COLLATION_NTOFS_SECURITY_HASH   0x12

Definition at line 205 of file ntfs.h.

◆ COLLATION_NTOFS_SID

#define COLLATION_NTOFS_SID   0x11

Definition at line 204 of file ntfs.h.

◆ COLLATION_NTOFS_ULONG

#define COLLATION_NTOFS_ULONG   0x10

Definition at line 203 of file ntfs.h.

◆ COLLATION_NTOFS_ULONGS

#define COLLATION_NTOFS_ULONGS   0x13

Definition at line 206 of file ntfs.h.

◆ COLLATION_UNICODE_STRING

#define COLLATION_UNICODE_STRING   0x02

Definition at line 202 of file ntfs.h.

◆ DATA_RUN_ALIGNMENT

#define DATA_RUN_ALIGNMENT   4

Definition at line 319 of file ntfs.h.

◆ DEVICE_NAME

#define DEVICE_NAME   L"\\Ntfs"

Definition at line 22 of file ntfs.h.

◆ FCB_CACHE_INITIALIZED

#define FCB_CACHE_INITIALIZED   0x0001

Definition at line 504 of file ntfs.h.

◆ FCB_IS_VOLUME

#define FCB_IS_VOLUME   0x0004

Definition at line 506 of file ntfs.h.

◆ FCB_IS_VOLUME_STREAM

#define FCB_IS_VOLUME_STREAM   0x0002

Definition at line 505 of file ntfs.h.

◆ FILE_RECORD_END

#define FILE_RECORD_END   0x11477982

Definition at line 182 of file ntfs.h.

◆ FRH_DIRECTORY

#define FRH_DIRECTORY   0x0002 /* Record is a directory */

Definition at line 264 of file ntfs.h.

◆ FRH_IN_USE

#define FRH_IN_USE   0x0001 /* Record is in use */

Definition at line 263 of file ntfs.h.

◆ FRH_UNKNOWN1

#define FRH_UNKNOWN1   0x0004 /* Don't know */

Definition at line 265 of file ntfs.h.

◆ FRH_UNKNOWN2

#define FRH_UNKNOWN2   0x0008 /* Don't know */

Definition at line 266 of file ntfs.h.

◆ INDEX_NODE_LARGE

#define INDEX_NODE_LARGE   0x1

Definition at line 212 of file ntfs.h.

◆ INDEX_NODE_SMALL

#define INDEX_NODE_SMALL   0x0

Definition at line 211 of file ntfs.h.

◆ INDEX_ROOT_LARGE

#define INDEX_ROOT_LARGE   0x1

Definition at line 209 of file ntfs.h.

◆ INDEX_ROOT_SMALL

#define INDEX_ROOT_SMALL   0x0

Definition at line 208 of file ntfs.h.

◆ IRPCONTEXT_CANWAIT

#define IRPCONTEXT_CANWAIT   0x1

Definition at line 470 of file ntfs.h.

◆ IRPCONTEXT_COMPLETE

#define IRPCONTEXT_COMPLETE   0x2

Definition at line 471 of file ntfs.h.

◆ IRPCONTEXT_QUEUE

#define IRPCONTEXT_QUEUE   0x4

Definition at line 472 of file ntfs.h.

◆ MAX_PATH

#define MAX_PATH   260

Definition at line 507 of file ntfs.h.

◆ NRH_FILE_TYPE

#define NRH_FILE_TYPE   0x454C4946 /* 'FILE' */

Definition at line 242 of file ntfs.h.

◆ NRH_INDX_TYPE

#define NRH_INDX_TYPE   0x58444E49 /* 'INDX' */

Definition at line 243 of file ntfs.h.

◆ NTFS_FILE_ATTRDEF

#define NTFS_FILE_ATTRDEF   4

Definition at line 188 of file ntfs.h.

◆ NTFS_FILE_BADCLUS

#define NTFS_FILE_BADCLUS   8

Definition at line 192 of file ntfs.h.

◆ NTFS_FILE_BITMAP

#define NTFS_FILE_BITMAP   6

Definition at line 190 of file ntfs.h.

◆ NTFS_FILE_BOOT

#define NTFS_FILE_BOOT   7

Definition at line 191 of file ntfs.h.

◆ NTFS_FILE_EXTEND

#define NTFS_FILE_EXTEND   11

Definition at line 195 of file ntfs.h.

◆ NTFS_FILE_FIRST_USER_FILE

#define NTFS_FILE_FIRST_USER_FILE   16

Definition at line 196 of file ntfs.h.

◆ NTFS_FILE_LOGFILE

#define NTFS_FILE_LOGFILE   2

Definition at line 186 of file ntfs.h.

◆ NTFS_FILE_MFT

#define NTFS_FILE_MFT   0

Definition at line 184 of file ntfs.h.

◆ NTFS_FILE_MFTMIRR

#define NTFS_FILE_MFTMIRR   1

Definition at line 185 of file ntfs.h.

◆ NTFS_FILE_NAME_DOS

#define NTFS_FILE_NAME_DOS   2

Definition at line 219 of file ntfs.h.

◆ NTFS_FILE_NAME_POSIX

#define NTFS_FILE_NAME_POSIX   0

Definition at line 217 of file ntfs.h.

◆ NTFS_FILE_NAME_WIN32

#define NTFS_FILE_NAME_WIN32   1

Definition at line 218 of file ntfs.h.

◆ NTFS_FILE_NAME_WIN32_AND_DOS

#define NTFS_FILE_NAME_WIN32_AND_DOS   3

Definition at line 220 of file ntfs.h.

◆ NTFS_FILE_QUOTA

#define NTFS_FILE_QUOTA   9

Definition at line 193 of file ntfs.h.

◆ NTFS_FILE_ROOT

#define NTFS_FILE_ROOT   5

Definition at line 189 of file ntfs.h.

◆ NTFS_FILE_TYPE_ARCHIVE

#define NTFS_FILE_TYPE_ARCHIVE   0x20

Definition at line 225 of file ntfs.h.

◆ NTFS_FILE_TYPE_COMPRESSED

#define NTFS_FILE_TYPE_COMPRESSED   0x800

Definition at line 227 of file ntfs.h.

◆ NTFS_FILE_TYPE_DIRECTORY

#define NTFS_FILE_TYPE_DIRECTORY   0x10000000

Definition at line 228 of file ntfs.h.

◆ NTFS_FILE_TYPE_HIDDEN

#define NTFS_FILE_TYPE_HIDDEN   0x2

Definition at line 223 of file ntfs.h.

◆ NTFS_FILE_TYPE_READ_ONLY

#define NTFS_FILE_TYPE_READ_ONLY   0x1

Definition at line 222 of file ntfs.h.

◆ NTFS_FILE_TYPE_REPARSE

#define NTFS_FILE_TYPE_REPARSE   0x400

Definition at line 226 of file ntfs.h.

◆ NTFS_FILE_TYPE_SYSTEM

#define NTFS_FILE_TYPE_SYSTEM   0x4

Definition at line 224 of file ntfs.h.

◆ NTFS_FILE_UPCASE

#define NTFS_FILE_UPCASE   10

Definition at line 194 of file ntfs.h.

◆ NTFS_FILE_VOLUME

#define NTFS_FILE_VOLUME   3

Definition at line 187 of file ntfs.h.

◆ NTFS_INDEX_ENTRY_END

#define NTFS_INDEX_ENTRY_END   2

Definition at line 215 of file ntfs.h.

◆ NTFS_INDEX_ENTRY_NODE

#define NTFS_INDEX_ENTRY_NODE   1

Definition at line 214 of file ntfs.h.

◆ NTFS_MFT_MASK

#define NTFS_MFT_MASK   0x0000FFFFFFFFFFFFULL

Definition at line 198 of file ntfs.h.

◆ NTFS_TYPE_CCB

#define NTFS_TYPE_CCB   '20SF'

Definition at line 87 of file ntfs.h.

◆ NTFS_TYPE_FCB

#define NTFS_TYPE_FCB   '30SF'

Definition at line 88 of file ntfs.h.

◆ NTFS_TYPE_GLOBAL_DATA

#define NTFS_TYPE_GLOBAL_DATA   '70SF'

Definition at line 91 of file ntfs.h.

◆ NTFS_TYPE_IRP_CONTEXT

#define NTFS_TYPE_IRP_CONTEXT   '60SF'

Definition at line 90 of file ntfs.h.

◆ NTFS_TYPE_VCB

#define NTFS_TYPE_VCB   '50SF'

Definition at line 89 of file ntfs.h.

◆ RA_INDEXED

#define RA_INDEXED   0x01

Definition at line 231 of file ntfs.h.

◆ ROUND_DOWN

#define ROUND_DOWN (   N,
  S 
)    ((N) - ((N) % (S)))

Definition at line 20 of file ntfs.h.

◆ ROUND_UP

#define ROUND_UP (   N,
  S 
)    ((((N) + (S) - 1) / (S)) * (S))

Definition at line 19 of file ntfs.h.

◆ TAG_ATT_CTXT

#define TAG_ATT_CTXT   'aftN'

Definition at line 16 of file ntfs.h.

◆ TAG_CCB

#define TAG_CCB   'CftN'

Definition at line 13 of file ntfs.h.

◆ TAG_FCB

#define TAG_FCB   'FftN'

Definition at line 14 of file ntfs.h.

◆ TAG_FILE_REC

#define TAG_FILE_REC   'rftN'

Definition at line 17 of file ntfs.h.

◆ TAG_IRP_CTXT

#define TAG_IRP_CTXT   'iftN'

Definition at line 15 of file ntfs.h.

◆ TAG_NTFS

#define TAG_NTFS   '0ftN'

Definition at line 12 of file ntfs.h.

◆ VALUE_OFFSET_ALIGNMENT

#define VALUE_OFFSET_ALIGNMENT   4

Definition at line 322 of file ntfs.h.

◆ VCB_VOLUME_LOCKED

#define VCB_VOLUME_LOCKED   0x0001

Definition at line 127 of file ntfs.h.

Typedef Documentation

◆ B_TREE_FILENAME_NODE

Definition at line 427 of file ntfs.h.

◆ B_TREE_KEY

◆ BIOS_PARAMETERS_BLOCK

◆ BOOT_SECTOR

◆ EXTENDED_BIOS_PARAMETERS_BLOCK

◆ FILE_RECORD_HEADER

◆ FIND_ATTR_CONTXT

◆ NTFS_ATTR_CONTEXT

◆ NTFS_FCB

typedef struct _FCB NTFS_FCB

◆ NTFS_INFO

◆ NTFS_VCB

◆ PATTRIBUTE_LIST

◆ PATTRIBUTE_TYPE

◆ PB_TREE

typedef struct B_TREE * PB_TREE

◆ PB_TREE_FILENAME_NODE

◆ PB_TREE_KEY

◆ PBIOS_PARAMETERS_BLOCK

◆ PBOOT_SECTOR

◆ PDEVICE_EXTENSION

◆ PEXTENDED_BIOS_PARAMETERS_BLOCK

◆ PFILE_RECORD_HEADER

◆ PFILENAME_ATTRIBUTE

◆ PFIND_ATTR_CONTXT

◆ PFIXUP_ARRAY

◆ PINDEX_BUFFER

◆ PINDEX_ENTRY_ATTRIBUTE

◆ PINDEX_HEADER_ATTRIBUTE

◆ PINDEX_ROOT_ATTRIBUTE

◆ PNTFS_ATTR_CONTEXT

◆ PNTFS_ATTR_RECORD

◆ PNTFS_ATTRIBUTE_LIST_ITEM

◆ PNTFS_CCB

◆ PNTFS_FCB

typedef struct _FCB * PNTFS_FCB

◆ PNTFS_GLOBAL_DATA

◆ PNTFS_INFO

◆ PNTFS_IRP_CONTEXT

◆ PNTFS_RECORD_HEADER

◆ PNTFS_VCB

◆ PNTFSIDENTIFIER

◆ PREPARSE_POINT_ATTRIBUTE

◆ PSTANDARD_INFORMATION

◆ PVOLINFO_ATTRIBUTE

Enumeration Type Documentation

◆ ATTRIBUTE_TYPE

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

Definition at line 159 of file ntfs.h.

Function Documentation

◆ AddBitmap()

NTSTATUS AddBitmap ( PNTFS_VCB  Vcb,
PFILE_RECORD_HEADER  FileRecord,
PNTFS_ATTR_RECORD  AttributeAddress,
PCWSTR  Name,
USHORT  NameLength 
)

Definition at line 72 of file attrib.c.

77 {
78  ULONG AttributeLength;
79  // Calculate the header length
80  ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
81  ULONG FileRecordEnd = AttributeAddress->Length;
82  ULONG NameOffset;
83  ULONG ValueOffset;
84  // We'll start out with 8 bytes of bitmap data
85  ULONG ValueLength = 8;
86  ULONG BytesAvailable;
87 
88  if (AttributeAddress->Type != AttributeEnd)
89  {
90  DPRINT1("FIXME: Can only add $BITMAP attribute to the end of a file record.\n");
92  }
93 
94  NameOffset = ResidentHeaderLength;
95 
96  // Calculate ValueOffset, which will be aligned to a 4-byte boundary
97  ValueOffset = ALIGN_UP_BY(NameOffset + (sizeof(WCHAR) * NameLength), VALUE_OFFSET_ALIGNMENT);
98 
99  // Calculate length of attribute
100  AttributeLength = ValueOffset + ValueLength;
101  AttributeLength = ALIGN_UP_BY(AttributeLength, ATTR_RECORD_ALIGNMENT);
102 
103  // Make sure the file record is large enough for the new attribute
104  BytesAvailable = Vcb->NtfsInfo.BytesPerFileRecord - FileRecord->BytesInUse;
105  if (BytesAvailable < AttributeLength)
106  {
107  DPRINT1("FIXME: Not enough room in file record for index allocation attribute!\n");
108  return STATUS_NOT_IMPLEMENTED;
109  }
110 
111  // Set Attribute fields
112  RtlZeroMemory(AttributeAddress, AttributeLength);
113 
114  AttributeAddress->Type = AttributeBitmap;
115  AttributeAddress->Length = AttributeLength;
116  AttributeAddress->NameLength = NameLength;
117  AttributeAddress->NameOffset = NameOffset;
118  AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
119 
120  AttributeAddress->Resident.ValueLength = ValueLength;
121  AttributeAddress->Resident.ValueOffset = ValueOffset;
122 
123  // Set the name
124  RtlCopyMemory((PCHAR)((ULONG_PTR)AttributeAddress + NameOffset), Name, NameLength * sizeof(WCHAR));
125 
126  // move the attribute-end and file-record-end markers to the end of the file record
127  AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
128  SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
129 
130  return STATUS_SUCCESS;
131 }
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT NameOffset
Definition: ntfs.h:126
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
ULONG BytesInUse
Definition: ntfs.h:253
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG Length
Definition: ntfs.h:123
USHORT Instance
Definition: ntfs.h:128
USHORT NextAttributeNumber
Definition: ntfs.h:256
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define Vcb
Definition: cdprocs.h:1425
unsigned char UCHAR
Definition: xmlstorage.h:181
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define VALUE_OFFSET_ALIGNMENT
Definition: ntfs.h:322
UCHAR NameLength
Definition: ntfs.h:125
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ALIGN_UP_BY(size, align)
UCHAR Reserved
Definition: ntfs.h:137
struct NTFS_ATTR_RECORD::@165::@167 Resident
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by DECLARE_INTERFACE_(), and UpdateIndexAllocation().

◆ AddData()

NTSTATUS AddData ( PFILE_RECORD_HEADER  FileRecord,
PNTFS_ATTR_RECORD  AttributeAddress 
)

Definition at line 160 of file attrib.c.

162 {
163  ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
164  ULONG FileRecordEnd = AttributeAddress->Length;
165 
166  if (AttributeAddress->Type != AttributeEnd)
167  {
168  DPRINT1("FIXME: Can only add $DATA attribute to the end of a file record.\n");
169  return STATUS_NOT_IMPLEMENTED;
170  }
171 
172  AttributeAddress->Type = AttributeData;
173  AttributeAddress->Length = ResidentHeaderLength;
174  AttributeAddress->Length = ALIGN_UP_BY(AttributeAddress->Length, ATTR_RECORD_ALIGNMENT);
175  AttributeAddress->Resident.ValueLength = 0;
176  AttributeAddress->Resident.ValueOffset = ResidentHeaderLength;
177 
178  // for unnamed $DATA attributes, NameOffset equals header length
179  AttributeAddress->NameOffset = ResidentHeaderLength;
180  AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
181 
182  // move the attribute-end and file-record-end markers to the end of the file record
183  AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
184  SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
185 
186  return STATUS_SUCCESS;
187 }
USHORT NameOffset
Definition: ntfs.h:126
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG Length
Definition: ntfs.h:123
USHORT Instance
Definition: ntfs.h:128
USHORT NextAttributeNumber
Definition: ntfs.h:256
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ALIGN_UP_BY(size, align)
UCHAR Reserved
Definition: ntfs.h:137
struct NTFS_ATTR_RECORD::@165::@167 Resident
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by NtfsCreateFileRecord().

◆ AddFileName()

NTSTATUS AddFileName ( PFILE_RECORD_HEADER  FileRecord,
PNTFS_ATTR_RECORD  AttributeAddress,
PDEVICE_EXTENSION  DeviceExt,
PFILE_OBJECT  FileObject,
BOOLEAN  CaseSensitive,
PULONGLONG  ParentMftIndex 
)

Definition at line 230 of file attrib.c.

236 {
237  ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
238  PFILENAME_ATTRIBUTE FileNameAttribute;
239  LARGE_INTEGER SystemTime;
240  ULONG FileRecordEnd = AttributeAddress->Length;
241  ULONGLONG CurrentMFTIndex = NTFS_FILE_ROOT;
242  UNICODE_STRING Current, Remaining, FilenameNoPath;
244  ULONG FirstEntry;
245 
246  if (AttributeAddress->Type != AttributeEnd)
247  {
248  DPRINT1("FIXME: Can only add $FILE_NAME attribute to the end of a file record.\n");
249  return STATUS_NOT_IMPLEMENTED;
250  }
251 
252  AttributeAddress->Type = AttributeFileName;
253  AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
254 
255  FileNameAttribute = (PFILENAME_ATTRIBUTE)((LONG_PTR)AttributeAddress + ResidentHeaderLength);
256 
257  // set timestamps
258  KeQuerySystemTime(&SystemTime);
259  FileNameAttribute->CreationTime = SystemTime.QuadPart;
260  FileNameAttribute->ChangeTime = SystemTime.QuadPart;
261  FileNameAttribute->LastWriteTime = SystemTime.QuadPart;
262  FileNameAttribute->LastAccessTime = SystemTime.QuadPart;
263 
264  // Is this a directory?
265  if(FileRecord->Flags & FRH_DIRECTORY)
266  FileNameAttribute->FileAttributes = NTFS_FILE_TYPE_DIRECTORY;
267  else
268  FileNameAttribute->FileAttributes = NTFS_FILE_TYPE_ARCHIVE;
269 
270  // we need to extract the filename from the path
271  DPRINT1("Pathname: %wZ\n", &FileObject->FileName);
272 
273  FsRtlDissectName(FileObject->FileName, &Current, &Remaining);
274 
275  FilenameNoPath.Buffer = Current.Buffer;
276  FilenameNoPath.MaximumLength = FilenameNoPath.Length = Current.Length;
277 
278  while (Current.Length != 0)
279  {
280  DPRINT1("Current: %wZ\n", &Current);
281 
282  if (Remaining.Length != 0)
283  {
284  FilenameNoPath.Buffer = Remaining.Buffer;
285  FilenameNoPath.Length = FilenameNoPath.MaximumLength = Remaining.Length;
286  }
287 
288  FirstEntry = 0;
289  Status = NtfsFindMftRecord(DeviceExt,
290  CurrentMFTIndex,
291  &Current,
292  &FirstEntry,
293  FALSE,
294  CaseSensitive,
295  &CurrentMFTIndex);
296  if (!NT_SUCCESS(Status))
297  break;
298 
299  if (Remaining.Length == 0 )
300  {
301  if (Current.Length != 0)
302  {
303  FilenameNoPath.Buffer = Current.Buffer;
304  FilenameNoPath.Length = FilenameNoPath.MaximumLength = Current.Length;
305  }
306  break;
307  }
308 
309  FsRtlDissectName(Remaining, &Current, &Remaining);
310  }
311 
312  DPRINT1("MFT Index of parent: %I64u\n", CurrentMFTIndex);
313 
314  // set reference to parent directory
315  FileNameAttribute->DirectoryFileReferenceNumber = CurrentMFTIndex;
316  *ParentMftIndex = CurrentMFTIndex;
317 
318  DPRINT1("SequenceNumber: 0x%02x\n", FileRecord->SequenceNumber);
319 
320  // The highest 2 bytes should be the sequence number, unless the parent happens to be root
321  if (CurrentMFTIndex == NTFS_FILE_ROOT)
322  FileNameAttribute->DirectoryFileReferenceNumber |= (ULONGLONG)NTFS_FILE_ROOT << 48;
323  else
324  FileNameAttribute->DirectoryFileReferenceNumber |= (ULONGLONG)FileRecord->SequenceNumber << 48;
325 
326  DPRINT1("FileNameAttribute->DirectoryFileReferenceNumber: 0x%016I64x\n", FileNameAttribute->DirectoryFileReferenceNumber);
327 
328  FileNameAttribute->NameLength = FilenameNoPath.Length / sizeof(WCHAR);
329  RtlCopyMemory(FileNameAttribute->Name, FilenameNoPath.Buffer, FilenameNoPath.Length);
330 
331  // For now, we're emulating the way Windows behaves when 8.3 name generation is disabled
332  // TODO: add DOS Filename as needed
333  if (!CaseSensitive && RtlIsNameLegalDOS8Dot3(&FilenameNoPath, NULL, NULL))
334  FileNameAttribute->NameType = NTFS_FILE_NAME_WIN32_AND_DOS;
335  else
336  FileNameAttribute->NameType = NTFS_FILE_NAME_POSIX;
337 
338  FileRecord->LinkCount++;
339 
340  AttributeAddress->Length = ResidentHeaderLength +
341  FIELD_OFFSET(FILENAME_ATTRIBUTE, Name) + FilenameNoPath.Length;
342  AttributeAddress->Length = ALIGN_UP_BY(AttributeAddress->Length, ATTR_RECORD_ALIGNMENT);
343 
344  AttributeAddress->Resident.ValueLength = FIELD_OFFSET(FILENAME_ATTRIBUTE, Name) + FilenameNoPath.Length;
345  AttributeAddress->Resident.ValueOffset = ResidentHeaderLength;
346  AttributeAddress->Resident.Flags = RA_INDEXED;
347 
348  // move the attribute-end and file-record-end markers to the end of the file record
349  AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
350  SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
351 
352  return Status;
353 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ULONGLONG ChangeTime
Definition: ntfs.h:358
USHORT MaximumLength
Definition: env_spec_w32.h:370
WCHAR Name[1]
Definition: ntfs.h:375
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
LONG NTSTATUS
Definition: precomp.h:26
ULONG Type
Definition: ntfs.h:122
UCHAR NameLength
Definition: ntfs.h:373
USHORT SequenceNumber
Definition: ntfs.h:249
ULONGLONG LastAccessTime
Definition: ntfs.h:360
#define NTFS_FILE_TYPE_DIRECTORY
Definition: ntfs.h:228
#define RA_INDEXED
Definition: ntfs.h:231
ULONG FileAttributes
Definition: ntfs.h:363
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
ULONG Length
Definition: ntfs.h:123
#define NTFS_FILE_NAME_POSIX
Definition: ntfs.h:63
#define FRH_DIRECTORY
Definition: ntfs.h:264
USHORT Instance
Definition: ntfs.h:128
smooth NULL
Definition: ftsmooth.c:416
USHORT LinkCount
Definition: ntfs.h:250
USHORT NextAttributeNumber
Definition: ntfs.h:256
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
#define NTFS_FILE_TYPE_ARCHIVE
Definition: ntfs.h:225
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI FsRtlDissectName(IN UNICODE_STRING Name, OUT PUNICODE_STRING FirstPart, OUT PUNICODE_STRING RemainingPart)
Definition: name.c:398
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONGLONG CreationTime
Definition: ntfs.h:357
unsigned char UCHAR
Definition: xmlstorage.h:181
ULONGLONG DirectoryFileReferenceNumber
Definition: ntfs.h:356
Status
Definition: gdiplustypes.h:24
ULONGLONG LastWriteTime
Definition: ntfs.h:359
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
USHORT Flags
Definition: ntfs.h:252
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ALIGN_UP_BY(size, align)
static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, PCHAR FileName, ULONGLONG *OutMFTIndex)
Definition: ntfs.c:545
UCHAR Reserved
Definition: ntfs.h:137
struct NTFS_ATTR_RECORD::@165::@167 Resident
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define NTFS_FILE_NAME_WIN32_AND_DOS
Definition: ntfs.h:66
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
LONGLONG QuadPart
Definition: typedefs.h:112
UCHAR NameType
Definition: ntfs.h:374
#define NTFS_FILE_ROOT
Definition: ntfs.h:28

Referenced by NtfsCreateDirectory(), and NtfsCreateFileRecord().

◆ AddFixupArray()

NTSTATUS AddFixupArray ( PDEVICE_EXTENSION  Vcb,
PNTFS_RECORD_HEADER  Record 
)

Definition at line 2603 of file mft.c.

2605 {
2606  USHORT *pShortToFixUp;
2607  ULONG ArrayEntryCount = Record->UsaCount - 1;
2608  ULONG Offset = Vcb->NtfsInfo.BytesPerSector - 2;
2609  ULONG i;
2610 
2611  PFIXUP_ARRAY fixupArray = (PFIXUP_ARRAY)((UCHAR*)Record + Record->UsaOffset);
2612 
2613  DPRINT("AddFixupArray(%p, %p)\n fixupArray->USN: %u, ArrayEntryCount: %u\n", Vcb, Record, fixupArray->USN, ArrayEntryCount);
2614 
2615  fixupArray->USN++;
2616 
2617  for (i = 0; i < ArrayEntryCount; i++)
2618  {
2619  DPRINT("USN: %u\tOffset: %u\n", fixupArray->USN, Offset);
2620 
2621  pShortToFixUp = (USHORT*)((PCHAR)Record + Offset);
2622  fixupArray->Array[i] = *pShortToFixUp;
2623  *pShortToFixUp = fixupArray->USN;
2624  Offset += Vcb->NtfsInfo.BytesPerSector;
2625  }
2626 
2627  return STATUS_SUCCESS;
2628 }
signed char * PCHAR
Definition: retypes.h:7
struct FIXUP_ARRAY * PFIXUP_ARRAY
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
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
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
USHORT USN
Definition: ntfs.h:557
void DPRINT(...)
Definition: polytest.cpp:61
#define Vcb
Definition: cdprocs.h:1425
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
USHORT Array[]
Definition: ntfs.h:558
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by CreateIndexBufferFromBTreeNode(), UpdateFileRecord(), and UpdateIndexEntryFileNameSize().

◆ AddIndexAllocation()

NTSTATUS AddIndexAllocation ( PNTFS_VCB  Vcb,
PFILE_RECORD_HEADER  FileRecord,
PNTFS_ATTR_RECORD  AttributeAddress,
PCWSTR  Name,
USHORT  NameLength 
)

Definition at line 388 of file attrib.c.

393 {
394  ULONG RecordLength;
395  ULONG FileRecordEnd;
396  ULONG NameOffset;
397  ULONG DataRunOffset;
398  ULONG BytesAvailable;
399 
400  if (AttributeAddress->Type != AttributeEnd)
401  {
402  DPRINT1("FIXME: Can only add $INDEX_ALLOCATION attribute to the end of a file record.\n");
403  return STATUS_NOT_IMPLEMENTED;
404  }
405 
406  // Calculate the name offset
407  NameOffset = FIELD_OFFSET(NTFS_ATTR_RECORD, NonResident.CompressedSize);
408 
409  // Calculate the offset to the first data run
410  DataRunOffset = (sizeof(WCHAR) * NameLength) + NameOffset;
411  // The data run offset must be aligned to a 4-byte boundary
412  DataRunOffset = ALIGN_UP_BY(DataRunOffset, DATA_RUN_ALIGNMENT);
413 
414  // Calculate the length of the new attribute; the empty data run will consist of a single byte
415  RecordLength = DataRunOffset + 1;
416 
417  // The size of the attribute itself must be aligned to an 8 - byte boundary
418  RecordLength = ALIGN_UP_BY(RecordLength, ATTR_RECORD_ALIGNMENT);
419 
420  // Back up the last 4-bytes of the file record (even though this value doesn't matter)
421  FileRecordEnd = AttributeAddress->Length;
422 
423  // Make sure the file record can contain the new attribute
424  BytesAvailable = Vcb->NtfsInfo.BytesPerFileRecord - FileRecord->BytesInUse;
425  if (BytesAvailable < RecordLength)
426  {
427  DPRINT1("FIXME: Not enough room in file record for index allocation attribute!\n");
428  return STATUS_NOT_IMPLEMENTED;
429  }
430 
431  // Set fields of attribute header
432  RtlZeroMemory(AttributeAddress, RecordLength);
433 
434  AttributeAddress->Type = AttributeIndexAllocation;
435  AttributeAddress->Length = RecordLength;
436  AttributeAddress->IsNonResident = TRUE;
437  AttributeAddress->NameLength = NameLength;
438  AttributeAddress->NameOffset = NameOffset;
439  AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
440 
441  AttributeAddress->NonResident.MappingPairsOffset = DataRunOffset;
442  AttributeAddress->NonResident.HighestVCN = (LONGLONG)-1;
443 
444  // Set the name
445  RtlCopyMemory((PCHAR)((ULONG_PTR)AttributeAddress + NameOffset), Name, NameLength * sizeof(WCHAR));
446 
447  // move the attribute-end and file-record-end markers to the end of the file record
448  AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
449  SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
450 
451  return STATUS_SUCCESS;
452 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT NameOffset
Definition: ntfs.h:126
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
ULONG BytesInUse
Definition: ntfs.h:253
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG Length
Definition: ntfs.h:123
USHORT Instance
Definition: ntfs.h:128
USHORT NextAttributeNumber
Definition: ntfs.h:256
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
int64_t LONGLONG
Definition: typedefs.h:66
LONGLONG CompressedSize
Definition: ntfs.h:150
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define Vcb
Definition: cdprocs.h:1425
UCHAR IsNonResident
Definition: ntfs.h:124
UCHAR NameLength
Definition: ntfs.h:125
struct NTFS_ATTR_RECORD::@165::@168 NonResident
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DATA_RUN_ALIGNMENT
Definition: ntfs.h:319
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ALIGN_UP_BY(size, align)
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by UpdateIndexAllocation().

◆ AddIndexRoot()

NTSTATUS AddIndexRoot ( PNTFS_VCB  Vcb,
PFILE_RECORD_HEADER  FileRecord,
PNTFS_ATTR_RECORD  AttributeAddress,
PINDEX_ROOT_ATTRIBUTE  NewIndexRoot,
ULONG  RootLength,
PCWSTR  Name,
USHORT  NameLength 
)

Definition at line 495 of file attrib.c.

502 {
503  ULONG AttributeLength;
504  // Calculate the header length
505  ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
506  // Back up the file record's final ULONG (even though it doesn't matter)
507  ULONG FileRecordEnd = AttributeAddress->Length;
508  ULONG NameOffset;
509  ULONG ValueOffset;
510  ULONG BytesAvailable;
511 
512  if (AttributeAddress->Type != AttributeEnd)
513  {
514  DPRINT1("FIXME: Can only add $DATA attribute to the end of a file record.\n");
515  return STATUS_NOT_IMPLEMENTED;
516  }
517 
518  NameOffset = ResidentHeaderLength;
519 
520  // Calculate ValueOffset, which will be aligned to a 4-byte boundary
521  ValueOffset = ALIGN_UP_BY(NameOffset + (sizeof(WCHAR) * NameLength), VALUE_OFFSET_ALIGNMENT);
522 
523  // Calculate length of attribute
524  AttributeLength = ValueOffset + RootLength;
525  AttributeLength = ALIGN_UP_BY(AttributeLength, ATTR_RECORD_ALIGNMENT);
526 
527  // Make sure the file record is large enough for the new attribute
528  BytesAvailable = Vcb->NtfsInfo.BytesPerFileRecord - FileRecord->BytesInUse;
529  if (BytesAvailable < AttributeLength)
530  {
531  DPRINT1("FIXME: Not enough room in file record for index allocation attribute!\n");
532  return STATUS_NOT_IMPLEMENTED;
533  }
534 
535  // Set Attribute fields
536  RtlZeroMemory(AttributeAddress, AttributeLength);
537 
538  AttributeAddress->Type = AttributeIndexRoot;
539  AttributeAddress->Length = AttributeLength;
540  AttributeAddress->NameLength = NameLength;
541  AttributeAddress->NameOffset = NameOffset;
542  AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
543 
544  AttributeAddress->Resident.ValueLength = RootLength;
545  AttributeAddress->Resident.ValueOffset = ValueOffset;
546 
547  // Set the name
548  RtlCopyMemory((PCHAR)((ULONG_PTR)AttributeAddress + NameOffset), Name, NameLength * sizeof(WCHAR));
549 
550  // Copy the index root attribute
551  RtlCopyMemory((PCHAR)((ULONG_PTR)AttributeAddress + ValueOffset), NewIndexRoot, RootLength);
552 
553  // move the attribute-end and file-record-end markers to the end of the file record
554  AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
555  SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
556 
557  return STATUS_SUCCESS;
558 }
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT NameOffset
Definition: ntfs.h:126
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
ULONG BytesInUse
Definition: ntfs.h:253
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG Length
Definition: ntfs.h:123
USHORT Instance
Definition: ntfs.h:128
USHORT NextAttributeNumber
Definition: ntfs.h:256
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define Vcb
Definition: cdprocs.h:1425
unsigned char UCHAR
Definition: xmlstorage.h:181
#define VALUE_OFFSET_ALIGNMENT
Definition: ntfs.h:322
UCHAR NameLength
Definition: ntfs.h:125
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ALIGN_UP_BY(size, align)
UCHAR Reserved
Definition: ntfs.h:137
struct NTFS_ATTR_RECORD::@165::@167 Resident
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by NtfsCreateDirectory().

◆ AddNewMftEntry()

NTSTATUS AddNewMftEntry ( PFILE_RECORD_HEADER  FileRecord,
PDEVICE_EXTENSION  DeviceExt,
PULONGLONG  DestinationIndex,
BOOLEAN  CanWait 
)

Definition at line 2022 of file mft.c.

2026 {
2028  ULONGLONG MftIndex;
2030  ULONGLONG BitmapDataSize;
2031  ULONGLONG AttrBytesRead;
2034  ULONG LengthWritten;
2035  PNTFS_ATTR_CONTEXT BitmapContext;
2036  LARGE_INTEGER BitmapBits;
2037  UCHAR SystemReservedBits;
2038 
2039  DPRINT1("AddNewMftEntry(%p, %p, %p, %s)\n", FileRecord, DeviceExt, DestinationIndex, CanWait ? "TRUE" : "FALSE");
2040 
2041  // First, we have to read the mft's $Bitmap attribute
2042 
2043  // Find the attribute
2044  Status = FindAttribute(DeviceExt, DeviceExt->MasterFileTable, AttributeBitmap, L"", 0, &BitmapContext, NULL);
2045  if (!NT_SUCCESS(Status))
2046  {
2047  DPRINT1("ERROR: Couldn't find $Bitmap attribute of master file table!\n");
2048  return Status;
2049  }
2050 
2051  // Get size of bitmap
2052  BitmapDataSize = AttributeDataLength(BitmapContext->pRecord);
2053 
2054  // RtlInitializeBitmap wants a ULONG-aligned pointer, and wants the memory passed to it to be a ULONG-multiple
2055  // Allocate a buffer for the $Bitmap attribute plus enough to ensure we can get a ULONG-aligned pointer
2056  BitmapBuffer = ExAllocatePoolWithTag(NonPagedPool, BitmapDataSize + sizeof(ULONG), TAG_NTFS);
2057  if (!BitmapBuffer)
2058  {
2059  ReleaseAttributeContext(BitmapContext);
2061  }
2062  RtlZeroMemory(BitmapBuffer, BitmapDataSize + sizeof(ULONG));
2063 
2064  // Get a ULONG-aligned pointer for the bitmap itself
2066 
2067  // read $Bitmap attribute
2068  AttrBytesRead = ReadAttribute(DeviceExt, BitmapContext, 0, (PCHAR)BitmapData, BitmapDataSize);
2069 
2070  if (AttrBytesRead != BitmapDataSize)
2071  {
2072  DPRINT1("ERROR: Unable to read $Bitmap attribute of master file table!\n");
2074  ReleaseAttributeContext(BitmapContext);
2076  }
2077 
2078  // We need to backup the bits for records 0x10 - 0x17 (3rd byte of bitmap) and mark these records
2079  // as in-use so we don't assign files to those indices. They're reserved for the system (e.g. ChkDsk).
2080  SystemReservedBits = BitmapData[2];
2081  BitmapData[2] = 0xff;
2082 
2083  // Calculate bit count
2084  BitmapBits.QuadPart = AttributeDataLength(DeviceExt->MFTContext->pRecord) /
2085  DeviceExt->NtfsInfo.BytesPerFileRecord;
2086  if (BitmapBits.HighPart != 0)
2087  {
2088  DPRINT1("\tFIXME: bitmap sizes beyond 32bits are not yet supported! (Your NTFS volume is too large)\n");
2091  ReleaseAttributeContext(BitmapContext);
2092  return STATUS_NOT_IMPLEMENTED;
2093  }
2094 
2095  // convert buffer into bitmap
2097 
2098  // set next available bit, preferrably after 23rd bit
2099  MftIndex = RtlFindClearBitsAndSet(&Bitmap, 1, 24);
2100  if ((LONG)MftIndex == -1)
2101  {
2102  DPRINT1("Couldn't find free space in MFT for file record, increasing MFT size.\n");
2103 
2105  ReleaseAttributeContext(BitmapContext);
2106 
2107  // Couldn't find a free record in the MFT, add some blank records and try again
2108  Status = IncreaseMftSize(DeviceExt, CanWait);
2109  if (!NT_SUCCESS(Status))
2110  {
2111  DPRINT1("ERROR: Couldn't find space in MFT for file or increase MFT size!\n");
2112  return Status;
2113  }
2114 
2115  return AddNewMftEntry(FileRecord, DeviceExt, DestinationIndex, CanWait);
2116  }
2117 
2118  DPRINT1("Creating file record at MFT index: %I64u\n", MftIndex);
2119 
2120  // update file record with index
2121  FileRecord->MFTRecordNumber = MftIndex;
2122 
2123  // [BitmapData should have been updated via RtlFindClearBitsAndSet()]
2124 
2125  // Restore the system reserved bits
2126  BitmapData[2] = SystemReservedBits;
2127 
2128  // write the bitmap back to the MFT's $Bitmap attribute
2129  Status = WriteAttribute(DeviceExt, BitmapContext, 0, BitmapData, BitmapDataSize, &LengthWritten, FileRecord);
2130  if (!NT_SUCCESS(Status))
2131  {
2132  DPRINT1("ERROR encountered when writing $Bitmap attribute!\n");
2134  ReleaseAttributeContext(BitmapContext);
2135  return Status;
2136  }
2137 
2138  // update the file record (write it to disk)
2139  Status = UpdateFileRecord(DeviceExt, MftIndex, FileRecord);
2140 
2141  if (!NT_SUCCESS(Status))
2142  {
2143  DPRINT1("ERROR: Unable to write file record!\n");
2145  ReleaseAttributeContext(BitmapContext);
2146  return Status;
2147  }
2148 
2149  *DestinationIndex = MftIndex;
2150 
2152  ReleaseAttributeContext(BitmapContext);
2153 
2154  return Status;
2155 }
signed char * PCHAR
Definition: retypes.h:7
NTSTATUS IncreaseMftSize(PDEVICE_EXTENSION Vcb, BOOLEAN CanWait)
Definition: mft.c:293
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
ULONG MFTRecordNumber
Definition: ntfs.h:258
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:41
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, PULONGLONG DestinationIndex, BOOLEAN CanWait)
Definition: mft.c:2022
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
struct BitmapData BitmapData
#define TAG_NTFS
Definition: ntfs.h:12
NTSTATUS WriteAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG RealLengthWritten, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:1315
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
ULONG LowPart
Definition: typedefs.h:104
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MftIndex, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:1931
unsigned int * PULONG
Definition: retypes.h:1
ULONG ReadAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
Definition: mft.c:1065
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ALIGN_UP_BY(size, align)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
BOOLEAN EnableWriteSupport
Definition: ntfs.h:155
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by AddNewMftEntry(), NtfsCreateDirectory(), and NtfsCreateFileRecord().

◆ AddRun()

NTSTATUS AddRun ( PNTFS_VCB  Vcb,
PNTFS_ATTR_CONTEXT  AttrContext,
ULONG  AttrOffset,
PFILE_RECORD_HEADER  FileRecord,
ULONGLONG  NextAssignedCluster,
ULONG  RunLength 
)

Definition at line 599 of file attrib.c.

605 {
607  int DataRunMaxLength;
608  PNTFS_ATTR_RECORD DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + AttrOffset);
609  ULONG NextAttributeOffset = AttrOffset + AttrContext->pRecord->Length;
610  ULONGLONG NextVBN = 0;
611 
612  PUCHAR RunBuffer;
613  ULONG RunBufferSize;
614 
615  if (!AttrContext->pRecord->IsNonResident)
617 
618  if (AttrContext->pRecord->NonResident.AllocatedSize != 0)
619  NextVBN = AttrContext->pRecord->NonResident.HighestVCN + 1;
620 
621  // Add newly-assigned clusters to mcb
622  _SEH2_TRY
623  {
624  if (!FsRtlAddLargeMcbEntry(&AttrContext->DataRunsMCB,
625  NextVBN,
626  NextAssignedCluster,
627  RunLength))
628  {
630  }
631  }
633  {
634  DPRINT1("Failed to add LargeMcb Entry!\n");
636  }
637  _SEH2_END;
638 
639  RunBuffer = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS);
640  if (!RunBuffer)
641  {
642  DPRINT1("ERROR: Couldn't allocate memory for data runs!\n");
644  }
645 
646  // Convert the map control block back to encoded data runs
647  ConvertLargeMCBToDataRuns(&AttrContext->DataRunsMCB, RunBuffer, Vcb->NtfsInfo.BytesPerCluster, &RunBufferSize);
648 
649  // Get the amount of free space between the start of the of the first data run and the attribute end
650  DataRunMaxLength = AttrContext->pRecord->Length - AttrContext->pRecord->NonResident.MappingPairsOffset;
651 
652  // Do we need to extend the attribute (or convert to attribute list)?
653  if (DataRunMaxLength < RunBufferSize)
654  {
655  PNTFS_ATTR_RECORD NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + NextAttributeOffset);
656  PNTFS_ATTR_RECORD NewRecord;
657 
658  // Add free space at the end of the file record to DataRunMaxLength
659  DataRunMaxLength += Vcb->NtfsInfo.BytesPerFileRecord - FileRecord->BytesInUse;
660 
661  // Can we resize the attribute?
662  if (DataRunMaxLength < RunBufferSize)
663  {
664  DPRINT1("FIXME: Need to create attribute list! Max Data Run Length available: %d, RunBufferSize: %d\n", DataRunMaxLength, RunBufferSize);
665  ExFreePoolWithTag(RunBuffer, TAG_NTFS);
666  return STATUS_NOT_IMPLEMENTED;
667  }
668 
669  // Are there more attributes after the one we're resizing?
670  if (NextAttribute->Type != AttributeEnd)
671  {
672  PNTFS_ATTR_RECORD FinalAttribute;
673 
674  // Calculate where to move the trailing attributes
675  ULONG_PTR MoveTo = (ULONG_PTR)DestinationAttribute + AttrContext->pRecord->NonResident.MappingPairsOffset + RunBufferSize;
676  MoveTo = ALIGN_UP_BY(MoveTo, ATTR_RECORD_ALIGNMENT);
677 
678  DPRINT1("Moving attribute(s) after this one starting with type 0x%lx\n", NextAttribute->Type);
679 
680  // Move the trailing attributes; FinalAttribute will point to the end marker
681  FinalAttribute = MoveAttributes(Vcb, NextAttribute, NextAttributeOffset, MoveTo);
682 
683  // set the file record end
684  SetFileRecordEnd(FileRecord, FinalAttribute, FILE_RECORD_END);
685  }
686 
687  // calculate position of end markers
688  NextAttributeOffset = AttrOffset + AttrContext->pRecord->NonResident.MappingPairsOffset + RunBufferSize;
689  NextAttributeOffset = ALIGN_UP_BY(NextAttributeOffset, ATTR_RECORD_ALIGNMENT);
690 
691  // Update the length of the destination attribute
692  DestinationAttribute->Length = NextAttributeOffset - AttrOffset;
693 
694  // Create a new copy of the attribute record
695  NewRecord = ExAllocatePoolWithTag(NonPagedPool, DestinationAttribute->Length, TAG_NTFS);
696  RtlCopyMemory(NewRecord, AttrContext->pRecord, AttrContext->pRecord->Length);
697  NewRecord->Length = DestinationAttribute->Length;
698 
699  // Free the old copy of the attribute record, which won't be large enough
700  ExFreePoolWithTag(AttrContext->pRecord, TAG_NTFS);
701 
702  // Set the attribute context's record to the new copy
703  AttrContext->pRecord = NewRecord;
704 
705  // if NextAttribute is the AttributeEnd marker
706  if (NextAttribute->Type == AttributeEnd)
707  {
708  // End the file record
709  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + NextAttributeOffset);
710  SetFileRecordEnd(FileRecord, NextAttribute, FILE_RECORD_END);
711  }
712  }
713 
714  // Update HighestVCN
715  DestinationAttribute->NonResident.HighestVCN =
716  AttrContext->pRecord->NonResident.HighestVCN = max(NextVBN - 1 + RunLength,
717  AttrContext->pRecord->NonResident.HighestVCN);
718 
719  // Write data runs to destination attribute
720  RtlCopyMemory((PVOID)((ULONG_PTR)DestinationAttribute + DestinationAttribute->NonResident.MappingPairsOffset),
721  RunBuffer,
722  RunBufferSize);
723 
724  // Update the attribute record in the attribute context
725  RtlCopyMemory((PVOID)((ULONG_PTR)AttrContext->pRecord + AttrContext->pRecord->NonResident.MappingPairsOffset),
726  RunBuffer,
727  RunBufferSize);
728 
729  // Update the file record
730  Status = UpdateFileRecord(Vcb, AttrContext->FileMFTIndex, FileRecord);
731 
732  ExFreePoolWithTag(RunBuffer, TAG_NTFS);
733 
734  NtfsDumpDataRuns((PUCHAR)((ULONG_PTR)DestinationAttribute + DestinationAttribute->NonResident.MappingPairsOffset), 0);
735 
736  return Status;
737 }
#define max(a, b)
Definition: svc.c:63
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
#define FILE_RECORD_END
Definition: ntfs.h:182
LONG NTSTATUS
Definition: precomp.h:26
#define ExRaiseStatus
Definition: ntoskrnl.h:96
ULONG BytesInUse
Definition: ntfs.h:253
ULONG Type
Definition: ntfs.h:122
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NtfsDumpDataRuns(PVOID StartOfRun, ULONGLONG CurrentLCN)
Definition: attrib.c:1755
ULONG Length
Definition: ntfs.h:123
PNTFS_ATTR_RECORD MoveAttributes(PDEVICE_EXTENSION DeviceExt, PNTFS_ATTR_RECORD FirstAttributeToMove, ULONG FirstAttributeOffset, ULONG_PTR MoveTo)
Definition: mft.c:512
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
uint64_t ULONGLONG
Definition: typedefs.h:65
#define Vcb
Definition: cdprocs.h:1425
#define TAG_NTFS
Definition: ntfs.h:12
BOOLEAN NTAPI FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
Definition: largemcb.c:282
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
NTSTATUS ConvertLargeMCBToDataRuns(PLARGE_MCB DataRunsMCB, PUCHAR RunBuffer, ULONG MaxBufferSize, PULONG UsedBufferSize)
Definition: attrib.c:896
_SEH2_END
Definition: create.c:4424
struct NTFS_ATTR_RECORD::@165::@168 NonResident
NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MftIndex, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:1931
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define ALIGN_UP_BY(size, align)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

Referenced by SetNonResidentAttributeDataLength().

◆ AddStandardInformation()

NTSTATUS AddStandardInformation ( PFILE_RECORD_HEADER  FileRecord,
PNTFS_ATTR_RECORD  AttributeAddress 
)

Definition at line 766 of file attrib.c.

768 {
769  ULONG ResidentHeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
770  PSTANDARD_INFORMATION StandardInfo = (PSTANDARD_INFORMATION)((LONG_PTR)AttributeAddress + ResidentHeaderLength);
771  LARGE_INTEGER SystemTime;
772  ULONG FileRecordEnd = AttributeAddress->Length;
773 
774  if (AttributeAddress->Type != AttributeEnd)
775  {
776  DPRINT1("FIXME: Can only add $STANDARD_INFORMATION attribute to the end of a file record.\n");
777  return STATUS_NOT_IMPLEMENTED;
778  }
779 
780  AttributeAddress->Type = AttributeStandardInformation;
781  AttributeAddress->Length = sizeof(STANDARD_INFORMATION) + ResidentHeaderLength;
782  AttributeAddress->Length = ALIGN_UP_BY(AttributeAddress->Length, ATTR_RECORD_ALIGNMENT);
783  AttributeAddress->Resident.ValueLength = sizeof(STANDARD_INFORMATION);
784  AttributeAddress->Resident.ValueOffset = ResidentHeaderLength;
785  AttributeAddress->Instance = FileRecord->NextAttributeNumber++;
786 
787  // set dates and times
788  KeQuerySystemTime(&SystemTime);
789  StandardInfo->CreationTime = SystemTime.QuadPart;
790  StandardInfo->ChangeTime = SystemTime.QuadPart;
791  StandardInfo->LastWriteTime = SystemTime.QuadPart;
792  StandardInfo->LastAccessTime = SystemTime.QuadPart;
793  StandardInfo->FileAttribute = NTFS_FILE_TYPE_ARCHIVE;
794 
795  // move the attribute-end and file-record-end markers to the end of the file record
796  AttributeAddress = (PNTFS_ATTR_RECORD)((ULONG_PTR)AttributeAddress + AttributeAddress->Length);
797  SetFileRecordEnd(FileRecord, AttributeAddress, FileRecordEnd);
798 
799  return STATUS_SUCCESS;
800 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
ULONGLONG LastAccessTime
Definition: ntfs.h:329
ULONGLONG LastWriteTime
Definition: ntfs.h:328
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
ULONG FileAttribute
Definition: ntfs.h:330
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG Length
Definition: ntfs.h:123
USHORT Instance
Definition: ntfs.h:128
USHORT NextAttributeNumber
Definition: ntfs.h:256
struct STANDARD_INFORMATION * PSTANDARD_INFORMATION
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
#define NTFS_FILE_TYPE_ARCHIVE
Definition: ntfs.h:225
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ALIGN_UP_BY(size, align)
ULONGLONG CreationTime
Definition: ntfs.h:326
UCHAR Reserved
Definition: ntfs.h:137
struct NTFS_ATTR_RECORD::@165::@167 Resident
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONGLONG ChangeTime
Definition: ntfs.h:327
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by NtfsCreateDirectory(), and NtfsCreateFileRecord().

◆ AttributeAllocatedLength()

ULONGLONG AttributeAllocatedLength ( PNTFS_ATTR_RECORD  AttrRecord)

Definition at line 249 of file mft.c.

250 {
251  if (AttrRecord->IsNonResident)
252  return AttrRecord->NonResident.AllocatedSize;
253  else
254  return ALIGN_UP_BY(AttrRecord->Resident.ValueLength, ATTR_RECORD_ALIGNMENT);
255 }
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
UCHAR IsNonResident
Definition: ntfs.h:124
struct NTFS_ATTR_RECORD::@165::@168 NonResident
#define ALIGN_UP_BY(size, align)
struct NTFS_ATTR_RECORD::@165::@167 Resident

Referenced by NtfsGetFileSize(), NtfsGetSteamInformation(), NtfsReadFile(), NtfsSetEndOfFile(), and NtfsWriteFile().

◆ AttributeDataLength()

◆ CompareFileName()

BOOLEAN CompareFileName ( PUNICODE_STRING  FileName,
PINDEX_ENTRY_ATTRIBUTE  IndexEntry,
BOOLEAN  DirSearch,
BOOLEAN  CaseSensitive 
)

Definition at line 2650 of file mft.c.

2654 {
2655  BOOLEAN Ret, Alloc = FALSE;
2656  UNICODE_STRING EntryName;
2657 
2658  EntryName.Buffer = IndexEntry->FileName.Name;
2659  EntryName.Length =
2660  EntryName.MaximumLength = IndexEntry->FileName.NameLength * sizeof(WCHAR);
2661 
2662  if (DirSearch)
2663  {
2664  UNICODE_STRING IntFileName;
2665  if (!CaseSensitive)
2666  {
2668  Alloc = TRUE;
2669  }
2670  else
2671  {
2672  IntFileName = *FileName;
2673  }
2674 
2675  Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, !CaseSensitive, NULL);
2676 
2677  if (Alloc)
2678  {
2679  RtlFreeUnicodeString(&IntFileName);
2680  }
2681 
2682  return Ret;
2683  }
2684  else
2685  {
2686  return (RtlCompareUnicodeString(FileName, &EntryName, !CaseSensitive) == 0);
2687  }
2688 }
#define TRUE
Definition: types.h:120
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
FILENAME_ATTRIBUTE FileName
Definition: ntfs.h:423
USHORT MaximumLength
Definition: env_spec_w32.h:370
WCHAR Name[1]
Definition: ntfs.h:375
UCHAR NameLength
Definition: ntfs.h:373
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID Alloc(IN DWORD dwFlags, IN SIZE_T dwBytes)
Definition: main.c:63
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
struct _FileName FileName
Definition: fatprocs.h:884

Referenced by BrowseIndexEntries(), BrowseSubNodeIndexEntries(), and UpdateIndexEntryFileNameSize().

◆ CompareTreeKeys()

LONG CompareTreeKeys ( PB_TREE_KEY  Key1,
PB_TREE_KEY  Key2,
BOOLEAN  CaseSensitive 
)

Definition at line 417 of file btree.c.

418 {
419  UNICODE_STRING Key1Name, Key2Name;
420  LONG Comparison;
421 
422  // Key1 must not be the final key (AKA the dummy key)
424 
425  // If Key2 is the "dummy key", key 1 will always come first
426  if (Key2->NextKey == NULL)
427  return -1;
428 
429  Key1Name.Buffer = Key1->IndexEntry->FileName.Name;
430  Key1Name.Length = Key1Name.MaximumLength
431  = Key1->IndexEntry->FileName.NameLength * sizeof(WCHAR);
432 
433  Key2Name.Buffer = Key2->IndexEntry->FileName.Name;
434  Key2Name.Length = Key2Name.MaximumLength
435  = Key2->IndexEntry->FileName.NameLength * sizeof(WCHAR);
436 
437  // Are the two keys the same length?
438  if (Key1Name.Length == Key2Name.Length)
439  return RtlCompareUnicodeString(&Key1Name, &Key2Name, !CaseSensitive);
440 
441  // Is Key1 shorter?
442  if (Key1Name.Length < Key2Name.Length)
443  {
444  // Truncate KeyName2 to be the same length as KeyName1
445  Key2Name.Length = Key1Name.Length;
446 
447  // Compare the names of the same length
448  Comparison = RtlCompareUnicodeString(&Key1Name, &Key2Name, !CaseSensitive);
449 
450  // If the truncated names are the same length, the shorter one comes first
451  if (Comparison == 0)
452  return -1;
453  }
454  else
455  {
456  // Key2 is shorter
457  // Truncate KeyName1 to be the same length as KeyName2
458  Key1Name.Length = Key2Name.Length;
459 
460  // Compare the names of the same length
461  Comparison = RtlCompareUnicodeString(&Key1Name, &Key2Name, !CaseSensitive);
462 
463  // If the truncated names are the same length, the shorter one comes first
464  if (Comparison == 0)
465  return 1;
466  }
467 
468  return Comparison;
469 }
FILENAME_ATTRIBUTE FileName
Definition: ntfs.h:423
USHORT MaximumLength
Definition: env_spec_w32.h:370
WCHAR Name[1]
Definition: ntfs.h:375
UCHAR NameLength
Definition: ntfs.h:373
#define NTFS_INDEX_ENTRY_END
Definition: ntfs.h:61
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
struct _B_TREE_KEY * NextKey
Definition: ntfs.h:432
__wchar_t WCHAR
Definition: xmlstorage.h:180
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
USHORT Flags
Definition: ntfs.h:421
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
PINDEX_ENTRY_ATTRIBUTE IndexEntry
Definition: ntfs.h:434

Referenced by NtfsInsertKey().

◆ ConvertDataRunsToLargeMCB()

NTSTATUS ConvertDataRunsToLargeMCB ( PUCHAR  DataRun,
PLARGE_MCB  DataRunsMCB,
PULONGLONG  pNextVBN 
)

Definition at line 825 of file attrib.c.

828 {
829  LONGLONG DataRunOffset;
830  ULONGLONG DataRunLength;
831  LONGLONG DataRunStartLCN;
832  ULONGLONG LastLCN = 0;
833 
834  // Initialize the MCB, potentially catch an exception
835  _SEH2_TRY{
839  } _SEH2_END;
840 
841  while (*DataRun != 0)
842  {
843  DataRun = DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
844 
845  if (DataRunOffset != -1)
846  {
847  // Normal data run.
848  DataRunStartLCN = LastLCN + DataRunOffset;
849  LastLCN = DataRunStartLCN;
850 
851  _SEH2_TRY{
852  if (!FsRtlAddLargeMcbEntry(DataRunsMCB,
853  *pNextVBN,
854  DataRunStartLCN,
855  DataRunLength))
856  {
858  }
860  FsRtlUninitializeLargeMcb(DataRunsMCB);
862  } _SEH2_END;
863 
864  }
865 
866  *pNextVBN += DataRunLength;
867  }
868 
869  return STATUS_SUCCESS;
870 }
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
Definition: attrib.c:966
#define ExRaiseStatus
Definition: ntoskrnl.h:96
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
VOID NTAPI FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType)
Definition: largemcb.c:450
int64_t LONGLONG
Definition: typedefs.h:66
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
uint64_t ULONGLONG
Definition: typedefs.h:65
BOOLEAN NTAPI FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
Definition: largemcb.c:282
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_SEH2_END
Definition: create.c:4424
VOID NTAPI FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:1053
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by PrepareAttributeContext().

◆ ConvertLargeMCBToDataRuns()

NTSTATUS ConvertLargeMCBToDataRuns ( PLARGE_MCB  DataRunsMCB,
PUCHAR  RunBuffer,
ULONG  MaxBufferSize,
PULONG  UsedBufferSize 
)

Definition at line 896 of file attrib.c.

900 {
902  ULONG RunBufferOffset = 0;
903  LONGLONG DataRunOffset;
904  ULONGLONG LastLCN = 0;
905  LONGLONG Vbn, Lbn, Count;
906  ULONG i;
907 
908 
909  DPRINT("\t[Vbn, Lbn, Count]\n");
910 
911  // convert each mcb entry to a data run
912  for (i = 0; FsRtlGetNextLargeMcbEntry(DataRunsMCB, i, &Vbn, &Lbn, &Count); i++)
913  {
914  UCHAR DataRunOffsetSize = 0;
915  UCHAR DataRunLengthSize = 0;
916  UCHAR ControlByte = 0;
917 
918  // [vbn, lbn, count]
919  DPRINT("\t[%I64d, %I64d,%I64d]\n", Vbn, Lbn, Count);
920 
921  // TODO: check for holes and convert to sparse runs
922  DataRunOffset = Lbn - LastLCN;
923  LastLCN = Lbn;
924 
925  // now we need to determine how to represent DataRunOffset with the minimum number of bytes
926  DPRINT("Determining how many bytes needed to represent %I64x\n", DataRunOffset);
927  DataRunOffsetSize = GetPackedByteCount(DataRunOffset, TRUE);
928  DPRINT("%d bytes needed.\n", DataRunOffsetSize);
929 
930  // determine how to represent DataRunLengthSize with the minimum number of bytes
931  DPRINT("Determining how many bytes needed to represent %I64x\n", Count);
932  DataRunLengthSize = GetPackedByteCount(Count, TRUE);
933  DPRINT("%d bytes needed.\n", DataRunLengthSize);
934 
935  // ensure the next data run + end marker would be <= Max buffer size
936  if (RunBufferOffset + 2 + DataRunLengthSize + DataRunOffsetSize > MaxBufferSize)
937  {
939  DPRINT1("FIXME: Ran out of room in buffer for data runs!\n");
940  break;
941  }
942 
943  // pack and copy the control byte
944  ControlByte = (DataRunOffsetSize << 4) + DataRunLengthSize;
945  RunBuffer[RunBufferOffset++] = ControlByte;
946 
947  // copy DataRunLength
948  RtlCopyMemory(RunBuffer + RunBufferOffset, &Count, DataRunLengthSize);
949  RunBufferOffset += DataRunLengthSize;
950 
951  // copy DataRunOffset
952  RtlCopyMemory(RunBuffer + RunBufferOffset, &DataRunOffset, DataRunOffsetSize);
953  RunBufferOffset += DataRunOffsetSize;
954  }
955 
956  // End of data runs
957  RunBuffer[RunBufferOffset++] = 0;
958 
959  *UsedBufferSize = RunBufferOffset;
960  DPRINT("New Size of DataRuns: %ld\n", *UsedBufferSize);
961 
962  return Status;
963 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ LONGLONG _In_ LONGLONG Lbn
Definition: fsrtlfuncs.h:479
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
BOOLEAN NTAPI FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount)
Definition: largemcb.c:391
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
void DPRINT(...)
Definition: polytest.cpp:61
int64_t LONGLONG
Definition: typedefs.h:66
uint64_t ULONGLONG
Definition: typedefs.h:65
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR GetPackedByteCount(LONGLONG NumberToPack, BOOLEAN IsSigned)
Definition: attrib.c:1846
Status
Definition: gdiplustypes.h:24
_In_ LONGLONG Vbn
Definition: fsrtlfuncs.h:470
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by AddRun(), FreeClusters(), ReadAttribute(), and WriteAttribute().

◆ CreateBTreeFromIndex()

NTSTATUS CreateBTreeFromIndex ( PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  FileRecordWithIndex,
PNTFS_ATTR_CONTEXT  IndexRootContext,
PINDEX_ROOT_ATTRIBUTE  IndexRoot,
PB_TREE NewTree 
)

Definition at line 682 of file btree.c.

688 {
689  PINDEX_ENTRY_ATTRIBUTE CurrentNodeEntry;
693  ULONG CurrentOffset = IndexRoot->Header.FirstEntryOffset;
694  PNTFS_ATTR_CONTEXT IndexAllocationContext = NULL;
696 
697  DPRINT("CreateBTreeFromIndex(%p, %p)\n", IndexRoot, NewTree);
698 
699  if (!Tree || !RootNode || !CurrentKey)
700  {
701  DPRINT1("Couldn't allocate enough memory for B-Tree!\n");
702  if (Tree)
704  if (CurrentKey)
705  ExFreePoolWithTag(CurrentKey, TAG_NTFS);
706  if (RootNode)
709  }
710 
711  RtlZeroMemory(Tree, sizeof(B_TREE));
713  RtlZeroMemory(CurrentKey, sizeof(B_TREE_KEY));
714 
715  // See if the file record has an attribute allocation
717  FileRecordWithIndex,
719  L"$I30",
720  4,
721  &IndexAllocationContext,
722  NULL);
723  if (!NT_SUCCESS(Status))
724  IndexAllocationContext = NULL;
725 
726  // Setup the Tree
727  RootNode->FirstKey = CurrentKey;
728  Tree->RootNode = RootNode;
729 
730  // Make sure we won't try reading past the attribute-end
731  if (FIELD_OFFSET(INDEX_ROOT_ATTRIBUTE, Header) + IndexRoot->Header.TotalSizeOfEntries > IndexRootContext->pRecord->Resident.ValueLength)
732  {
733  DPRINT1("Filesystem corruption detected!\n");
736  goto Cleanup;
737  }
738 
739  // Start at the first node entry
740  CurrentNodeEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexRoot
742  + IndexRoot->Header.FirstEntryOffset);
743 
744  // Create a key for each entry in the node
745  while (CurrentOffset < IndexRoot->Header.TotalSizeOfEntries)
746  {
747  // Allocate memory for the current entry
748  CurrentKey->IndexEntry = ExAllocatePoolWithTag(NonPagedPool, CurrentNodeEntry->Length, TAG_NTFS);
749  if (!CurrentKey->IndexEntry)
750  {
751  DPRINT1("ERROR: Couldn't allocate memory for next key!\n");
754  goto Cleanup;
755  }
756 
757  RootNode->KeyCount++;
758 
759  // If this isn't the last entry
760  if (!(CurrentNodeEntry->Flags & NTFS_INDEX_ENTRY_END))
761  {
762  // Create the next key
764  if (!NextKey)
765  {
766  DPRINT1("ERROR: Couldn't allocate memory for next key!\n");
769  goto Cleanup;
770  }
771 
772  RtlZeroMemory(NextKey, sizeof(B_TREE_KEY));
773 
774  // Add NextKey to the end of the list
775  CurrentKey->NextKey = NextKey;
776 
777  // Copy the current entry to its key
778  RtlCopyMemory(CurrentKey->IndexEntry, CurrentNodeEntry, CurrentNodeEntry->Length);
779 
780  // Does this key have a sub-node?
781  if (CurrentKey->IndexEntry->Flags & NTFS_INDEX_ENTRY_NODE)
782  {
783  // Create the child node
785  IndexRoot,
786  IndexAllocationContext,
787  CurrentKey->IndexEntry);
788  if (!CurrentKey->LesserChild)
789  {
790  DPRINT1("ERROR: Couldn't create child node!\n");
793  goto Cleanup;
794  }
795  }
796 
797  // Advance to the next entry
798  CurrentOffset += CurrentNodeEntry->Length;
799  CurrentNodeEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)CurrentNodeEntry + CurrentNodeEntry->Length);
800  CurrentKey = NextKey;
801  }
802  else
803  {
804  // Copy the final entry to its key
805  RtlCopyMemory(CurrentKey->IndexEntry, CurrentNodeEntry, CurrentNodeEntry->Length);
806  CurrentKey->NextKey = NULL;
807 
808  // Does this key have a sub-node?
809  if (CurrentKey->IndexEntry->Flags & NTFS_INDEX_ENTRY_NODE)
810  {
811  // Create the child node
813  IndexRoot,
814  IndexAllocationContext,
815  CurrentKey->IndexEntry);
816  if (!CurrentKey->LesserChild)
817  {
818  DPRINT1("ERROR: Couldn't create child node!\n");
821  goto Cleanup;
822  }
823  }
824 
825  break;
826  }
827  }
828 
829  *NewTree = Tree;
831 
832 Cleanup:
833  if (IndexAllocationContext)
834  ReleaseAttributeContext(IndexAllocationContext);
835 
836  return Status;
837 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
LONG NTSTATUS
Definition: precomp.h:26
USHORT Length
Definition: ntfs.h:419
Definition: ntfs.h:404
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
#define NTFS_INDEX_ENTRY_END
Definition: ntfs.h:61
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG FirstEntryOffset
Definition: ntfs.h:380
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
Definition: Header.h:8
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _B_TREE_KEY * NextKey
Definition: ntfs.h:432
B_TREE_FILENAME_NODE * LesserChild
Definition: ntfs.h:433
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
INDEX_HEADER_ATTRIBUTE Header
Definition: ntfs.h:394
CRegistryTree Tree
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
USHORT Flags
Definition: ntfs.h:421
static const WCHAR L[]
Definition: oid.c:1250
ULONG TotalSizeOfEntries
Definition: ntfs.h:381
static const WCHAR Cleanup[]
Definition: register.c:80
#define NTFS_INDEX_ENTRY_NODE
Definition: ntfs.h:60
Status
Definition: gdiplustypes.h:24
VOID DestroyBTree(PB_TREE Tree)
Definition: btree.c:1542
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
Definition: ntfs.h:449
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PINDEX_ENTRY_ATTRIBUTE IndexEntry
Definition: ntfs.h:434
PB_TREE_FILENAME_NODE CreateBTreeNodeFromIndexNode(PDEVICE_EXTENSION Vcb, PINDEX_ROOT_ATTRIBUTE IndexRoot, PNTFS_ATTR_CONTEXT IndexAllocationAttributeCtx, PINDEX_ENTRY_ATTRIBUTE NodeEntry)
Definition: btree.c:499
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938
struct INDEX_ENTRY_ATTRIBUTE * PINDEX_ENTRY_ATTRIBUTE
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19

Referenced by NtfsAddFilenameToDirectory().

◆ CreateEmptyBTree()

NTSTATUS CreateEmptyBTree ( PB_TREE NewTree)

Definition at line 348 of file btree.c.

349 {
352  PB_TREE_KEY DummyKey;
353 
354  DPRINT1("CreateEmptyBTree(%p) called\n", NewTree);
355 
356  if (!Tree || !RootNode)
357  {
358  DPRINT1("Couldn't allocate enough memory for B-Tree!\n");
359  if (Tree)
361  if (RootNode)
364  }
365 
366  // Create the dummy key
367  DummyKey = CreateDummyKey(FALSE);
368  if (!DummyKey)
369  {
370  DPRINT1("ERROR: Failed to create dummy key!\n");
374  }
375 
376  RtlZeroMemory(Tree, sizeof(B_TREE));
378 
379  // Setup the Tree
380  RootNode->FirstKey = DummyKey;
381  RootNode->KeyCount = 1;
382  RootNode->DiskNeedsUpdating = TRUE;
383  Tree->RootNode = RootNode;
384 
385  *NewTree = Tree;
386 
387  // Memory will be freed when DestroyBTree() is called
388 
389  return STATUS_SUCCESS;
390 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PB_TREE_KEY CreateDummyKey(BOOLEAN HasChildNode)
Definition: btree.c:289
CRegistryTree Tree
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: ntfs.h:449
#define DPRINT1
Definition: precomp.h:8
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938
PCONFIGURATION_COMPONENT_DATA RootNode
Definition: macharm.c:19

Referenced by NtfsCreateDirectory().

◆ CreateIndexRootFromBTree()

NTSTATUS CreateIndexRootFromBTree ( PDEVICE_EXTENSION  DeviceExt,
PB_TREE  Tree,
ULONG  MaxIndexSize,
PINDEX_ROOT_ATTRIBUTE IndexRoot,
ULONG Length 
)

Definition at line 910 of file btree.c.

915 {
916  ULONG i;
917  PB_TREE_KEY CurrentKey;
918  PINDEX_ENTRY_ATTRIBUTE CurrentNodeEntry;
920  DeviceExt->NtfsInfo.BytesPerFileRecord,
921  TAG_NTFS);
922 
923  DPRINT("CreateIndexRootFromBTree(%p, %p, 0x%lx, %p, %p)\n", DeviceExt, Tree, MaxIndexSize, IndexRoot, Length);
924 
925 #ifndef NDEBUG
926  DumpBTree(Tree);
927 #endif
928 
929  if (!NewIndexRoot)
930  {
931  DPRINT1("Failed to allocate memory for Index Root!\n");
933  }
934 
935  // Setup the new index root
936  RtlZeroMemory(NewIndexRoot, DeviceExt->NtfsInfo.BytesPerFileRecord);
937 
938  NewIndexRoot->AttributeType = AttributeFileName;
939  NewIndexRoot->CollationRule = COLLATION_FILE_NAME;
940  NewIndexRoot->SizeOfEntry = DeviceExt->NtfsInfo.BytesPerIndexRecord;
941  // If Bytes per index record is less than cluster size, clusters per index record becomes sectors per index
942  if (NewIndexRoot->SizeOfEntry < DeviceExt->NtfsInfo.BytesPerCluster)
943  NewIndexRoot->ClustersPerIndexRecord = NewIndexRoot->SizeOfEntry / DeviceExt->NtfsInfo.BytesPerSector;
944  else
945  NewIndexRoot->ClustersPerIndexRecord = NewIndexRoot->SizeOfEntry / DeviceExt->NtfsInfo.BytesPerCluster;
946 
947  // Setup the Index node header
948  NewIndexRoot->Header.FirstEntryOffset = sizeof(INDEX_HEADER_ATTRIBUTE);
949  NewIndexRoot->Header.Flags = INDEX_ROOT_SMALL;
950 
951  // Start summing the total size of this node's entries
952  NewIndexRoot->Header.TotalSizeOfEntries = NewIndexRoot->Header.FirstEntryOffset;
953 
954  // Setup each Node Entry
955  CurrentKey = Tree->RootNode->FirstKey;
956  CurrentNodeEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)NewIndexRoot
958  + NewIndexRoot->Header.FirstEntryOffset);
959  for (i = 0; i < Tree->RootNode->KeyCount; i++)
960  {
961  // Would adding the current entry to the index increase the index size beyond the limit we've set?
962  ULONG IndexSize = NewIndexRoot->Header.TotalSizeOfEntries - NewIndexRoot->Header.FirstEntryOffset + CurrentKey->IndexEntry->Length;
963  if (IndexSize > MaxIndexSize)
964  {
965  DPRINT1("TODO: Adding file would require creating an attribute list!\n");
966  ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
967  return STATUS_NOT_IMPLEMENTED;
968  }
969 
970  ASSERT(CurrentKey->IndexEntry->Length != 0);
971 
972  // Copy the index entry
973  RtlCopyMemory(CurrentNodeEntry, CurrentKey->IndexEntry, CurrentKey->IndexEntry->Length);
974 
975  DPRINT1("Index Node Entry Stream Length: %u\nIndex Node Entry Length: %u\n",
976  CurrentNodeEntry->KeyLength,
977  CurrentNodeEntry->Length);
978 
979  // Does the current key have any sub-nodes?
980  if (CurrentKey->LesserChild)
981  NewIndexRoot->Header.Flags = INDEX_ROOT_LARGE;
982 
983  // Add Length of Current Entry to Total Size of Entries
984  NewIndexRoot->Header.TotalSizeOfEntries += CurrentKey->IndexEntry->Length;
985 
986  // Go to the next node entry
987  CurrentNodeEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)CurrentNodeEntry + CurrentNodeEntry->Length);
988 
989  CurrentKey = CurrentKey->NextKey;
990  }
991 
992  NewIndexRoot->Header.AllocatedSize = NewIndexRoot->Header.TotalSizeOfEntries;
993 
994  *IndexRoot = NewIndexRoot;
996 
997  return STATUS_SUCCESS;
998 }
ULONG CollationRule
Definition: ntfs.h:390
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT Length
Definition: ntfs.h:419
Definition: ntfs.h:404
USHORT KeyLength
Definition: ntfs.h:420
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG FirstEntryOffset
Definition: ntfs.h:380
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
Definition: Header.h:8
void DPRINT(...)
Definition: polytest.cpp:61
struct _B_TREE_KEY * NextKey
Definition: ntfs.h:432
B_TREE_FILENAME_NODE * LesserChild
Definition: ntfs.h:433
ULONG SizeOfEntry
Definition: ntfs.h:391
ULONG AttributeType
Definition: ntfs.h:389
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
INDEX_HEADER_ATTRIBUTE Header
Definition: ntfs.h:394
CRegistryTree Tree
#define TAG_NTFS
Definition: ntfs.h:12
VOID DumpBTree(PB_TREE Tree)
Definition: btree.c:1622
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG TotalSizeOfEntries
Definition: ntfs.h:381
#define INDEX_ROOT_LARGE
Definition: ntfs.h:209
UCHAR ClustersPerIndexRecord
Definition: ntfs.h:392
#define INDEX_ROOT_SMALL
Definition: ntfs.h:208
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PINDEX_ENTRY_ATTRIBUTE IndexEntry
Definition: ntfs.h:434
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define COLLATION_FILE_NAME
Definition: ntfs.h:201
struct INDEX_ENTRY_ATTRIBUTE * PINDEX_ENTRY_ATTRIBUTE

Referenced by NtfsAddFilenameToDirectory(), and NtfsCreateDirectory().

◆ DecodeRun()

PUCHAR DecodeRun ( PUCHAR  DataRun,
LONGLONG DataRunOffset,
ULONGLONG DataRunLength 
)

Definition at line 966 of file attrib.c.

969 {
970  UCHAR DataRunOffsetSize;
971  UCHAR DataRunLengthSize;
972  CHAR i;
973 
974  DataRunOffsetSize = (*DataRun >> 4) & 0xF;
975  DataRunLengthSize = *DataRun & 0xF;
976  *DataRunOffset = 0;
977  *DataRunLength = 0;
978  DataRun++;
979  for (i = 0; i < DataRunLengthSize; i++)
980  {
981  *DataRunLength += ((ULONG64)*DataRun) << (i * 8);
982  DataRun++;
983  }
984 
985  /* NTFS 3+ sparse files */
986  if (DataRunOffsetSize == 0)
987  {
988  *DataRunOffset = -1;
989  }
990  else
991  {
992  for (i = 0; i < DataRunOffsetSize - 1; i++)
993  {
994  *DataRunOffset += ((ULONG64)*DataRun) << (i * 8);
995  DataRun++;
996  }
997  /* The last byte contains sign so we must process it different way. */
998  *DataRunOffset = ((LONG64)(CHAR)(*(DataRun++)) << (i * 8)) + *DataRunOffset;
999  }
1000 
1001  DPRINT("DataRunOffsetSize: %x\n", DataRunOffsetSize);
1002  DPRINT("DataRunLengthSize: %x\n", DataRunLengthSize);
1003  DPRINT("DataRunOffset: %x\n", *DataRunOffset);
1004  DPRINT("DataRunLength: %x\n", *DataRunLength);
1005 
1006  return DataRun;
1007 }
char CHAR
Definition: xmlstorage.h:175
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
void DPRINT(...)
Definition: polytest.cpp:61
int64_t LONG64
Definition: typedefs.h:66
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ConvertDataRunsToLargeMCB(), FindRun(), GetLastClusterInDataRun(), NtfsDumpDataRuns(), PrepareAttributeContext(), PrintAttributeInfo(), ReadAttribute(), and WriteAttribute().

◆ DemoteBTreeRoot()

NTSTATUS DemoteBTreeRoot ( PB_TREE  Tree)

Definition at line 1089 of file btree.c.

1090 {
1091  PB_TREE_FILENAME_NODE NewSubNode, NewIndexRoot;
1092  PB_TREE_KEY DummyKey;
1093 
1094  DPRINT("Collapsing Index Root into sub-node.\n");
1095 
1096 #ifndef NDEBUG
1097  DumpBTree(Tree);
1098 #endif
1099 
1100  // Create a new node that will hold the keys currently in index root
1102  if (!NewSubNode)
1103  {
1104  DPRINT1("ERROR: Couldn't allocate memory for new sub-node.\n");
1106  }
1107  RtlZeroMemory(NewSubNode, sizeof(B_TREE_FILENAME_NODE));
1108 
1109  // Copy the applicable data from the old index root node
1110  NewSubNode->KeyCount = Tree->RootNode->KeyCount;
1111  NewSubNode->FirstKey = Tree->RootNode->FirstKey;
1112  NewSubNode->DiskNeedsUpdating = TRUE;
1113 
1114  // Create a new dummy key, and make the new node it's child
1115  DummyKey = CreateDummyKey(TRUE);
1116  if (!DummyKey)
1117  {
1118  DPRINT1("ERROR: Couldn't allocate memory for new root node.\n");
1119  ExFreePoolWithTag(NewSubNode, TAG_NTFS);
1121  }
1122 
1123  // Make the new node a child of the dummy key
1124  DummyKey->LesserChild = NewSubNode;
1125 
1126  // Create a new index root node
1128  if (!NewIndexRoot)
1129  {
1130  DPRINT1("ERROR: Couldn't allocate memory for new index root.\n");
1131  ExFreePoolWithTag(NewSubNode, TAG_NTFS);
1132  ExFreePoolWithTag(DummyKey, TAG_NTFS);
1134  }
1135  RtlZeroMemory(NewIndexRoot, sizeof(B_TREE_FILENAME_NODE));
1136 
1137  NewIndexRoot->DiskNeedsUpdating = TRUE;
1138 
1139  // Insert the dummy key into the new node
1140  NewIndexRoot->FirstKey = DummyKey;
1141  NewIndexRoot->KeyCount = 1;
1142  NewIndexRoot->DiskNeedsUpdating = TRUE;
1143 
1144  // Make the new node the Tree's root node
1145  Tree->RootNode = NewIndexRoot;
1146 
1147 #ifndef NDEBUG
1148  DumpBTree(Tree);
1149 #endif
1150 
1151  return STATUS_SUCCESS;
1152 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PB_TREE_KEY FirstKey
Definition: ntfs.h:446
PB_TREE_KEY CreateDummyKey(BOOLEAN HasChildNode)
Definition: btree.c:289
void DPRINT(...)
Definition: polytest.cpp:61
B_TREE_FILENAME_NODE * LesserChild
Definition: ntfs.h:433
BOOLEAN DiskNeedsUpdating
Definition: ntfs.h:444
CRegistryTree Tree
#define TAG_NTFS
Definition: ntfs.h:12
VOID DumpBTree(PB_TREE Tree)
Definition: btree.c:1622
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define DPRINT1
Definition: precomp.h:8
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by NtfsAddFilenameToDirectory().

◆ DestroyBTree()

VOID DestroyBTree ( PB_TREE  Tree)

Definition at line 1542 of file btree.c.

1543 {
1544  DestroyBTreeNode(Tree->RootNode);
1546 }
VOID DestroyBTreeNode(PB_TREE_FILENAME_NODE Node)
Definition: btree.c:1511
CRegistryTree Tree
#define TAG_NTFS
Definition: ntfs.h:12
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by CreateBTreeFromIndex(), NtfsAddFilenameToDirectory(), and NtfsCreateDirectory().

◆ DestroyBTreeNode()

VOID DestroyBTreeNode ( PB_TREE_FILENAME_NODE  Node)

Definition at line 1511 of file btree.c.

1512 {
1513  PB_TREE_KEY NextKey;
1514  PB_TREE_KEY CurrentKey = Node->FirstKey;
1515  ULONG i;
1516  for (i = 0; i < Node->KeyCount; i++)
1517  {
1518  NT_ASSERT(CurrentKey);
1519  NextKey = CurrentKey->NextKey;
1520  DestroyBTreeKey(CurrentKey);
1521  CurrentKey = NextKey;
1522  }
1523 
1524  NT_ASSERT(NextKey == NULL);
1525 
1527 }
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
smooth NULL
Definition: ftsmooth.c:416
struct _B_TREE_KEY * NextKey
Definition: ntfs.h:432
#define TAG_NTFS
Definition: ntfs.h:12
VOID DestroyBTreeKey(PB_TREE_KEY Key)
Definition: btree.c:1499
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
Definition: dlist.c:348
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by CreateBTreeNodeFromIndexNode(), DestroyBTree(), and DestroyBTreeKey().

◆ DumpBTree()

VOID DumpBTree ( PB_TREE  Tree)

Definition at line 1622 of file btree.c.

1623 {
1624  DbgPrint("B_TREE @ %p\n", Tree);
1625  DumpBTreeNode(Tree, Tree->RootNode, 0, 0);
1626 }
#define DbgPrint
Definition: loader.c:25
CRegistryTree Tree
VOID DumpBTreeNode(PB_TREE Tree, PB_TREE_FILENAME_NODE Node, ULONG Number, ULONG Depth)
Definition: btree.c:1583

Referenced by CreateIndexRootFromBTree(), DemoteBTreeRoot(), NtfsAddFilenameToDirectory(), NtfsInsertKey(), and UpdateIndexAllocation().

◆ DumpBTreeKey()

VOID DumpBTreeKey ( PB_TREE  Tree,
PB_TREE_KEY  Key,
ULONG  Number,
ULONG  Depth 
)

Definition at line 1549 of file btree.c.

1550 {
1551  ULONG i;
1552  for (i = 0; i < Depth; i++)
1553  DbgPrint(" ");
1554  DbgPrint(" Key #%d", Number);
1555 
1556  if (!(Key->IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
1557  {
1559  FileName.Length = Key->IndexEntry->FileName.NameLength * sizeof(WCHAR);
1560  FileName.MaximumLength = FileName.Length;
1561  FileName.Buffer = Key->IndexEntry->FileName.Name;
1562  DbgPrint(" '%wZ'\n", &FileName);
1563  }
1564  else
1565  {
1566  DbgPrint(" (Dummy Key)\n");
1567  }
1568 
1569  // Is there a child node?
1570  if (Key->IndexEntry->Flags & NTFS_INDEX_ENTRY_NODE)
1571  {
1572  if (Key->LesserChild)
1573  DumpBTreeNode(Tree, Key->LesserChild, Number, Depth + 1);
1574  else
1575  {
1576  // This will be an assert once nodes with arbitrary depth are debugged
1577  DPRINT1("DRIVER ERROR: No Key->LesserChild despite Key->IndexEntry->Flags indicating this is a node!\n");
1578  }
1579  }
1580 }
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:656
#define DbgPrint
Definition: loader.c:25
#define NTFS_INDEX_ENTRY_END
Definition: ntfs.h:61
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
CRegistryTree Tree
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
#define NTFS_INDEX_ENTRY_NODE
Definition: ntfs.h:60
struct _FileName FileName
Definition: fatprocs.h:884
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
VOID DumpBTreeNode(PB_TREE Tree, PB_TREE_FILENAME_NODE Node, ULONG Number, ULONG Depth)
Definition: btree.c:1583

Referenced by DumpBTreeNode().

◆ DumpBTreeNode()

VOID DumpBTreeNode ( PB_TREE  Tree,
PB_TREE_FILENAME_NODE  Node,
ULONG  Number,
ULONG  Depth 
)

Definition at line 1583 of file btree.c.

1587 {
1588  PB_TREE_KEY CurrentKey;
1589  ULONG i;
1590  for (i = 0; i < Depth; i++)
1591  DbgPrint(" ");
1592  DbgPrint("Node #%d, Depth %d, has %d key%s", Number, Depth, Node->KeyCount, Node->KeyCount == 1 ? "" : "s");
1593 
1594  if (Node->HasValidVCN)
1595  DbgPrint(" VCN: %I64u\n", Node->VCN);
1596  else if (Tree->RootNode == Node)
1597  DbgPrint(" Index Root");
1598  else
1599  DbgPrint(" NOT ASSIGNED VCN YET\n");
1600 
1601  CurrentKey = Node->FirstKey;
1602  for (i = 0; i < Node->KeyCount; i++)
1603  {
1604  DumpBTreeKey(Tree, CurrentKey, i, Depth);
1605  CurrentKey = CurrentKey->NextKey;
1606  }
1607 }
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:656
#define DbgPrint
Definition: loader.c:25
VOID DumpBTreeKey(PB_TREE Tree, PB_TREE_KEY Key, ULONG Number, ULONG Depth)
Definition: btree.c:1549
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
struct _B_TREE_KEY * NextKey
Definition: ntfs.h:432
CRegistryTree Tree
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
unsigned int ULONG
Definition: retypes.h:1
Definition: dlist.c:348

Referenced by DumpBTree(), DumpBTreeKey(), and SplitBTreeNode().

◆ EnumerAttribute()

VOID EnumerAttribute ( PFILE_RECORD_HEADER  file,
PDEVICE_EXTENSION  Vcb,
PDEVICE_OBJECT  DeviceObject 
)

◆ FindAttribute()

NTSTATUS FindAttribute ( PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  MftRecord,
ULONG  Type,
PCWSTR  Name,
ULONG  NameLength,
PNTFS_ATTR_CONTEXT AttrCtx,
PULONG  Offset 
)

Definition at line 131 of file mft.c.

138 {
139  BOOLEAN Found;
142  PNTFS_ATTR_RECORD Attribute;
143  PNTFS_ATTRIBUTE_LIST_ITEM AttrListItem;
144 
145  DPRINT("FindAttribute(%p, %p, 0x%x, %S, %lu, %p, %p)\n", Vcb, MftRecord, Type, Name, NameLength, AttrCtx, Offset);
146 
147  Found = FALSE;
148  Status = FindFirstAttribute(&Context, Vcb, MftRecord, FALSE, &Attribute);
149  while (NT_SUCCESS(Status))
150  {
151  if (Attribute->Type == Type && Attribute->NameLength == NameLength)
152  {
153  if (NameLength != 0)
154  {
155  PWCHAR AttrName;
156 
157  AttrName = (PWCHAR)((PCHAR)Attribute + Attribute->NameOffset);
158  DPRINT("%.*S, %.*S\n", Attribute->NameLength, AttrName, NameLength, Name);
159  if (RtlCompareMemory(AttrName, Name, NameLength * sizeof(WCHAR)) == (NameLength * sizeof(WCHAR)))
160  {
161  Found = TRUE;
162  }
163  }
164  else
165  {
166  Found = TRUE;
167  }
168 
169  if (Found)
170  {
171  /* Found it, fill up the context and return. */
172  DPRINT("Found context\n");
173  *AttrCtx = PrepareAttributeContext(Attribute);
174 
175  (*AttrCtx)->FileMFTIndex = MftRecord->MFTRecordNumber;
176 
177  if (Offset != NULL)
178  *Offset = Context.Offset;
179 
181  return STATUS_SUCCESS;
182  }
183  }
184 
185  Status = FindNextAttribute(&Context, &Attribute);
186  }
187 
188  /* No attribute found, check if it is referenced in another file record */
189  Status = FindFirstAttributeListItem(&Context, &AttrListItem);
190  while (NT_SUCCESS(Status))
191  {
192  if (AttrListItem->Type == Type && AttrListItem->NameLength == NameLength)
193  {
194  if (NameLength != 0)
195  {
196  PWCHAR AttrName;
197 
198  AttrName = (PWCHAR)((PCHAR)AttrListItem + AttrListItem->NameOffset);
199  DPRINT("%.*S, %.*S\n", AttrListItem->NameLength, AttrName, NameLength, Name);
200  if (RtlCompareMemory(AttrName, Name, NameLength * sizeof(WCHAR)) == (NameLength * sizeof(WCHAR)))
201  {
202  Found = TRUE;
203  }
204  }
205  else
206  {
207  Found = TRUE;
208  }
209 
210  if (Found == TRUE)
211  {
212  /* Get the MFT Index of attribute */
213  ULONGLONG MftIndex;
214  PFILE_RECORD_HEADER RemoteHdr;
215 
216  MftIndex = AttrListItem->MFTIndex & NTFS_MFT_MASK;
217  RemoteHdr = ExAllocateFromNPagedLookasideList(&Vcb->FileRecLookasideList);
218 
219  if (RemoteHdr == NULL)
220  {
223  }
224 
225  /* Check we are not reading ourselves */
226  if (MftRecord->MFTRecordNumber == MftIndex)
227  {
228  DPRINT1("Attribute list references missing attribute to this file entry !");
229  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, RemoteHdr);
232  }
233  /* Read the new file record */
234  ReadFileRecord(Vcb, MftIndex, RemoteHdr);
235  Status = FindAttribute(Vcb, RemoteHdr, Type, Name, NameLength, AttrCtx, Offset);
236  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, RemoteHdr);
238  return Status;
239  }
240  }
241  Status = FindNextAttributeListItem(&Context, &AttrListItem);
242  }
245 }
signed char * PCHAR
Definition: retypes.h:7
#define NTFS_MFT_MASK
Definition: ntfs.h:198
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Type
Definition: Type.h:6
USHORT NameOffset
Definition: ntfs.h:126
NTSTATUS FindFirstAttributeListItem(PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
Definition: attrib.c:1307
ULONG MFTRecordNumber
Definition: ntfs.h:258
LONG NTSTATUS
Definition: precomp.h:26
ULONG Type
Definition: ntfs.h:122
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
uint16_t * PWCHAR
Definition: typedefs.h:54
ULONGLONG MFTIndex
Definition: ntfs.h:310
PNTFS_ATTR_CONTEXT PrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:41
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
return Found
Definition: dirsup.c:1270
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1431
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
#define Vcb
Definition: cdprocs.h:1425
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1465
NTSTATUS FindNextAttributeListItem(PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
Definition: attrib.c:1321
Status
Definition: gdiplustypes.h:24
UCHAR NameLength
Definition: ntfs.h:125
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1383
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1631
#define DPRINT1
Definition: precomp.h:8
struct tagContext Context
Definition: acpixf.h:1024
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by AddNewMftEntry(), AllocateIndexNode(), BrowseIndexEntries(), CreateBTreeFromIndex(), FindAttribute(), tinyxml2::XMLElement::FindAttribute(), FreeClusters(), GetVolumeBitmap(), IncreaseMftSize(), NtfsAddFilenameToDirectory(), NtfsAllocateClusters(), NtfsCreateFile(), NtfsDirFindFile(), NtfsFindMftRecord(), NtfsGetFileSize(), NtfsGetFreeClusters(), NtfsGetVolumeData(), NtfsReadFCBAttribute(), NtfsReadFile(), NtfsSetEndOfFile(), NtfsWriteFile(), tinyxml2::XMLElement::QueryBoolAttribute(), tinyxml2::XMLElement::QueryDoubleAttribute(), tinyxml2::XMLElement::QueryFloatAttribute(), tinyxml2::XMLElement::QueryIntAttribute(), tinyxml2::XMLElement::QueryUnsignedAttribute(), UpdateFileNameRecord(), UpdateIndexAllocation(), UpdateIndexEntryFileNameSize(), UpdateMftMirror(), and WriteAttribute().

◆ FindCloseAttribute()

VOID FindCloseAttribute ( PFIND_ATTR_CONTXT  Context)

Definition at line 1465 of file attrib.c.

1466 {
1467  if (Context->NonResidentStart != NULL)
1468  {
1469  ExFreePoolWithTag(Context->NonResidentStart, TAG_NTFS);
1470  Context->NonResidentStart = NULL;
1471  }
1472 }
smooth NULL
Definition: ftsmooth.c:416
#define TAG_NTFS
Definition: ntfs.h:12
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by FindAttribute(), GetFileNameFromRecord(), GetNfsVolumeData(), GetStandardInformationFromRecord(), NtfsDumpFileAttributes(), NtfsGetSteamInformation(), NtfsReadFile(), and NtfsWriteFile().

◆ FindFirstAttribute()

NTSTATUS FindFirstAttribute ( PFIND_ATTR_CONTXT  Context,
PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  FileRecord,
BOOLEAN  OnlyResident,
PNTFS_ATTR_RECORD Attribute 
)

Definition at line 1383 of file attrib.c.

1388 {
1389  NTSTATUS Status;
1390 
1391  DPRINT("FindFistAttribute(%p, %p, %p, %p, %u, %p)\n", Context, Vcb, FileRecord, OnlyResident, Attribute);
1392 
1393  Context->Vcb = Vcb;
1394  Context->OnlyResident = OnlyResident;
1395  Context->FirstAttr = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
1396  Context->CurrAttr = Context->FirstAttr;
1397  Context->LastAttr = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse);
1398  Context->NonResidentStart = NULL;
1399  Context->NonResidentEnd = NULL;
1400  Context->Offset = FileRecord->AttributeOffset;
1401 
1402  if (Context->FirstAttr->Type == AttributeEnd)
1403  {
1404  Context->CurrAttr = (PVOID)-1;
1405  return STATUS_END_OF_FILE;
1406  }
1407  else if (Context->FirstAttr->Type == AttributeAttributeList)
1408  {
1410  if (!NT_SUCCESS(Status))
1411  {
1412  return Status;
1413  }
1414 
1415  *Attribute = InternalGetNextAttribute(Context);
1416  if (*Attribute == NULL)
1417  {
1418  return STATUS_END_OF_FILE;
1419  }
1420  }
1421  else
1422  {
1423  *Attribute = Context->CurrAttr;
1424  Context->Offset = (UCHAR*)Context->CurrAttr - (UCHAR*)FileRecord;
1425  }
1426 
1427  return STATUS_SUCCESS;
1428 }
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
static NTSTATUS InternalReadNonResidentAttributes(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1214
LONG NTSTATUS
Definition: precomp.h:26
ULONG BytesInUse
Definition: ntfs.h:253
#define STATUS_END_OF_FILE
Definition: shellext.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:63
USHORT AttributeOffset
Definition: ntfs.h:251
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
static PNTFS_ATTR_RECORD InternalGetNextAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1334
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by FindAttribute(), GetFileNameFromRecord(), GetNfsVolumeData(), GetStandardInformationFromRecord(), NtfsDumpFileAttributes(), NtfsGetSteamInformation(), NtfsReadFile(), and NtfsWriteFile().

◆ FindFirstAttributeListItem()

NTSTATUS FindFirstAttributeListItem ( PFIND_ATTR_CONTXT  Context,
PNTFS_ATTRIBUTE_LIST_ITEM Item 
)

Definition at line 1307 of file attrib.c.

1309 {
1310  if (Context->NonResidentStart == NULL || Context->NonResidentStart->Type == AttributeEnd)
1311  {
1312  return STATUS_UNSUCCESSFUL;
1313  }
1314 
1315  Context->NonResidentCur = Context->NonResidentStart;
1316  *Item = Context->NonResidentCur;
1317  return STATUS_SUCCESS;
1318 }
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by FindAttribute().

◆ FindNextAttribute()

NTSTATUS FindNextAttribute ( PFIND_ATTR_CONTXT  Context,
PNTFS_ATTR_RECORD Attribute 
)

Definition at line 1431 of file attrib.c.

1433 {
1434  NTSTATUS Status;
1435 
1436  DPRINT("FindNextAttribute(%p, %p)\n", Context, Attribute);
1437 
1438  *Attribute = InternalGetNextAttribute(Context);
1439  if (*Attribute == NULL)
1440  {
1441  return STATUS_END_OF_FILE;
1442  }
1443 
1444  if (Context->CurrAttr->Type != AttributeAttributeList)
1445  {
1446  return STATUS_SUCCESS;
1447  }
1448 
1450  if (!NT_SUCCESS(Status))
1451  {
1452  return Status;
1453  }
1454 
1455  *Attribute = InternalGetNextAttribute(Context);
1456  if (*Attribute == NULL)
1457  {
1458  return STATUS_END_OF_FILE;
1459  }
1460 
1461  return STATUS_SUCCESS;
1462 }
static NTSTATUS InternalReadNonResidentAttributes(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1214
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_END_OF_FILE
Definition: shellext.h:67
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
static PNTFS_ATTR_RECORD InternalGetNextAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1334
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by FindAttribute(), GetFileNameFromRecord(), GetNfsVolumeData(), GetStandardInformationFromRecord(), NtfsDumpFileAttributes(), NtfsGetSteamInformation(), NtfsReadFile(), and NtfsWriteFile().

◆ FindNextAttributeListItem()

NTSTATUS FindNextAttributeListItem ( PFIND_ATTR_CONTXT  Context,
PNTFS_ATTRIBUTE_LIST_ITEM Item 
)

Definition at line 1321 of file attrib.c.

1323 {
1325  if (*Item == NULL)
1326  {
1327  return STATUS_UNSUCCESSFUL;
1328  }
1329  return STATUS_SUCCESS;
1330 }
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static PNTFS_ATTRIBUTE_LIST_ITEM InternalGetNextAttributeListItem(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1267
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by FindAttribute().

◆ FixupUpdateSequenceArray()

NTSTATUS FixupUpdateSequenceArray ( PDEVICE_EXTENSION  Vcb,
PNTFS_RECORD_HEADER  Record 
)

Definition at line 1965 of file mft.c.

1967 {
1968  USHORT *USA;
1969  USHORT USANumber;
1970  USHORT USACount;
1971  USHORT *Block;
1972 
1973  USA = (USHORT*)((PCHAR)Record + Record->UsaOffset);
1974  USANumber = *(USA++);
1975  USACount = Record->UsaCount - 1; /* Exclude the USA Number. */
1976  Block = (USHORT*)((PCHAR)Record + Vcb->NtfsInfo.BytesPerSector - 2);
1977 
1978  DPRINT("FixupUpdateSequenceArray(%p, %p)\nUSANumber: %u\tUSACount: %u\n", Vcb, Record, USANumber, USACount);
1979 
1980  while (USACount)
1981  {
1982  if (*Block != USANumber)
1983  {
1984  DPRINT1("Mismatch with USA: %u read, %u expected\n" , *Block, USANumber);
1985  return STATUS_UNSUCCESSFUL;
1986  }
1987  *Block = *(USA++);
1988  Block = (USHORT*)((PCHAR)Block + Vcb->NtfsInfo.BytesPerSector);
1989  USACount--;
1990  }
1991 
1992  return STATUS_SUCCESS;
1993 }
signed char * PCHAR
Definition: retypes.h:7
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
void DPRINT(...)
Definition: polytest.cpp:61
#define Vcb
Definition: cdprocs.h:1425
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT1
Definition: precomp.h:8
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by BrowseSubNodeIndexEntries(), CreateBTreeNodeFromIndexNode(), PrintAllVCNs(), ReadFileRecord(), UpdateFileRecord(), and UpdateIndexEntryFileNameSize().

◆ FreeClusters()

NTSTATUS FreeClusters ( PNTFS_VCB  Vcb,
PNTFS_ATTR_CONTEXT  AttrContext,
ULONG  AttrOffset,
PFILE_RECORD_HEADER  FileRecord,
ULONG  ClustersToFree 
)

Definition at line 1057 of file attrib.c.

1062 {
1064  ULONG ClustersLeftToFree = ClustersToFree;
1065 
1066  PNTFS_ATTR_RECORD DestinationAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + AttrOffset);
1067  ULONG NextAttributeOffset = AttrOffset + AttrContext->pRecord->Length;
1068  PNTFS_ATTR_RECORD NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + NextAttributeOffset);
1069 
1070  PUCHAR RunBuffer;
1071  ULONG RunBufferSize = 0;
1072 
1073  PFILE_RECORD_HEADER BitmapRecord;
1074  PNTFS_ATTR_CONTEXT DataContext;
1075  ULONGLONG BitmapDataSize;
1078  ULONG LengthWritten;
1079 
1080  if (!AttrContext->pRecord->IsNonResident)
1081  {
1082  return STATUS_INVALID_PARAMETER;
1083  }
1084 
1085  // Read the $Bitmap file
1086  BitmapRecord = ExAllocateFromNPagedLookasideList(&Vcb->FileRecLookasideList);
1087  if (BitmapRecord == NULL)
1088  {
1089  DPRINT1("Error: Unable to allocate memory for bitmap file record!\n");
1090  return STATUS_NO_MEMORY;
1091  }
1092 
1093  Status = ReadFileRecord(Vcb, NTFS_FILE_BITMAP, BitmapRecord);
1094  if (!NT_SUCCESS(Status))
1095  {
1096  DPRINT1("Error: Unable to read file record for bitmap!\n");
1097  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, BitmapRecord);
1098  return 0;
1099  }
1100 
1101  Status = FindAttribute(Vcb, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
1102  if (!NT_SUCCESS(Status))
1103  {
1104  DPRINT1("Error: Unable to find data attribute for bitmap file!\n");
1105  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, BitmapRecord);
1106  return 0;
1107  }
1108 
1109  BitmapDataSize = AttributeDataLength(DataContext->pRecord);
1110  BitmapDataSize = min(BitmapDataSize, ULONG_MAX);
1111  ASSERT((BitmapDataSize * 8) >= Vcb->NtfsInfo.ClusterCount);
1112  BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, Vcb->NtfsInfo.BytesPerSector), TAG_NTFS);
1113  if (BitmapData == NULL)
1114  {
1115  DPRINT1("Error: Unable to allocate memory for bitmap file data!\n");
1116  ReleaseAttributeContext(DataContext);
1117  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, BitmapRecord);
1118  return 0;
1119  }
1120 
1121  ReadAttribute(Vcb, DataContext, 0, (PCHAR)BitmapData, (ULONG)BitmapDataSize);
1122 
1123  RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, Vcb->NtfsInfo.ClusterCount);
1124 
1125  // free clusters in $BITMAP file
1126  while (ClustersLeftToFree > 0)
1127  {
1129 
1130  if (!FsRtlLookupLastLargeMcbEntry(&AttrContext->DataRunsMCB, &LargeVbn, &LargeLbn))
1131  {
1133  DPRINT1("DRIVER ERROR: FreeClusters called to free %lu clusters, which is %lu more clusters than are assigned to attribute!",
1134  ClustersToFree,
1135  ClustersLeftToFree);
1136  break;
1137  }
1138 
1139  if (LargeLbn != -1)
1140  {
1141  // deallocate this cluster
1143  }
1144  FsRtlTruncateLargeMcb(&AttrContext->DataRunsMCB, AttrContext->pRecord->NonResident.HighestVCN);
1145 
1146  // decrement HighestVCN, but don't let it go below 0
1147  AttrContext->pRecord->NonResident.HighestVCN = min(AttrContext->pRecord->NonResident.HighestVCN, AttrContext->pRecord->NonResident.HighestVCN - 1);
1148  ClustersLeftToFree--;
1149  }
1150 
1151  // update $BITMAP file on disk
1152  Status = WriteAttribute(Vcb, DataContext, 0, BitmapData, (ULONG)BitmapDataSize, &LengthWritten, FileRecord);
1153  if (!NT_SUCCESS(Status))
1154  {
1155  ReleaseAttributeContext(DataContext);
1157  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, BitmapRecord);
1158  return Status;
1159  }
1160 
1161  ReleaseAttributeContext(DataContext);
1163  ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, BitmapRecord);
1164 
1165  // Save updated data runs to file record
1166 
1167  // Allocate some memory for a new RunBuffer
1168  RunBuffer = ExAllocatePoolWithTag(NonPagedPool, Vcb->NtfsInfo.BytesPerFileRecord, TAG_NTFS);
1169  if (!RunBuffer)
1170  {
1171  DPRINT1("ERROR: Couldn't allocate memory for data runs!\n");
1173  }
1174 
1175  // Convert the map control block back to encoded data runs
1176  ConvertLargeMCBToDataRuns(&AttrContext->DataRunsMCB, RunBuffer, Vcb->NtfsInfo.BytesPerCluster, &RunBufferSize);
1177 
1178  // Update HighestVCN
1179  DestinationAttribute->NonResident.HighestVCN = AttrContext->pRecord->NonResident.HighestVCN;
1180 
1181  // Write data runs to destination attribute
1182  RtlCopyMemory((PVOID)((ULONG_PTR)DestinationAttribute + DestinationAttribute->NonResident.MappingPairsOffset),
1183  RunBuffer,
1184  RunBufferSize);
1185 
1186  // Is DestinationAttribute the last attribute in the file record?
1187  if (NextAttribute->Type == AttributeEnd)
1188  {
1189  // update attribute length
1190  DestinationAttribute->Length = ALIGN_UP_BY(AttrContext->pRecord->NonResident.MappingPairsOffset + RunBufferSize,
1192 
1193  ASSERT(DestinationAttribute->Length <= AttrContext->pRecord->Length);
1194 
1195  AttrContext->pRecord->Length = DestinationAttribute->Length;
1196 
1197  // write end markers
1198  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)DestinationAttribute + DestinationAttribute->Length);
1199  SetFileRecordEnd(FileRecord, NextAttribute, FILE_RECORD_END);
1200  }
1201 
1202  // Update the file record
1203  Status = UpdateFileRecord(Vcb, AttrContext->FileMFTIndex, FileRecord);
1204 
1205  ExFreePoolWithTag(RunBuffer, TAG_NTFS);
1206 
1207  NtfsDumpDataRuns((PUCHAR)((ULONG_PTR)DestinationAttribute + DestinationAttribute->NonResident.MappingPairsOffset), 0);
1208 
1209  return Status;
1210 }
signed char * PCHAR
Definition: retypes.h:7
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define NTFS_FILE_BITMAP
Definition: ntfs.h:29
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3