ReactOS  0.4.14-dev-606-g14ebc0b
attrib.c File Reference
#include "ntfs.h"
#include <ntintsafe.h>
#include <debug.h>
Include dependency graph for attrib.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

AddBitmap

@implemented

Adds a $BITMAP attribute to a given FileRecord.

Parameters
VcbPointer to an NTFS_VCB for the destination volume.
FileRecordPointer to a complete file record to add the attribute to.
AttributeAddressPointer to the region of memory that will receive the $INDEX_ALLOCATION attribute. This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
NamePointer to a string of 16-bit Unicode characters naming the attribute. Most often L"$I30".
NameLengthThe number of wide-characters in the name. L"$I30" Would use 4 here.
Returns
STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record, or if the file record isn't large enough for the attribute.
Remarks
Only adding the attribute to the end of the file record is supported; AttributeAddress must be of type AttributeEnd. This could be improved by adding an $ATTRIBUTE_LIST to the file record if there's not enough space.
NTSTATUS AddBitmap (PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PCWSTR Name, USHORT NameLength)
 
AddData

@implemented

Adds a $DATA attribute to a given FileRecord.

Parameters
FileRecordPointer to a complete file record to add the attribute to. Caller is responsible for ensuring FileRecord is large enough to contain $DATA.
AttributeAddressPointer to the region of memory that will receive the $DATA attribute. This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
Returns
STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record.
Remarks
Only adding the attribute to the end of the file record is supported; AttributeAddress must be of type AttributeEnd. As it's implemented, this function is only intended to assist in creating new file records. It could be made more general-purpose by considering file records with an $ATTRIBUTE_LIST. It's the caller's responsibility to ensure the given file record has enough memory allocated for the attribute.
NTSTATUS AddData (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
 
AddFileName

@implemented

Adds a $FILE_NAME attribute to a given FileRecord.

Parameters
FileRecordPointer to a complete file record to add the attribute to. Caller is responsible for ensuring FileRecord is large enough to contain $FILE_NAME.
AttributeAddressPointer to the region of memory that will receive the $FILE_NAME attribute. This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
DeviceExtPoints to the target disk's DEVICE_EXTENSION.
FileObjectPointer to the FILE_OBJECT which represents the new name. This parameter is used to determine the filename and parent directory.
CaseSensitiveBoolean indicating if the function should operate in case-sensitive mode. This will be TRUE if an application opened the file with the FILE_FLAG_POSIX_SEMANTICS flag.
ParentMftIndexPointer to a ULONGLONG which will receive the index of the parent directory.
Returns
STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record.
Remarks
Only adding the attribute to the end of the file record is supported; AttributeAddress must be of type AttributeEnd. As it's implemented, this function is only intended to assist in creating new file records. It could be made more general-purpose by considering file records with an $ATTRIBUTE_LIST. It's the caller's responsibility to ensure the given file record has enough memory allocated for the attribute.
NTSTATUS AddFileName (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PULONGLONG ParentMftIndex)
 
AddIndexAllocation

@implemented

Adds an $INDEX_ALLOCATION attribute to a given FileRecord.

Parameters
VcbPointer to an NTFS_VCB for the destination volume.
FileRecordPointer to a complete file record to add the attribute to.
AttributeAddressPointer to the region of memory that will receive the $INDEX_ALLOCATION attribute. This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
NamePointer to a string of 16-bit Unicode characters naming the attribute. Most often, this will be L"$I30".
NameLengthThe number of wide-characters in the name. L"$I30" Would use 4 here.
Returns
STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record, or if the file record isn't large enough for the attribute.
Remarks
Only adding the attribute to the end of the file record is supported; AttributeAddress must be of type AttributeEnd. This could be improved by adding an $ATTRIBUTE_LIST to the file record if there's not enough space.
NTSTATUS AddIndexAllocation (PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PCWSTR Name, USHORT NameLength)
 
AddIndexRoot

@implemented

Adds an $INDEX_ROOT attribute to a given FileRecord.

Parameters
VcbPointer to an NTFS_VCB for the destination volume.
FileRecordPointer to a complete file record to add the attribute to. Caller is responsible for ensuring FileRecord is large enough to contain $INDEX_ROOT.
AttributeAddressPointer to the region of memory that will receive the $INDEX_ROOT attribute. This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
NewIndexRootPointer to an INDEX_ROOT_ATTRIBUTE containing the index root that will be copied to the new attribute.
RootLengthThe length of NewIndexRoot, in bytes.
NamePointer to a string of 16-bit Unicode characters naming the attribute. Most often, this will be L"$I30".
NameLengthThe number of wide-characters in the name. L"$I30" Would use 4 here.
Returns
STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record.
Remarks
This function is intended to assist in creating new folders. Only adding the attribute to the end of the file record is supported; AttributeAddress must be of type AttributeEnd. It's the caller's responsibility to ensure the given file record has enough memory allocated for the attribute, and this memory must have been zeroed.
NTSTATUS AddIndexRoot (PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PINDEX_ROOT_ATTRIBUTE NewIndexRoot, ULONG RootLength, PCWSTR Name, USHORT NameLength)
 
AddRun

@implemented

Adds a run of allocated clusters to a non-resident attribute.

Parameters
VcbPointer to an NTFS_VCB for the destination volume.
AttrContextPointer to an NTFS_ATTR_CONTEXT describing the destination attribute.
AttrOffsetByte offset of the destination attribute relative to its file record.
FileRecordPointer to a complete copy of the file record containing the destination attribute. Must be at least Vcb->NtfsInfo.BytesPerFileRecord bytes long.
NextAssignedClusterLogical cluster number of the start of the data run being added.
RunLengthHow many clusters are in the data run being added. Can't be 0.
Returns
STATUS_SUCCESS on success. STATUS_INVALID_PARAMETER if AttrContext describes a resident attribute. STATUS_INSUFFICIENT_RESOURCES if ConvertDataRunsToLargeMCB() fails or if we fail to allocate a buffer for the new data runs. STATUS_INSUFFICIENT_RESOURCES or STATUS_UNSUCCESSFUL if FsRtlAddLargeMcbEntry() fails. STATUS_BUFFER_TOO_SMALL if ConvertLargeMCBToDataRuns() fails. STATUS_NOT_IMPLEMENTED if we need to migrate the attribute to an attribute list (TODO).
Remarks
Clusters should have been allocated previously with NtfsAllocateClusters().
NTSTATUS AddRun (PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONGLONG NextAssignedCluster, ULONG RunLength)
 
AddStandardInformation

@implemented

Adds a $STANDARD_INFORMATION attribute to a given FileRecord.

Parameters
FileRecordPointer to a complete file record to add the attribute to. Caller is responsible for ensuring FileRecord is large enough to contain $STANDARD_INFORMATION.
AttributeAddressPointer to the region of memory that will receive the $STANDARD_INFORMATION attribute. This address must reside within FileRecord. Must be aligned to an 8-byte boundary (relative to FileRecord).
Returns
STATUS_SUCCESS on success. STATUS_NOT_IMPLEMENTED if target address isn't at the end of the given file record.
Remarks
Only adding the attribute to the end of the file record is supported; AttributeAddress must be of type AttributeEnd. As it's implemented, this function is only intended to assist in creating new file records. It could be made more general-purpose by considering file records with an $ATTRIBUTE_LIST. It's the caller's responsibility to ensure the given file record has enough memory allocated for the attribute.
NTSTATUS AddStandardInformation (PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
 
ConvertDataRunsToLargeMCB

@implemented

Converts binary data runs to a map control block.

Parameters
DataRunPointer to the run data
DataRunsMCBPointer to an unitialized LARGE_MCB structure.
Returns
STATUS_SUCCESS on success, STATUS_INSUFFICIENT_RESOURCES or STATUS_UNSUCCESSFUL if we fail to initialize the mcb or add an entry.
Remarks
Initializes the LARGE_MCB pointed to by DataRunsMCB. If this function succeeds, you need to call FsRtlUninitializeLargeMcb() when you're done with DataRunsMCB. This function will ensure the LargeMCB has been unitialized in case of failure.
NTSTATUS ConvertDataRunsToLargeMCB (PUCHAR DataRun, PLARGE_MCB DataRunsMCB, PULONGLONG pNextVBN)
 
ConvertLargeMCBToDataRuns

@implemented

Converts a map control block to a series of encoded data runs (used by non-resident attributes).

Parameters
DataRunsMCBPointer to a LARGE_MCB structure describing the data runs.
RunBufferPointer to the buffer that will receive the encoded data runs.
MaxBufferSizeSize of RunBuffer, in bytes.
UsedBufferSizePointer to a ULONG that will receive the size of the data runs in bytes. Can't be NULL.
Returns
STATUS_SUCCESS on success, STATUS_BUFFER_TOO_SMALL if RunBuffer is too small to contain the complete output.
NTSTATUS ConvertLargeMCBToDataRuns (PLARGE_MCB DataRunsMCB, PUCHAR RunBuffer, ULONG MaxBufferSize, PULONG UsedBufferSize)
 
PUCHAR DecodeRun (PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
 
BOOLEAN FindRun (PNTFS_ATTR_RECORD NresAttr, ULONGLONG vcn, PULONGLONG lcn, PULONGLONG count)
 
FreeClusters

@implemented

Shrinks the allocation size of a non-resident attribute by a given number of clusters. Frees the clusters from the volume's $BITMAP file as well as the attribute's data runs.

Parameters
VcbPointer to an NTFS_VCB for the destination volume.
AttrContextPointer to an NTFS_ATTR_CONTEXT describing the attribute from which the clusters will be freed.
AttrOffsetByte offset of the destination attribute relative to its file record.
FileRecordPointer to a complete copy of the file record containing the attribute. Must be at least Vcb->NtfsInfo.BytesPerFileRecord bytes long.
ClustersToFreeNumber of clusters that should be freed from the end of the data stream. Must be no more Than the number of clusters assigned to the attribute (HighestVCN + 1).
Returns
STATUS_SUCCESS on success. STATUS_INVALID_PARAMETER if AttrContext describes a resident attribute, or if the caller requested more clusters be freed than the attribute has been allocated. STATUS_INSUFFICIENT_RESOURCES if allocating a buffer for the data runs fails or if ConvertDataRunsToLargeMCB() fails. STATUS_BUFFER_TOO_SMALL if ConvertLargeMCBToDataRuns() fails.
NTSTATUS FreeClusters (PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONG ClustersToFree)
 
static NTSTATUS InternalReadNonResidentAttributes (PFIND_ATTR_CONTXT Context)
 
static PNTFS_ATTRIBUTE_LIST_ITEM InternalGetNextAttributeListItem (PFIND_ATTR_CONTXT Context)
 
NTSTATUS FindFirstAttributeListItem (PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
 
NTSTATUS FindNextAttributeListItem (PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
 
static PNTFS_ATTR_RECORD InternalGetNextAttribute (PFIND_ATTR_CONTXT Context)
 
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)
 
static VOID NtfsDumpFileNameAttribute (PNTFS_ATTR_RECORD Attribute)
 
static VOID NtfsDumpStandardInformationAttribute (PNTFS_ATTR_RECORD Attribute)
 
static VOID NtfsDumpVolumeNameAttribute (PNTFS_ATTR_RECORD Attribute)
 
static VOID NtfsDumpVolumeInformationAttribute (PNTFS_ATTR_RECORD Attribute)
 
static VOID NtfsDumpIndexRootAttribute (PNTFS_ATTR_RECORD Attribute)
 
static VOID NtfsDumpAttribute (PDEVICE_EXTENSION Vcb, PNTFS_ATTR_RECORD Attribute)
 
VOID NtfsDumpDataRunData (PUCHAR DataRun)
 
VOID NtfsDumpDataRuns (PVOID StartOfRun, ULONGLONG CurrentLCN)
 
VOID NtfsDumpFileAttributes (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)
 
PSTANDARD_INFORMATION GetStandardInformationFromRecord (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
 
GetFileNameAttributeLength

@implemented

Returns the size of a given FILENAME_ATTRIBUTE, in bytes.

Parameters
FileNameAttributePointer to a FILENAME_ATTRIBUTE to determine the size of.
Remarks
The length of a FILENAME_ATTRIBUTE is variable and is dependent on the length of the file name stored at the end. This function operates on the FILENAME_ATTRIBUTE proper, so don't try to pass it a PNTFS_ATTR_RECORD.
ULONG GetFileNameAttributeLength (PFILENAME_ATTRIBUTE FileNameAttribute)
 
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord (PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 34 of file attrib.c.

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().

◆ 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().

◆ 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().

◆ 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().

◆ 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(), ReadAttribute(), 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().

◆ FindRun()

BOOLEAN FindRun ( PNTFS_ATTR_RECORD  NresAttr,
ULONGLONG  vcn,
PULONGLONG  lcn,
PULONGLONG  count 
)

Definition at line 1010 of file attrib.c.

1014 {
1015  if (vcn < NresAttr->NonResident.LowestVCN || vcn > NresAttr->NonResident.HighestVCN)
1016  return FALSE;
1017 
1018  DecodeRun((PUCHAR)((ULONG_PTR)NresAttr + NresAttr->NonResident.MappingPairsOffset), (PLONGLONG)lcn, count);
1019 
1020  return TRUE;
1021 }
#define TRUE
Definition: types.h:120
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned char * PUCHAR
Definition: retypes.h:3
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
Definition: attrib.c:966
uint32_t ULONG_PTR
Definition: typedefs.h:63
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:389
struct NTFS_ATTR_RECORD::@165::@168 NonResident

Referenced by NtfsDumpAttribute().

◆ 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
#define FILE_RECORD_END
Definition: ntfs.h:182
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
_Out_ PLONGLONG LargeVbn
Definition: fsrtlfuncs.h:520
VOID NTAPI FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, IN LONGLONG Vbn)
Definition: largemcb.c:1016
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NtfsDumpDataRuns(PVOID StartOfRun, ULONGLONG CurrentLCN)
Definition: attrib.c:1755
ULONG Length
Definition: ntfs.h:123
BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn)
Definition: largemcb.c:722
smooth NULL
Definition: ftsmooth.c:416
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
int64_t LONGLONG
Definition: typedefs.h:66
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:316
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
#define Vcb
Definition: cdprocs.h:1425
struct BitmapData BitmapData
#define TAG_NTFS
Definition: ntfs.h:12
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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 const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
NTSTATUS ConvertLargeMCBToDataRuns(PLARGE_MCB DataRunsMCB, PUCHAR RunBuffer, ULONG MaxBufferSize, PULONG UsedBufferSize)
Definition: attrib.c:896
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1631
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
struct NTFS_ATTR_RECORD::@165::@168 NonResident
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
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 min(a, b)
Definition: monoChain.cc:55
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define ALIGN_UP_BY(size, align)
_Out_ PLONGLONG _Out_ PLONGLONG LargeLbn
Definition: fsrtlfuncs.h:520
#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
#define ULONG_MAX
Definition: limits.h:44

Referenced by FatExamineFatEntries(), GetDiskFreeSpaceW(), HandleNotify(), NtfsAllocateClusters(), NtfsGetFreeClusters(), DriveVolume::ObtainInfo(), and SetNonResidentAttributeDataLength().

◆ GetBestFileNameFromRecord()

PFILENAME_ATTRIBUTE GetBestFileNameFromRecord ( PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  FileRecord 
)

Definition at line 1985 of file attrib.c.

1987 {
1989 
1991  if (FileName == NULL)
1992  {
1994  if (FileName == NULL)
1995  {
1997  }
1998  }
1999 
2000  return FileName;
2001 }
#define NTFS_FILE_NAME_DOS
Definition: ntfs.h:65
PFILENAME_ATTRIBUTE GetFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, UCHAR NameType)
Definition: attrib.c:1809
#define NTFS_FILE_NAME_POSIX
Definition: ntfs.h:63
smooth NULL
Definition: ftsmooth.c:416
#define Vcb
Definition: cdprocs.h:1425
struct _FileName FileName
Definition: fatprocs.h:884
#define NTFS_FILE_NAME_WIN32
Definition: ntfs.h:64

Referenced by NtfsGetBothDirectoryInformation(), NtfsGetDirectoryInformation(), NtfsGetFullDirectoryInformation(), NtfsGetNamesInformation(), NtfsMakeFCBFromDirEntry(), NtfsMoonWalkID(), NtfsSetEndOfFile(), and NtfsWriteFile().

◆ GetFileNameAttributeLength()

ULONG GetFileNameAttributeLength ( PFILENAME_ATTRIBUTE  FileNameAttribute)

Definition at line 1978 of file attrib.c.

1979 {
1980  ULONG Length = FIELD_OFFSET(FILENAME_ATTRIBUTE, Name) + (FileNameAttribute->NameLength * sizeof(WCHAR));
1981  return Length;
1982 }
UCHAR NameLength
Definition: ntfs.h:373
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int ULONG
Definition: retypes.h:1

Referenced by CreateBTreeKeyFromFilename().

◆ GetFileNameFromRecord()

PFILENAME_ATTRIBUTE GetFileNameFromRecord ( PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  FileRecord,
UCHAR  NameType 
)

Definition at line 1809 of file attrib.c.

1812 {
1814  PNTFS_ATTR_RECORD Attribute;
1816  NTSTATUS Status;
1817 
1818  Status = FindFirstAttribute(&Context, Vcb, FileRecord, FALSE, &Attribute);
1819  while (NT_SUCCESS(Status))
1820  {
1821  if (Attribute->Type == AttributeFileName)
1822  {
1823  Name = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1824  if (Name->NameType == NameType ||
1827  {
1829  return Name;
1830  }
1831  }
1832 
1833  Status = FindNextAttribute(&Context, &Attribute);
1834  }
1835 
1837  return NULL;
1838 }
#define NTFS_FILE_NAME_DOS
Definition: ntfs.h:65
LONG NTSTATUS
Definition: precomp.h:26
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
struct NameRec_ * Name
Definition: cdprocs.h:464
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1431
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1465
Status
Definition: gdiplustypes.h:24
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1383
struct tagContext Context
Definition: acpixf.h:1030
#define NTFS_FILE_NAME_WIN32
Definition: ntfs.h:64
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 NameType
Definition: acpixf.h:654
struct NTFS_ATTR_RECORD::@165::@167 Resident
#define NTFS_FILE_NAME_WIN32_AND_DOS
Definition: ntfs.h:66

Referenced by GetBestFileNameFromRecord(), NtfsGetBothDirectoryInformation(), and NtfsMakeRootFCB().

◆ GetLastClusterInDataRun()

NTSTATUS GetLastClusterInDataRun ( PDEVICE_EXTENSION  Vcb,
PNTFS_ATTR_RECORD  Attribute,
PULONGLONG  LastCluster 
)

Definition at line 1908 of file attrib.c.

1909 {
1910  LONGLONG DataRunOffset;
1911  ULONGLONG DataRunLength;
1912  LONGLONG DataRunStartLCN;
1913 
1914  ULONGLONG LastLCN = 0;
1915  PUCHAR DataRun = (PUCHAR)Attribute + Attribute->NonResident.MappingPairsOffset;
1916 
1917  if (!Attribute->IsNonResident)
1918  return STATUS_INVALID_PARAMETER;
1919 
1920  while (1)
1921  {
1922  DataRun = DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
1923 
1924  if (DataRunOffset != -1)
1925  {
1926  // Normal data run.
1927  DataRunStartLCN = LastLCN + DataRunOffset;
1928  LastLCN = DataRunStartLCN;
1929  *LastCluster = LastLCN + DataRunLength - 1;
1930  }
1931 
1932  if (*DataRun == 0)
1933  break;
1934  }
1935 
1936  return STATUS_SUCCESS;
1937 }
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
Definition: attrib.c:966
int64_t LONGLONG
Definition: typedefs.h:66
if(!(yy_init))
Definition: macro.lex.yy.c:714
uint64_t ULONGLONG
Definition: typedefs.h:65
UCHAR IsNonResident
Definition: ntfs.h:124
struct NTFS_ATTR_RECORD::@165::@168 NonResident
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ GetPackedByteCount()

UCHAR GetPackedByteCount ( LONGLONG  NumberToPack,
BOOLEAN  IsSigned 
)

GetPackedByteCount Returns the minimum number of bytes needed to represent the value of a 64-bit number. Used to encode data runs.

Definition at line 1846 of file attrib.c.

1848 {
1849  if (!IsSigned)
1850  {
1851  if (NumberToPack >= 0x0100000000000000)
1852  return 8;
1853  if (NumberToPack >= 0x0001000000000000)
1854  return 7;
1855  if (NumberToPack >= 0x0000010000000000)
1856  return 6;
1857  if (NumberToPack >= 0x0000000100000000)
1858  return 5;
1859  if (NumberToPack >= 0x0000000001000000)
1860  return 4;
1861  if (NumberToPack >= 0x0000000000010000)
1862  return 3;
1863  if (NumberToPack >= 0x0000000000000100)
1864  return 2;
1865  return 1;
1866  }
1867 
1868  if (NumberToPack > 0)
1869  {
1870  // we have to make sure the number that gets encoded won't be interpreted as negative
1871  if (NumberToPack >= 0x0080000000000000)
1872  return 8;
1873  if (NumberToPack >= 0x0000800000000000)
1874  return 7;
1875  if (NumberToPack >= 0x0000008000000000)
1876  return 6;
1877  if (NumberToPack >= 0x0000000080000000)
1878  return 5;
1879  if (NumberToPack >= 0x0000000000800000)
1880  return 4;
1881  if (NumberToPack >= 0x0000000000008000)
1882  return 3;
1883  if (NumberToPack >= 0x0000000000000080)
1884  return 2;
1885  }
1886  else
1887  {
1888  // negative number
1889  if (NumberToPack <= 0xff80000000000000)
1890  return 8;
1891  if (NumberToPack <= 0xffff800000000000)
1892  return 7;
1893  if (NumberToPack <= 0xffffff8000000000)
1894  return 6;
1895  if (NumberToPack <= 0xffffffff80000000)
1896  return 5;
1897  if (NumberToPack <= 0xffffffffff800000)
1898  return 4;
1899  if (NumberToPack <= 0xffffffffffff8000)
1900  return 3;
1901  if (NumberToPack <= 0xffffffffffffff80)
1902  return 2;
1903  }
1904  return 1;
1905 }

Referenced by ConvertLargeMCBToDataRuns().

◆ GetStandardInformationFromRecord()

PSTANDARD_INFORMATION GetStandardInformationFromRecord ( PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  FileRecord 
)

Definition at line 1940 of file attrib.c.

1942 {
1943  NTSTATUS Status;
1945  PNTFS_ATTR_RECORD Attribute;
1946  PSTANDARD_INFORMATION StdInfo;
1947 
1948  Status = FindFirstAttribute(&Context, Vcb, FileRecord, FALSE, &Attribute);
1949  while (NT_SUCCESS(Status))
1950  {
1951  if (Attribute->Type == AttributeStandardInformation)
1952  {
1953  StdInfo = (PSTANDARD_INFORMATION)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1955  return StdInfo;
1956  }
1957 
1958  Status = FindNextAttribute(&Context, &Attribute);
1959  }
1960 
1962  return NULL;
1963 }
LONG NTSTATUS
Definition: precomp.h:26
ULONG Type
Definition: ntfs.h:122
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
struct STANDARD_INFORMATION * PSTANDARD_INFORMATION
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1431
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1465
Status
Definition: gdiplustypes.h:24
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1383
struct tagContext Context
Definition: acpixf.h:1030
struct NTFS_ATTR_RECORD::@165::@167 Resident

Referenced by NtfsGetBothDirectoryInformation(), NtfsGetDirectoryInformation(), NtfsGetFullDirectoryInformation(), and NtfsMakeFCBFromDirEntry().

◆ InternalGetNextAttribute()

static PNTFS_ATTR_RECORD InternalGetNextAttribute ( PFIND_ATTR_CONTXT  Context)
static

Definition at line 1334 of file attrib.c.

1335 {
1336  PNTFS_ATTR_RECORD NextAttribute;
1337 
1338  if (Context->CurrAttr == (PVOID)-1)
1339  {
1340  return NULL;
1341  }
1342 
1343  if (Context->CurrAttr >= Context->FirstAttr &&
1344  Context->CurrAttr < Context->LastAttr)
1345  {
1346  if (Context->CurrAttr->Length == 0)
1347  {
1348  DPRINT1("Broken length!\n");
1349  Context->CurrAttr = (PVOID)-1;
1350  return NULL;
1351  }
1352 
1353  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Context->CurrAttr + Context->CurrAttr->Length);
1354 
1355  if (NextAttribute > Context->LastAttr || NextAttribute < Context->FirstAttr)
1356  {
1357  DPRINT1("Broken length: 0x%lx!\n", Context->CurrAttr->Length);
1358  Context->CurrAttr = (PVOID)-1;
1359  return NULL;
1360  }
1361 
1362  Context->Offset += ((ULONG_PTR)NextAttribute - (ULONG_PTR)Context->CurrAttr);
1363  Context->CurrAttr = NextAttribute;
1364 
1365  if (Context->CurrAttr < Context->LastAttr &&
1366  Context->CurrAttr->Type != AttributeEnd)
1367  {
1368  return Context->CurrAttr;
1369  }
1370  }
1371 
1372  if (Context->NonResidentStart == NULL)
1373  {
1374  Context->CurrAttr = (PVOID)-1;
1375  return NULL;
1376  }
1377 
1378  Context->CurrAttr = (PVOID)-1;
1379  return NULL;
1380 }
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define DPRINT1
Definition: precomp.h:8
#define ULONG_PTR
Definition: config.h:101

Referenced by FindFirstAttribute(), and FindNextAttribute().

◆ InternalGetNextAttributeListItem()

static PNTFS_ATTRIBUTE_LIST_ITEM InternalGetNextAttributeListItem ( PFIND_ATTR_CONTXT  Context)
static

Definition at line 1267 of file attrib.c.

1268 {
1270 
1271  if (Context->NonResidentCur == (PVOID)-1)
1272  {
1273  return NULL;
1274  }
1275 
1276  if (Context->NonResidentCur == NULL || Context->NonResidentCur->Type == AttributeEnd)
1277  {
1278  Context->NonResidentCur = (PVOID)-1;
1279  return NULL;
1280  }
1281 
1282  if (Context->NonResidentCur->Length == 0)
1283  {
1284  DPRINT1("Broken length list entry length !");
1285  Context->NonResidentCur = (PVOID)-1;
1286  return NULL;
1287  }
1288 
1289  NextItem = (PNTFS_ATTRIBUTE_LIST_ITEM)((PCHAR)Context->NonResidentCur + Context->NonResidentCur->Length);
1290  if (NextItem->Length == 0 || NextItem->Type == AttributeEnd)
1291  {
1292  Context->NonResidentCur = (PVOID)-1;
1293  return NULL;
1294  }
1295 
1296  if (NextItem < Context->NonResidentStart || NextItem > Context->NonResidentEnd)
1297  {
1298  Context->NonResidentCur = (PVOID)-1;
1299  return NULL;
1300  }
1301 
1302  Context->NonResidentCur = NextItem;
1303  return NextItem;
1304 }
signed char * PCHAR
Definition: retypes.h:7
struct NTFS_ATTRIBUTE_LIST_ITEM * PNTFS_ATTRIBUTE_LIST_ITEM
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define DPRINT1
Definition: precomp.h:8
static LPDATABLOCK_HEADER NextItem(LPDBLIST lpList)
Definition: clist.c:42

Referenced by FindNextAttributeListItem().

◆ InternalReadNonResidentAttributes()

static NTSTATUS InternalReadNonResidentAttributes ( PFIND_ATTR_CONTXT  Context)
static

Definition at line 1214 of file attrib.c.

1215 {
1216  ULONGLONG ListSize;
1217  PNTFS_ATTR_RECORD Attribute;
1218  PNTFS_ATTR_CONTEXT ListContext;
1219 
1220  DPRINT("InternalReadNonResidentAttributes(%p)\n", Context);
1221 
1222  Attribute = Context->CurrAttr;
1223  ASSERT(Attribute->Type == AttributeAttributeList);
1224 
1225  if (Context->OnlyResident)
1226  {
1227  Context->NonResidentStart = NULL;
1228  Context->NonResidentEnd = NULL;
1229  return STATUS_SUCCESS;
1230  }
1231 
1232  if (Context->NonResidentStart != NULL)
1233  {
1235  }
1236 
1237  ListContext = PrepareAttributeContext(Attribute);
1238  ListSize = AttributeDataLength(ListContext->pRecord);
1239  if (ListSize > 0xFFFFFFFF)
1240  {
1241  ReleaseAttributeContext(ListContext);
1242  return STATUS_BUFFER_OVERFLOW;
1243  }
1244 
1245  Context->NonResidentStart = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS);
1246  if (Context->NonResidentStart == NULL)
1247  {
1248  ReleaseAttributeContext(ListContext);
1250  }
1251 
1252  if (ReadAttribute(Context->Vcb, ListContext, 0, (PCHAR)Context->NonResidentStart, (ULONG)ListSize) != ListSize)
1253  {
1254  ExFreePoolWithTag(Context->NonResidentStart, TAG_NTFS);
1255  Context->NonResidentStart = NULL;
1256  ReleaseAttributeContext(ListContext);
1258  }
1259 
1260  ReleaseAttributeContext(ListContext);
1261  Context->NonResidentEnd = (PNTFS_ATTRIBUTE_LIST_ITEM)((PCHAR)Context->NonResidentStart + ListSize);
1262  return STATUS_SUCCESS;
1263 }
signed char * PCHAR
Definition: retypes.h:7
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG Type
Definition: ntfs.h:122
PNTFS_ATTR_CONTEXT PrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:41
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
struct NTFS_ATTRIBUTE_LIST_ITEM * PNTFS_ATTRIBUTE_LIST_ITEM
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
uint64_t ULONGLONG
Definition: typedefs.h:65
#define TAG_NTFS
Definition: ntfs.h:12
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
ULONG ReadAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
Definition: mft.c:1065
unsigned int ULONG
Definition: retypes.h:1
#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

Referenced by FindFirstAttribute(), and FindNextAttribute().

◆ NtfsDumpAttribute()

static VOID NtfsDumpAttribute ( PDEVICE_EXTENSION  Vcb,
PNTFS_ATTR_RECORD  Attribute 
)
static

Definition at line 1617 of file attrib.c.

1619 {
1621 
1622  ULONGLONG lcn = 0;
1623  ULONGLONG runcount = 0;
1624 
1625  switch (Attribute->Type)
1626  {
1627  case AttributeFileName:
1628  NtfsDumpFileNameAttribute(Attribute);
1629  break;
1630 
1633  break;
1634 
1635  case AttributeObjectId:
1636  DbgPrint(" $OBJECT_ID ");
1637  break;
1638 
1640  DbgPrint(" $SECURITY_DESCRIPTOR ");
1641  break;
1642 
1643  case AttributeVolumeName:
1644  NtfsDumpVolumeNameAttribute(Attribute);
1645  break;
1646 
1649  break;
1650 
1651  case AttributeData:
1652  DbgPrint(" $DATA ");
1653  //DataBuf = ExAllocatePool(NonPagedPool,AttributeLengthAllocated(Attribute));
1654  break;
1655 
1656  case AttributeIndexRoot:
1657  NtfsDumpIndexRootAttribute(Attribute);
1658  break;
1659 
1661  DbgPrint(" $INDEX_ALLOCATION ");
1662  break;
1663 
1664  case AttributeBitmap:
1665  DbgPrint(" $BITMAP ");
1666  break;
1667 
1668  case AttributeReparsePoint:
1669  DbgPrint(" $REPARSE_POINT ");
1670  break;
1671 
1673  DbgPrint(" $EA_INFORMATION ");
1674  break;
1675 
1676  case AttributeEA:
1677  DbgPrint(" $EA ");
1678  break;
1679 
1680  case AttributePropertySet:
1681  DbgPrint(" $PROPERTY_SET ");
1682  break;
1683 
1685  DbgPrint(" $LOGGED_UTILITY_STREAM ");
1686  break;
1687 
1688  default:
1689  DbgPrint(" Attribute %lx ",
1690  Attribute->Type);
1691  break;
1692  }
1693 
1694  if (Attribute->Type != AttributeAttributeList)
1695  {
1696  if (Attribute->NameLength != 0)
1697  {
1698  Name.Length = Attribute->NameLength * sizeof(WCHAR);
1699  Name.MaximumLength = Name.Length;
1700  Name.Buffer = (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset);
1701 
1702  DbgPrint("'%wZ' ", &Name);
1703  }
1704 
1705  DbgPrint("(%s)\n",
1706  Attribute->IsNonResident ? "non-resident" : "resident");
1707 
1708  if (Attribute->IsNonResident)
1709  {
1710  FindRun(Attribute,0,&lcn, &runcount);
1711 
1712  DbgPrint(" AllocatedSize %I64u DataSize %I64u InitilizedSize %I64u\n",
1713  Attribute->NonResident.AllocatedSize, Attribute->NonResident.DataSize, Attribute->NonResident.InitializedSize);
1714  DbgPrint(" logical clusters: %I64u - %I64u\n",
1715  lcn, lcn + runcount - 1);
1716  }
1717  else
1718  DbgPrint(" %u bytes of data\n", Attribute->Resident.ValueLength);
1719  }
1720 }
USHORT NameOffset
Definition: ntfs.h:126
#define DbgPrint
Definition: loader.c:25
static VOID NtfsDumpVolumeNameAttribute(PNTFS_ATTR_RECORD Attribute)
Definition: attrib.c:1509
ULONG Type
Definition: ntfs.h:122
BOOLEAN FindRun(PNTFS_ATTR_RECORD NresAttr, ULONGLONG vcn, PULONGLONG lcn, PULONGLONG count)
Definition: attrib.c:1010
uint16_t * PWCHAR
Definition: typedefs.h:54
uint32_t ULONG_PTR
Definition: typedefs.h:63
static VOID NtfsDumpStandardInformationAttribute(PNTFS_ATTR_RECORD Attribute)
Definition: attrib.c:1494
struct NameRec_ * Name
Definition: cdprocs.h:464
static VOID NtfsDumpVolumeInformationAttribute(PNTFS_ATTR_RECORD Attribute)
Definition: attrib.c:1524
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint64_t ULONGLONG
Definition: typedefs.h:65
UCHAR IsNonResident
Definition: ntfs.h:124
static VOID NtfsDumpIndexRootAttribute(PNTFS_ATTR_RECORD Attribute)
Definition: attrib.c:1542
UCHAR NameLength
Definition: ntfs.h:125
struct NTFS_ATTR_RECORD::@165::@168 NonResident
static VOID NtfsDumpFileNameAttribute(PNTFS_ATTR_RECORD Attribute)
Definition: attrib.c:1476
struct NTFS_ATTR_RECORD::@165::@167 Resident

Referenced by NtfsDumpFileAttributes().

◆ NtfsDumpDataRunData()

VOID NtfsDumpDataRunData ( PUCHAR  DataRun)

Definition at line 1723 of file attrib.c.

1724 {
1725  UCHAR DataRunOffsetSize;
1726  UCHAR DataRunLengthSize;
1727  CHAR i;
1728 
1729  DbgPrint("%02x ", *DataRun);
1730 
1731  if (*DataRun == 0)
1732  return;
1733 
1734  DataRunOffsetSize = (*DataRun >> 4) & 0xF;
1735  DataRunLengthSize = *DataRun & 0xF;
1736 
1737  DataRun++;
1738  for (i = 0; i < DataRunLengthSize; i++)
1739  {
1740  DbgPrint("%02x ", *DataRun);
1741  DataRun++;
1742  }
1743 
1744  for (i = 0; i < DataRunOffsetSize; i++)
1745  {
1746  DbgPrint("%02x ", *DataRun);
1747  DataRun++;
1748  }
1749 
1750  NtfsDumpDataRunData(DataRun);
1751 }
#define DbgPrint
Definition: loader.c:25
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 NtfsDumpDataRunData(PUCHAR DataRun)
Definition: attrib.c:1723
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by NtfsDumpDataRuns().

◆ NtfsDumpDataRuns()

VOID NtfsDumpDataRuns ( PVOID  StartOfRun,
ULONGLONG  CurrentLCN 
)

Definition at line 1755 of file attrib.c.

1757 {
1758  PUCHAR DataRun = StartOfRun;
1759  LONGLONG DataRunOffset;
1760  ULONGLONG DataRunLength;
1761 
1762  if (CurrentLCN == 0)
1763  {
1764  DPRINT1("Dumping data runs.\n\tData:\n\t\t");
1765  NtfsDumpDataRunData(StartOfRun);
1766  DbgPrint("\n\tRuns:\n\t\tOff\t\tLCN\t\tLength\n");
1767  }
1768 
1769  DataRun = DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
1770 
1771  if (DataRunOffset != -1)
1772  CurrentLCN += DataRunOffset;
1773 
1774  DbgPrint("\t\t%I64d\t", DataRunOffset);
1775  if (DataRunOffset < 99999)
1776  DbgPrint("\t");
1777  DbgPrint("%I64u\t", CurrentLCN);
1778  if (CurrentLCN < 99999)
1779  DbgPrint("\t");
1780  DbgPrint("%I64u\n", DataRunLength);
1781 
1782  if (*DataRun == 0)
1783  DbgPrint("\t\t00\n");
1784  else
1785  NtfsDumpDataRuns(DataRun, CurrentLCN);
1786 }
#define DbgPrint
Definition: loader.c:25
unsigned char * PUCHAR
Definition: retypes.h:3
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
Definition: attrib.c:966
VOID NtfsDumpDataRuns(PVOID StartOfRun, ULONGLONG CurrentLCN)
Definition: attrib.c:1755
VOID NtfsDumpDataRunData(PUCHAR DataRun)
Definition: attrib.c:1723
int64_t LONGLONG
Definition: typedefs.h:66
uint64_t ULONGLONG
Definition: typedefs.h:65
#define DPRINT1
Definition: precomp.h:8

Referenced by AddRun(), FreeClusters(), and NtfsDumpDataRuns().

◆ NtfsDumpFileAttributes()

VOID NtfsDumpFileAttributes ( PDEVICE_EXTENSION  Vcb,
PFILE_RECORD_HEADER  FileRecord 
)

Definition at line 1790 of file attrib.c.

1792 {
1793  NTSTATUS Status;
1795  PNTFS_ATTR_RECORD Attribute;
1796 
1797  Status = FindFirstAttribute(&Context, Vcb, FileRecord, FALSE, &Attribute);
1798  while (NT_SUCCESS(Status))
1799  {
1800  NtfsDumpAttribute(Vcb, Attribute);
1801 
1802  Status = FindNextAttribute(&Context, &Attribute);
1803  }
1804 
1806 }
LONG NTSTATUS
Definition: precomp.h:26
static VOID NtfsDumpAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_RECORD Attribute)
Definition: attrib.c:1617
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1431
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1465
Status
Definition: gdiplustypes.h:24
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1383
struct tagContext Context
Definition: acpixf.h:1030

Referenced by IncreaseMftSize(), NtfsDumpFileRecord(), NtfsGetBothDirectoryInformation(), NtfsGetDirectoryInformation(), NtfsGetFullDirectoryInformation(), NtfsGetNamesInformation(), and NtfsGetVolumeData().

◆ NtfsDumpFileNameAttribute()

static VOID NtfsDumpFileNameAttribute ( PNTFS_ATTR_RECORD  Attribute)
static

Definition at line 1476 of file attrib.c.

1477 {
1478  PFILENAME_ATTRIBUTE FileNameAttr;
1479 
1480  DbgPrint(" $FILE_NAME ");
1481 
1482 // DbgPrint(" Length %lu Offset %hu ", Attribute->Resident.ValueLength, Attribute->Resident.ValueOffset);
1483 
1484  FileNameAttr = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1485  DbgPrint(" (%x) '%.*S' ", FileNameAttr->NameType, FileNameAttr->NameLength, FileNameAttr->Name);
1486  DbgPrint(" '%x' \n", FileNameAttr->FileAttributes);
1487  DbgPrint(" AllocatedSize: %I64u\nDataSize: %I64u\n", FileNameAttr->AllocatedSize, FileNameAttr->DataSize);
1488  DbgPrint(" File reference: 0x%016I64x\n", FileNameAttr->DirectoryFileReferenceNumber);
1489 }
ULONGLONG AllocatedSize
Definition: ntfs.h:361
#define DbgPrint
Definition: loader.c:25
WCHAR Name[1]
Definition: ntfs.h:375
UCHAR NameLength
Definition: ntfs.h:373
ULONG FileAttributes
Definition: ntfs.h:363
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
ULONGLONG DataSize
Definition: ntfs.h:362
ULONGLONG DirectoryFileReferenceNumber
Definition: ntfs.h:356
struct NTFS_ATTR_RECORD::@165::@167 Resident
UCHAR NameType
Definition: ntfs.h:374

Referenced by NtfsDumpAttribute().

◆ NtfsDumpIndexRootAttribute()

static VOID NtfsDumpIndexRootAttribute ( PNTFS_ATTR_RECORD  Attribute)
static

Definition at line 1542 of file attrib.c.

1543 {
1544  PINDEX_ROOT_ATTRIBUTE IndexRootAttr;
1545  ULONG CurrentOffset;
1546  ULONG CurrentNode;
1547 
1548  IndexRootAttr = (PINDEX_ROOT_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1549 
1550  if (IndexRootAttr->AttributeType == AttributeFileName)
1551  ASSERT(IndexRootAttr->CollationRule == COLLATION_FILE_NAME);
1552 
1553  DbgPrint(" $INDEX_ROOT (%u bytes per index record, %u clusters) ", IndexRootAttr->SizeOfEntry, IndexRootAttr->ClustersPerIndexRecord);
1554 
1555  if (IndexRootAttr->Header.Flags == INDEX_ROOT_SMALL)
1556  {
1557  DbgPrint(" (small)\n");
1558  }
1559  else
1560  {
1561  ASSERT(IndexRootAttr->Header.Flags == INDEX_ROOT_LARGE);
1562  DbgPrint(" (large)\n");
1563  }
1564 
1565  DbgPrint(" Offset to first index: 0x%lx\n Total size of index entries: 0x%lx\n Allocated size of node: 0x%lx\n",
1566  IndexRootAttr->Header.FirstEntryOffset,
1567  IndexRootAttr->Header.TotalSizeOfEntries,
1568  IndexRootAttr->Header.AllocatedSize);
1569  CurrentOffset = IndexRootAttr->Header.FirstEntryOffset;
1570  CurrentNode = 0;
1571  // print details of every node in the index
1572  while (CurrentOffset < IndexRootAttr->Header.TotalSizeOfEntries)
1573  {
1574  PINDEX_ENTRY_ATTRIBUTE currentIndexExtry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)IndexRootAttr + 0x10 + CurrentOffset);
1575  DbgPrint(" Index Node Entry %lu", CurrentNode++);
1576  if (BooleanFlagOn(currentIndexExtry->Flags, NTFS_INDEX_ENTRY_NODE))
1577  DbgPrint(" (Branch)");
1578  else
1579  DbgPrint(" (Leaf)");
1580  if (BooleanFlagOn(currentIndexExtry->Flags, NTFS_INDEX_ENTRY_END))
1581  {
1582  DbgPrint(" (Dummy Key)");
1583  }
1584  DbgPrint("\n File Reference: 0x%016I64x\n", currentIndexExtry->Data.Directory.IndexedFile);
1585  DbgPrint(" Index Entry Length: 0x%x\n", currentIndexExtry->Length);
1586  DbgPrint(" Index Key Length: 0x%x\n", currentIndexExtry->KeyLength);
1587 
1588  // if this isn't the final (dummy) node, print info about the key (Filename attribute)
1589  if (!(currentIndexExtry->Flags & NTFS_INDEX_ENTRY_END))
1590  {
1592  DbgPrint(" Parent File Reference: 0x%016I64x\n", currentIndexExtry->FileName.DirectoryFileReferenceNumber);
1593  DbgPrint(" $FILENAME indexed: ");
1594  Name.Length = currentIndexExtry->FileName.NameLength * sizeof(WCHAR);
1595  Name.MaximumLength = Name.Length;
1596  Name.Buffer = currentIndexExtry->FileName.Name;
1597  DbgPrint("'%wZ'\n", &Name);
1598  }
1599 
1600  // if this node has a sub-node beneath it
1601  if (currentIndexExtry->Flags & NTFS_INDEX_ENTRY_NODE)
1602  {
1603  // Print the VCN of the sub-node
1604  PULONGLONG SubNodeVCN = (PULONGLONG)((ULONG_PTR)currentIndexExtry + currentIndexExtry->Length - sizeof(ULONGLONG));
1605  DbgPrint(" VCN of sub-node: 0x%llx\n", *SubNodeVCN);
1606  }
1607 
1608  CurrentOffset += currentIndexExtry->Length;
1609  ASSERT(currentIndexExtry->Length);
1610  }
1611 
1612 }
ULONG CollationRule
Definition: ntfs.h:390
FILENAME_ATTRIBUTE FileName
Definition: ntfs.h:423
#define DbgPrint
Definition: loader.c:25
WCHAR Name[1]
Definition: ntfs.h:375
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
USHORT Length
Definition: ntfs.h:419
UCHAR NameLength
Definition: ntfs.h:373
Definition: ntfs.h:404
#define NTFS_INDEX_ENTRY_END
Definition: ntfs.h:61
USHORT KeyLength
Definition: ntfs.h:420
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG FirstEntryOffset
Definition: ntfs.h:380
struct INDEX_ENTRY_ATTRIBUTE::@761::@762 Directory
Definition: Header.h:8
struct NameRec_ * Name
Definition: cdprocs.h:464
ULONG SizeOfEntry
Definition: ntfs.h:391
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint64_t ULONGLONG
Definition: typedefs.h:65
ULONG AttributeType
Definition: ntfs.h:389
INDEX_HEADER_ATTRIBUTE Header
Definition: ntfs.h:394
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
USHORT Flags
Definition: ntfs.h:421
ULONG TotalSizeOfEntries
Definition: ntfs.h:381
ULONGLONG DirectoryFileReferenceNumber
Definition: ntfs.h:356
#define INDEX_ROOT_LARGE
Definition: ntfs.h:209
UCHAR ClustersPerIndexRecord
Definition: ntfs.h:392
#define NTFS_INDEX_ENTRY_NODE
Definition: ntfs.h:60
#define INDEX_ROOT_SMALL
Definition: ntfs.h:208
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
unsigned int ULONG
Definition: retypes.h:1
struct INDEX_ROOT_ATTRIBUTE * PINDEX_ROOT_ATTRIBUTE
union INDEX_ENTRY_ATTRIBUTE::@761 Data
struct NTFS_ATTR_RECORD::@165::@167 Resident
#define COLLATION_FILE_NAME
Definition: ntfs.h:201
struct INDEX_ENTRY_ATTRIBUTE * PINDEX_ENTRY_ATTRIBUTE

Referenced by NtfsDumpAttribute().

◆ NtfsDumpStandardInformationAttribute()

static VOID NtfsDumpStandardInformationAttribute ( PNTFS_ATTR_RECORD  Attribute)
static

Definition at line 1494 of file attrib.c.

1495 {
1496  PSTANDARD_INFORMATION StandardInfoAttr;
1497 
1498  DbgPrint(" $STANDARD_INFORMATION ");
1499 
1500 // DbgPrint(" Length %lu Offset %hu ", Attribute->Resident.ValueLength, Attribute->Resident.ValueOffset);
1501 
1502  StandardInfoAttr = (PSTANDARD_INFORMATION)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1503  DbgPrint(" '%x' ", StandardInfoAttr->FileAttribute);
1504 }
#define DbgPrint
Definition: loader.c:25
ULONG FileAttribute
Definition: ntfs.h:330
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct STANDARD_INFORMATION * PSTANDARD_INFORMATION
struct NTFS_ATTR_RECORD::@165::@167 Resident

Referenced by NtfsDumpAttribute().

◆ NtfsDumpVolumeInformationAttribute()

static VOID NtfsDumpVolumeInformationAttribute ( PNTFS_ATTR_RECORD  Attribute)
static

Definition at line 1524 of file attrib.c.

1525 {
1526  PVOLINFO_ATTRIBUTE VolInfoAttr;
1527 
1528  DbgPrint(" $VOLUME_INFORMATION ");
1529 
1530 // DbgPrint(" Length %lu Offset %hu ", Attribute->Resident.ValueLength, Attribute->Resident.ValueOffset);
1531 
1532  VolInfoAttr = (PVOLINFO_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1533  DbgPrint(" NTFS Version %u.%u Flags 0x%04hx ",
1534  VolInfoAttr->MajorVersion,
1535  VolInfoAttr->MinorVersion,
1536  VolInfoAttr->Flags);
1537 }
#define DbgPrint
Definition: loader.c:25
UCHAR MajorVersion
Definition: ntfs.h:457
struct VOLINFO_ATTRIBUTE * PVOLINFO_ATTRIBUTE
uint32_t ULONG_PTR
Definition: typedefs.h:63
USHORT Flags
Definition: ntfs.h:459
UCHAR MinorVersion
Definition: ntfs.h:458
struct NTFS_ATTR_RECORD::@165::@167 Resident

Referenced by NtfsDumpAttribute().

◆ NtfsDumpVolumeNameAttribute()

static VOID NtfsDumpVolumeNameAttribute ( PNTFS_ATTR_RECORD  Attribute)
static

Definition at line 1509 of file attrib.c.

1510 {
1512 
1513  DbgPrint(" $VOLUME_NAME ");
1514 
1515 // DbgPrint(" Length %lu Offset %hu ", Attribute->Resident.ValueLength, Attribute->Resident.ValueOffset);
1516 
1517  VolumeName = (PWCHAR)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1518  DbgPrint(" '%.*S' ", Attribute->Resident.ValueLength / sizeof(WCHAR), VolumeName);
1519 }
#define DbgPrint
Definition: loader.c:25
uint16_t * PWCHAR
Definition: typedefs.h:54
uint32_t ULONG_PTR
Definition: typedefs.h:63
__wchar_t WCHAR
Definition: xmlstorage.h:180
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
struct NTFS_ATTR_RECORD::@165::@167 Resident

Referenced by NtfsDumpAttribute().