ReactOS 0.4.17-dev-1190-g4c812f4
finfo.c File Reference
#include "ntfs.h"
#include <debug.h>
Include dependency graph for finfo.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define NTFS_MAX_NAME_LENGTH   255
 

Functions

static NTSTATUS NtfsGetStandardInformation (PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetPositionInformation (PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetBasicInformation (PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetAttributeTagInformation (PNTFS_FCB Fcb, PFILE_ATTRIBUTE_TAG_INFORMATION AttributeTagInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetEaInformation (PNTFS_FCB Fcb, PFILE_EA_INFORMATION EaInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetNameInformation (PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetInternalInformation (PNTFS_FCB Fcb, PFILE_INTERNAL_INFORMATION InternalInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetNetworkOpenInformation (PNTFS_FCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_NETWORK_OPEN_INFORMATION NetworkInfo, PULONG BufferLength)
 
static NTSTATUS NtfsGetStreamInformation (PNTFS_FCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_STREAM_INFORMATION StreamInfo, PULONG BufferLength)
 
const PCSTR GetInfoClassName (FILE_INFORMATION_CLASS infoClass)
 
NTSTATUS NtfsQueryInformation (PNTFS_IRP_CONTEXT IrpContext)
 
NtfsSetEndOfFile

@implemented

Sets the end of file (file size) for a given file.

Parameters
FcbPointer to an NTFS_FCB which describes the target file. Fcb->MainResource should have been acquired with ExAcquireResourceSharedLite().
FileObjectPointer to a FILE_OBJECT describing the target file.
DeviceExtPoints to the target disk's DEVICE_EXTENSION
IrpFlagsULONG describing the flags of the original IRP request (Irp->Flags).
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.
NewFileSizePointer to a LARGE_INTEGER which indicates the new end of file (file size).
Returns
STATUS_SUCCESS if successful, STATUS_USER_MAPPED_FILE if trying to truncate a file but MmCanFileBeTruncated() returned false, STATUS_OBJECT_NAME_NOT_FOUND if there was no $DATA attribute associated with the target file, STATUS_INVALID_PARAMETER if there was no $FILENAME attribute associated with the target file, STATUS_INSUFFICIENT_RESOURCES if an allocation failed, STATUS_ACCESS_DENIED if target file is a volume or if paging is involved.
Remarks
As this function sets the size of a file at the file-level (and not at the attribute level) it's not recommended to use this function alongside functions that operate on the data attribute directly.
NTSTATUS NtfsSetEndOfFile (PNTFS_FCB Fcb, PFILE_OBJECT FileObject, PDEVICE_EXTENSION DeviceExt, ULONG IrpFlags, BOOLEAN CaseSensitive, PLARGE_INTEGER NewFileSize)
 
static NTSTATUS NTAPI NtfsSetAllocationInformation (_In_ PNTFS_FCB Fcb, _In_ PFILE_OBJECT FileObject, _In_ PDEVICE_EXTENSION DeviceExt, _In_ ULONG IrpFlags, _In_ BOOLEAN CaseSensitive, _In_ PLARGE_INTEGER AllocationSize)
 
NtfsSetBasicInformation

@implemented

Applies a FILE_BASIC_INFORMATION to a file: its four timestamps and its attribute flags.

Parameters
DeviceExtPoints to the target disk's DEVICE_EXTENSION
FcbFile control block of the file being changed
CaseSensitiveWhether the parent directory's index should be searched case-sensitively
BasicInfoThe timestamps and attributes to apply
Returns
STATUS_SUCCESS on success, STATUS_INSUFFICIENT_RESOURCES if an allocation failed, STATUS_INVALID_PARAMETER if the file record has no $STANDARD_INFORMATION, or whatever status reading or writing the file record returned.
Remarks
A timestamp of zero means "leave as is" and -1 means "stop maintaining automatically"; both are treated as no change, as the driver doesn't yet update timestamps on I/O. FileAttributes of zero means no change.

NTFS keeps a second copy of these in $FILE_NAME and a third in the parent directory's index entry; all three are updated here.

static NTSTATUS NtfsSetBasicInformation (PDEVICE_EXTENSION DeviceExt, PNTFS_FCB Fcb, BOOLEAN CaseSensitive, PFILE_BASIC_INFORMATION BasicInfo)
 
NtfsSetDispositionInformation

@implemented

Marks a file for deletion, or clears an existing mark.

Parameters
DeviceExtPoints to the target disk's DEVICE_EXTENSION.
FcbPointer to the NTFS_FCB of the file. Fcb->MainResource should have been acquired.
FileObjectPointer to the FILE_OBJECT the request arrived on.
CaseSensitiveBoolean indicating if the function should operate in case-sensitive mode. This will be TRUE if an application created the file with the FILE_FLAG_POSIX_SEMANTICS flag.
DispositionInfoPointer to the FILE_DISPOSITION_INFORMATION supplied by the caller.
Returns
STATUS_SUCCESS on success. STATUS_CANNOT_DELETE if the file is read-only or is the volume root. STATUS_DIRECTORY_NOT_EMPTY if the file is a directory that still holds entries.
Remarks
Only records the intent; the file is deleted at cleanup, once its last handle is closed.
static NTSTATUS NtfsSetDispositionInformation (PDEVICE_EXTENSION DeviceExt, PNTFS_FCB Fcb, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PFILE_DISPOSITION_INFORMATION DispositionInfo)
 
NtfsIsValidFileName

Checks a single path component against what NTFS stores and Win32 can open.

static BOOLEAN NtfsIsValidFileName (_In_ PCUNICODE_STRING Name)
 
NtfsSetFileNameAttribute

Rebuilds FileRecord so its only $FILE_NAME is one holding Value. Attributes stay sorted by type, which NTFS requires.

Returns
STATUS_SUCCESS, or STATUS_INSUFFICIENT_RESOURCES if the new name doesn't fit in the record.
static NTSTATUS NtfsSetFileNameAttribute (_In_ PDEVICE_EXTENSION DeviceExt, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ PFILENAME_ATTRIBUTE Value, _In_ ULONG ValueLength)
 
NtfsRenameFcbs

Moves the FCB table over to NewPath: the renamed FCB, its other streams, and for a directory every FCB cached beneath it.

static VOID NtfsRenameFcbs (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ PCWSTR NewPath)
 
NtfsCheckRenamePaths

Fails if moving Fcb to NewPath would push any cached path past MAX_PATH.

static NTSTATUS NtfsCheckRenamePaths (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ PCWSTR NewPath)
 
NtfsRelinkFileNames

Adds back to the parent index the first Count $FILE_NAMEs in FileRecord. Used to undo a rename that failed after those names were taken out.

static VOID NtfsRelinkFileNames (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG FileReference, _In_ ULONG Count, _In_ BOOLEAN CaseSensitive)
 
NtfsBuildRenamePath

Works out the new name and full path of a rename, and checks both.

Parameters
TargetDirMftReceives the MFT index of the target directory, or 0 for a rename within the file's current directory.
static NTSTATUS NtfsBuildRenamePath (_In_ PNTFS_FCB Fcb, _In_opt_ PFILE_OBJECT TargetFileObject, _In_ PFILE_RENAME_INFORMATION RenameInfo, _In_ ULONG BufferLength, _Out_ PUNICODE_STRING NewName, _Out_writes_z_(MAX_PATH) PWSTR NewPath, _Out_ PULONGLONG TargetDirMft)
 
NtfsFindLongFileName

Finds the one non-DOS $FILE_NAME in FileRecord and the directory holding it. More than one long name, or names in more than one directory, means hard links, which rename doesn't handle.

static NTSTATUS NtfsFindLongFileName (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _Outptr_ PFILENAME_ATTRIBUTE *LongName, _Out_ PULONGLONG ParentMft)
 
NtfsClearRenameTarget

Makes sure NewName is free in the target directory, deleting the file already there when that's allowed.

Parameters
ScratchFile record sized buffer the function may overwrite.
static NTSTATUS NtfsClearRenameTarget (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ ULONGLONG TargetDirMft, _In_ PUNICODE_STRING NewName, _In_z_ PCWSTR NewPath, _In_ BOOLEAN ReplaceIfExists, _In_ BOOLEAN CaseSensitive, _Out_ PFILE_RECORD_HEADER Scratch)
 
NtfsBuildRenamedFileName

Allocates the $FILE_NAME value for the new name. It keeps the duplicated information of OldName. Free it with ExFreePoolWithTag.

Parameters
ScratchFile record sized buffer the function may overwrite.
static NTSTATUS NtfsBuildRenamedFileName (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILENAME_ATTRIBUTE OldName, _In_ ULONGLONG TargetDirMft, _In_ PUNICODE_STRING NewName, _In_ BOOLEAN CaseSensitive, _Out_ PFILE_RECORD_HEADER Scratch, _Outptr_ PFILENAME_ATTRIBUTE *NewValue, _Out_ PULONG NewValueLength)
 
NtfsUnlinkFileNames

Takes every $FILE_NAME in FileRecord out of the ParentMft index. Removed receives how many were taken out, even on failure.

static NTSTATUS NtfsUnlinkFileNames (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG ParentMft, _In_ BOOLEAN CaseSensitive, _Out_ PULONG Removed)
 
NtfsCommitRename

Swaps the file's names on disk for NewValue. On failure everything is put back as it was in Original.

Parameters
FileRecordThe file's record, rewritten in place.
OriginalUnchanged copy of FileRecord.
static NTSTATUS NtfsCommitRename (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ PFILE_RECORD_HEADER Original, _In_ ULONGLONG OldParentMft, _In_ ULONGLONG TargetDirMft, _In_ PFILENAME_ATTRIBUTE NewValue, _In_ ULONG NewValueLength, _In_ BOOLEAN CaseSensitive)
 
NtfsSetRenameInformation

@implemented

Renames or moves a file or directory within the volume.

Parameters
DeviceExtVolume holding the file.
FcbFCB of the file being renamed. The caller holds DirResource and the FCB's MainResource exclusively.
TargetFileObjectDirectory the I/O manager opened with SL_OPEN_TARGET_DIRECTORY, whose FileName holds the new name. NULL for a rename within the same directory, in which case the name comes from RenameInfo.
ReplaceIfExistsWhether an existing file with the new name may be deleted.
CaseSensitiveTRUE for POSIX semantics.
RenameInfoThe caller's FILE_RENAME_INFORMATION.
BufferLengthSize of RenameInfo in bytes.
Returns
STATUS_SUCCESS on success. STATUS_OBJECT_NAME_COLLISION if the name is taken and may not be replaced, STATUS_ACCESS_DENIED if the existing file can't be replaced, STATUS_OBJECT_NAME_INVALID for a bad name, or the error that stopped the update.
static NTSTATUS NtfsSetRenameInformation (_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_opt_ PFILE_OBJECT TargetFileObject, _In_ BOOLEAN ReplaceIfExists, _In_ BOOLEAN CaseSensitive, _In_ PFILE_RENAME_INFORMATION RenameInfo, _In_ ULONG BufferLength)
 
NTSTATUS NtfsSetInformation (PNTFS_IRP_CONTEXT IrpContext)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 32 of file finfo.c.

◆ NTFS_MAX_NAME_LENGTH

#define NTFS_MAX_NAME_LENGTH   255

Definition at line 36 of file finfo.c.

Function Documentation

◆ GetInfoClassName()

const PCSTR GetInfoClassName ( FILE_INFORMATION_CLASS  infoClass)

Definition at line 346 of file finfo.c.

347{
348 const PCSTR fileInfoClassNames[] = { "???????",
349 "FileDirectoryInformation",
350 "FileFullDirectoryInformation",
351 "FileBothDirectoryInformation",
352 "FileBasicInformation",
353 "FileStandardInformation",
354 "FileInternalInformation",
355 "FileEaInformation",
356 "FileAccessInformation",
357 "FileNameInformation",
358 "FileRenameInformation",
359 "FileLinkInformation",
360 "FileNamesInformation",
361 "FileDispositionInformation",
362 "FilePositionInformation",
363 "FileFullEaInformation",
364 "FileModeInformation",
365 "FileAlignmentInformation",
366 "FileAllInformation",
367 "FileAllocationInformation",
368 "FileEndOfFileInformation",
369 "FileAlternateNameInformation",
370 "FileStreamInformation",
371 "FilePipeInformation",
372 "FilePipeLocalInformation",
373 "FilePipeRemoteInformation",
374 "FileMailslotQueryInformation",
375 "FileMailslotSetInformation",
376 "FileCompressionInformation",
377 "FileObjectIdInformation",
378 "FileCompletionInformation",
379 "FileMoveClusterInformation",
380 "FileQuotaInformation",
381 "FileReparsePointInformation",
382 "FileNetworkOpenInformation",
383 "FileAttributeTagInformation",
384 "FileTrackingInformation",
385 "FileIdBothDirectoryInformation",
386 "FileIdFullDirectoryInformation",
387 "FileValidDataLengthInformation",
388 "FileShortNameInformation",
389 "FileIoCompletionNotificationInformation",
390 "FileIoStatusBlockRangeInformation",
391 "FileIoPriorityHintInformation",
392 "FileSfioReserveInformation",
393 "FileSfioVolumeInformation",
394 "FileHardLinkInformation",
395 "FileProcessIdsUsingFileInformation",
396 "FileNormalizedNameInformation",
397 "FileNetworkPhysicalNameInformation",
398 "FileIdGlobalTxDirectoryInformation",
399 "FileIsRemoteDeviceInformation",
400 "FileAttributeCacheInformation",
401 "FileNumaNodeInformation",
402 "FileStandardLinkInformation",
403 "FileRemoteProtocolInformation",
404 "FileReplaceCompletionInformation",
405 "FileMaximumInformation",
406 "FileDirectoryInformation",
407 "FileFullDirectoryInformation",
408 "FileBothDirectoryInformation",
409 "FileBasicInformation",
410 "FileStandardInformation",
411 "FileInternalInformation",
412 "FileEaInformation",
413 "FileAccessInformation",
414 "FileNameInformation",
415 "FileRenameInformation",
416 "FileLinkInformation",
417 "FileNamesInformation",
418 "FileDispositionInformation",
419 "FilePositionInformation",
420 "FileFullEaInformation",
421 "FileModeInformation",
422 "FileAlignmentInformation",
423 "FileAllInformation",
424 "FileAllocationInformation",
425 "FileEndOfFileInformation",
426 "FileAlternateNameInformation",
427 "FileStreamInformation",
428 "FilePipeInformation",
429 "FilePipeLocalInformation",
430 "FilePipeRemoteInformation",
431 "FileMailslotQueryInformation",
432 "FileMailslotSetInformation",
433 "FileCompressionInformation",
434 "FileObjectIdInformation",
435 "FileCompletionInformation",
436 "FileMoveClusterInformation",
437 "FileQuotaInformation",
438 "FileReparsePointInformation",
439 "FileNetworkOpenInformation",
440 "FileAttributeTagInformation",
441 "FileTrackingInformation",
442 "FileIdBothDirectoryInformation",
443 "FileIdFullDirectoryInformation",
444 "FileValidDataLengthInformation",
445 "FileShortNameInformation",
446 "FileIoCompletionNotificationInformation",
447 "FileIoStatusBlockRangeInformation",
448 "FileIoPriorityHintInformation",
449 "FileSfioReserveInformation",
450 "FileSfioVolumeInformation",
451 "FileHardLinkInformation",
452 "FileProcessIdsUsingFileInformation",
453 "FileNormalizedNameInformation",
454 "FileNetworkPhysicalNameInformation",
455 "FileIdGlobalTxDirectoryInformation",
456 "FileIsRemoteDeviceInformation",
457 "FileAttributeCacheInformation",
458 "FileNumaNodeInformation",
459 "FileStandardLinkInformation",
460 "FileRemoteProtocolInformation",
461 "FileReplaceCompletionInformation",
462 "FileMaximumInformation" };
463 return fileInfoClassNames[infoClass];
464}
const char * PCSTR
Definition: typedefs.h:52

Referenced by NtfsQueryInformation(), and NtfsSetInformation().

◆ NtfsBuildRenamedFileName()

static NTSTATUS NtfsBuildRenamedFileName ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PFILENAME_ATTRIBUTE  OldName,
_In_ ULONGLONG  TargetDirMft,
_In_ PUNICODE_STRING  NewName,
_In_ BOOLEAN  CaseSensitive,
_Out_ PFILE_RECORD_HEADER  Scratch,
_Outptr_ PFILENAME_ATTRIBUTE *  NewValue,
_Out_ PULONG  NewValueLength 
)
static

Definition at line 1466 of file finfo.c.

1475{
1477 ULONG Length;
1479
1480 *NewValue = NULL;
1481 *NewValueLength = 0;
1482
1483 /* The parent reference needs the directory's sequence number */
1484 Status = ReadFileRecord(DeviceExt, TargetDirMft, Scratch);
1485 if (!NT_SUCCESS(Status))
1486 return Status;
1487
1490 if (Value == NULL)
1492
1494 Value->DirectoryFileReferenceNumber = TargetDirMft | ((ULONGLONG)Scratch->SequenceNumber << 48);
1495 Value->NameLength = (UCHAR)(NewName->Length / sizeof(WCHAR));
1497
1498 if (CaseSensitive)
1499 Value->NameType = NTFS_FILE_NAME_POSIX;
1502 else
1503 Value->NameType = NTFS_FILE_NAME_WIN32;
1504
1505 *NewValue = Value;
1506 *NewValueLength = Length;
1507 return STATUS_SUCCESS;
1508}
LONG NTSTATUS
Definition: precomp.h:26
#define NTFS_FILE_NAME_WIN32
Definition: ntfs.h:64
#define NTFS_FILE_NAME_POSIX
Definition: ntfs.h:63
#define NTFS_FILE_NAME_WIN32_AND_DOS
Definition: ntfs.h:66
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:24
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1936
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
short WCHAR
Definition: pedump.c:58
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
#define STATUS_SUCCESS
Definition: shellext.h:65
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203

Referenced by NtfsSetRenameInformation().

◆ NtfsBuildRenamePath()

static NTSTATUS NtfsBuildRenamePath ( _In_ PNTFS_FCB  Fcb,
_In_opt_ PFILE_OBJECT  TargetFileObject,
_In_ PFILE_RENAME_INFORMATION  RenameInfo,
_In_ ULONG  BufferLength,
_Out_ PUNICODE_STRING  NewName,
_Out_writes_z_(MAX_PATH) PWSTR  NewPath,
_Out_ PULONGLONG  TargetDirMft 
)
static

Definition at line 1272 of file finfo.c.

1280{
1281 PCWSTR TargetDirPath;
1282 SIZE_T TargetDirLength;
1283 SIZE_T NameLength;
1284
1285 if (TargetFileObject != NULL)
1286 {
1287 PNTFS_FCB TargetFcb = TargetFileObject->FsContext;
1288
1289 *NewName = TargetFileObject->FileName;
1290 *TargetDirMft = TargetFcb->MFTIndex;
1291 TargetDirPath = TargetFcb->PathName;
1292 TargetDirLength = NtfsFCBIsRoot(TargetFcb) ? 0 : wcslen(TargetFcb->PathName);
1293 }
1294 else
1295 {
1297 RenameInfo->FileNameLength > BufferLength - FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) ||
1298 RenameInfo->FileNameLength > MAXUSHORT)
1299 {
1301 }
1302
1303 NewName->Buffer = RenameInfo->FileName;
1304 NewName->Length = (USHORT)RenameInfo->FileNameLength;
1306
1307 *TargetDirMft = 0;
1308 TargetDirPath = Fcb->PathName;
1309 TargetDirLength = Fcb->ObjectName - Fcb->PathName;
1310 }
1311
1314
1315 NameLength = NewName->Length / sizeof(WCHAR);
1316 if (TargetDirLength + 1 + NameLength >= MAX_PATH)
1317 return STATUS_NAME_TOO_LONG;
1318
1319 /* A directory can't become its own descendant */
1321 {
1322 SIZE_T OldLength = wcslen(Fcb->PathName);
1323
1324 if (TargetDirLength >= OldLength &&
1325 _wcsnicmp(TargetDirPath, Fcb->PathName, OldLength) == 0 &&
1326 (TargetDirLength == OldLength || TargetDirPath[OldLength] == L'\\'))
1327 {
1329 }
1330 }
1331
1332 RtlCopyMemory(NewPath, TargetDirPath, TargetDirLength * sizeof(WCHAR));
1333 NewPath[TargetDirLength] = L'\\';
1334 RtlCopyMemory(NewPath + TargetDirLength + 1, NewName->Buffer, NewName->Length);
1335 NewPath[TargetDirLength + 1 + NameLength] = UNICODE_NULL;
1336
1337 return STATUS_SUCCESS;
1338}
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define MAX_PATH
Definition: compat.h:34
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
#define L(x)
Definition: resources.c:13
#define UNICODE_NULL
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:144
BOOLEAN NtfsFCBIsRoot(PNTFS_FCB Fcb)
Definition: fcb.c:185
static BOOLEAN NtfsIsValidFileName(_In_ PCUNICODE_STRING Name)
Definition: finfo.c:1007
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
unsigned short USHORT
Definition: pedump.c:61
Definition: cdstruc.h:902
ULONGLONG MFTIndex
Definition: ntfs.h:622
WCHAR * ObjectName
Definition: ntfs.h:603
WCHAR PathName[MAX_PATH]
Definition: ntfs.h:604
USHORT MaximumLength
Definition: env_spec_w32.h:370
const uint16_t * PCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAXUSHORT
Definition: typedefs.h:83
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777

Referenced by NtfsSetRenameInformation().

◆ NtfsCheckRenamePaths()

static NTSTATUS NtfsCheckRenamePaths ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PNTFS_FCB  Fcb,
_In_ PCWSTR  NewPath 
)
static

Definition at line 1186 of file finfo.c.

1190{
1191 SIZE_T OldLength = wcslen(Fcb->PathName);
1192 SIZE_T NewLength = wcslen(NewPath);
1195 KIRQL OldIrql;
1196
1197 KeAcquireSpinLock(&DeviceExt->FcbListLock, &OldIrql);
1198
1199 for (Entry = DeviceExt->FcbListHead.Flink; Entry != &DeviceExt->FcbListHead; Entry = Entry->Flink)
1200 {
1202
1203 if (_wcsnicmp(Other->PathName, Fcb->PathName, OldLength) == 0 &&
1204 (Other->PathName[OldLength] == UNICODE_NULL || Other->PathName[OldLength] == L'\\') &&
1205 wcslen(Other->PathName) - OldLength + NewLength >= MAX_PATH)
1206 {
1208 break;
1209 }
1210 }
1211
1212 KeReleaseSpinLock(&DeviceExt->FcbListLock, OldIrql);
1213 return Status;
1214}
static USHORT USHORT * NewLength
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
@ Other
Definition: video.h:273
Entry
Definition: section.c:5216
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by NtfsSetRenameInformation().

◆ NtfsClearRenameTarget()

static NTSTATUS NtfsClearRenameTarget ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PNTFS_FCB  Fcb,
_In_ ULONGLONG  TargetDirMft,
_In_ PUNICODE_STRING  NewName,
_In_z_ PCWSTR  NewPath,
_In_ BOOLEAN  ReplaceIfExists,
_In_ BOOLEAN  CaseSensitive,
_Out_ PFILE_RECORD_HEADER  Scratch 
)
static

Definition at line 1408 of file finfo.c.

1417{
1418 PNTFS_FCB ExistingFcb;
1419 ULONGLONG ExistingMft;
1420 ULONG FirstEntry = 0;
1422
1423 Status = NtfsFindMftRecord(DeviceExt, TargetDirMft, NewName, &FirstEntry, FALSE, CaseSensitive, &ExistingMft);
1425 return STATUS_SUCCESS;
1426
1427 if (!NT_SUCCESS(Status))
1428 return Status;
1429
1430 /* A case-only rename finds the file itself */
1431 if (ExistingMft == Fcb->MFTIndex)
1432 return STATUS_SUCCESS;
1433
1434 if (!ReplaceIfExists)
1436
1437 Status = ReadFileRecord(DeviceExt, ExistingMft, Scratch);
1438 if (!NT_SUCCESS(Status))
1439 return Status;
1440
1441 if (Scratch->Flags & FRH_DIRECTORY)
1442 return STATUS_ACCESS_DENIED;
1443
1444 /* A cached FCB means it's open or still mapped */
1445 ExistingFcb = NtfsGrabFCBFromTable(DeviceExt, NewPath);
1446 if (ExistingFcb != NULL)
1447 {
1448 NtfsReleaseFCB(DeviceExt, ExistingFcb);
1449 return STATUS_ACCESS_DENIED;
1450 }
1451
1452 return NtfsDeleteFileRecord(DeviceExt, ExistingMft, CaseSensitive);
1453}
static BOOLEAN NtfsFindMftRecord(_In_ PNTFS_VOLUME_INFO Volume, _In_ ULONGLONG MFTIndex, _In_ PCSTR FileName, _Out_ PULONGLONG OutMFTIndex, _Out_ PULONG FileAttributes)
Definition: ntfs.c:675
#define FALSE
Definition: types.h:117
#define FRH_DIRECTORY
Definition: ntfs.h:299
NTSTATUS NtfsDeleteFileRecord(PDEVICE_EXTENSION DeviceExt, ULONGLONG MftIndex, BOOLEAN CaseSensitive)
Definition: mft.c:3470
PNTFS_FCB NtfsGrabFCBFromTable(PNTFS_VCB Vcb, PCWSTR FileName)
Definition: fcb.c:291
VOID NtfsReleaseFCB(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:209
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by NtfsSetRenameInformation().

◆ NtfsCommitRename()

static NTSTATUS NtfsCommitRename ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PNTFS_FCB  Fcb,
_Inout_ PFILE_RECORD_HEADER  FileRecord,
_In_ PFILE_RECORD_HEADER  Original,
_In_ ULONGLONG  OldParentMft,
_In_ ULONGLONG  TargetDirMft,
_In_ PFILENAME_ATTRIBUTE  NewValue,
_In_ ULONG  NewValueLength,
_In_ BOOLEAN  CaseSensitive 
)
static

Definition at line 1569 of file finfo.c.

1579{
1580 ULONGLONG FileReference = Fcb->MFTIndex | ((ULONGLONG)FileRecord->SequenceNumber << 48);
1581 BOOLEAN RecordChanged = FALSE;
1582 ULONG Removed;
1584
1585 /* Take the old names out of the index first, so a case-only rename in the
1586 * same directory doesn't collide with itself */
1587 Status = NtfsUnlinkFileNames(DeviceExt, Original, OldParentMft, CaseSensitive, &Removed);
1588
1589 if (NT_SUCCESS(Status))
1590 Status = NtfsSetFileNameAttribute(DeviceExt, FileRecord, NewValue, NewValueLength);
1591
1592 if (NT_SUCCESS(Status))
1593 {
1594 RecordChanged = TRUE;
1595 Status = UpdateFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
1596 }
1597
1598 if (NT_SUCCESS(Status))
1599 Status = NtfsAddFilenameToDirectory(DeviceExt, TargetDirMft, FileReference, NewValue, CaseSensitive);
1600
1601 if (!NT_SUCCESS(Status))
1602 {
1603 /* Put the old record back, then the names that were taken out */
1604 if (RecordChanged)
1605 UpdateFileRecord(DeviceExt, Fcb->MFTIndex, Original);
1606
1607 NtfsRelinkFileNames(DeviceExt, Original, FileReference, Removed, CaseSensitive);
1608 }
1609
1610 return Status;
1611}
unsigned char BOOLEAN
Definition: actypes.h:127
#define TRUE
Definition: types.h:120
@ Removed
Definition: fbtusb.h:86
NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MftIndex, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:2391
NTSTATUS NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
Definition: mft.c:3049
static VOID NtfsRelinkFileNames(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG FileReference, _In_ ULONG Count, _In_ BOOLEAN CaseSensitive)
Definition: finfo.c:1224
static NTSTATUS NtfsUnlinkFileNames(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG ParentMft, _In_ BOOLEAN CaseSensitive, _Out_ PULONG Removed)
Definition: finfo.c:1518
static NTSTATUS NtfsSetFileNameAttribute(_In_ PDEVICE_EXTENSION DeviceExt, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ PFILENAME_ATTRIBUTE Value, _In_ ULONG ValueLength)
Definition: finfo.c:1048

Referenced by NtfsSetRenameInformation().

◆ NtfsFindLongFileName()

static NTSTATUS NtfsFindLongFileName ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PFILE_RECORD_HEADER  FileRecord,
_Outptr_ PFILENAME_ATTRIBUTE *  LongName,
_Out_ PULONGLONG  ParentMft 
)
static

Definition at line 1349 of file finfo.c.

1354{
1355 PNTFS_ATTR_RECORD Attribute;
1356 ULONG Offset = FileRecord->AttributeOffset;
1357 BOOLEAN SeenName = FALSE;
1358
1359 *LongName = NULL;
1360 *ParentMft = 0;
1361
1362 while (Offset + sizeof(ULONG) <= DeviceExt->NtfsInfo.BytesPerFileRecord)
1363 {
1364 Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + Offset);
1365 if (Attribute->Type == AttributeEnd || Attribute->Length == 0)
1366 break;
1367
1368 if (Attribute->Type == AttributeFileName && !Attribute->IsNonResident)
1369 {
1370 PFILENAME_ATTRIBUTE Name = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1371 ULONGLONG Parent = Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK;
1372
1373 if (SeenName && Parent != *ParentMft)
1375
1376 SeenName = TRUE;
1377 *ParentMft = Parent;
1378
1379 if (Name->NameType != NTFS_FILE_NAME_DOS)
1380 {
1381 if (*LongName != NULL)
1383
1384 *LongName = Name;
1385 }
1386 }
1387
1388 Offset += Attribute->Length;
1389 }
1390
1391 if (*LongName == NULL)
1393
1394 return STATUS_SUCCESS;
1395}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define NTFS_FILE_NAME_DOS
Definition: ntfs.h:65
#define NTFS_MFT_MASK
Definition: ntfs.h:76
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
@ AttributeEnd
Definition: ntfs.h:204
@ AttributeFileName
Definition: ntfs.h:190
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING LongName
Definition: fsrtlfuncs.h:338
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct NTFS_ATTR_RECORD::@170::@172 Resident
ULONG Length
Definition: ntfs.h:135
UCHAR IsNonResident
Definition: ntfs.h:136
ULONG Type
Definition: ntfs.h:134
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168

Referenced by NtfsSetRenameInformation().

◆ NtfsGetAttributeTagInformation()

static NTSTATUS NtfsGetAttributeTagInformation ( PNTFS_FCB  Fcb,
PFILE_ATTRIBUTE_TAG_INFORMATION  AttributeTagInfo,
PULONG  BufferLength 
)
static

Definition at line 129 of file finfo.c.

132{
134
135 DPRINT("NtfsGetAttributeTagInformation(%p, %p, %p)\n", Fcb, AttributeTagInfo, BufferLength);
136
139
140 RtlZeroMemory(AttributeTagInfo, sizeof(FILE_ATTRIBUTE_TAG_INFORMATION));
141
142 NtfsFileFlagsToAttributes(FileName->FileAttributes, &AttributeTagInfo->FileAttributes);
143
144 /* FIXME: Read the tag from $REPARSE_POINT for a reparse point */
145 AttributeTagInfo->ReparseTag = 0;
146
148
149 return STATUS_SUCCESS;
150}
VOID NtfsFileFlagsToAttributes(ULONG NtfsAttributes, PULONG FileAttributes)
Definition: misc.c:105
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
FILENAME_ATTRIBUTE Entry
Definition: ntfs.h:625
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _FILE_ATTRIBUTE_TAG_INFORMATION FILE_ATTRIBUTE_TAG_INFORMATION

Referenced by NtfsQueryInformation().

◆ NtfsGetBasicInformation()

static NTSTATUS NtfsGetBasicInformation ( PFILE_OBJECT  FileObject,
PNTFS_FCB  Fcb,
PDEVICE_OBJECT  DeviceObject,
PFILE_BASIC_INFORMATION  BasicInfo,
PULONG  BufferLength 
)
static

Definition at line 100 of file finfo.c.

105{
107
108 DPRINT("NtfsGetBasicInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, BasicInfo, BufferLength);
109
112
113 RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
114
115 BasicInfo->CreationTime.QuadPart = FileName->CreationTime;
116 BasicInfo->LastAccessTime.QuadPart = FileName->LastAccessTime;
117 BasicInfo->LastWriteTime.QuadPart = FileName->LastWriteTime;
118 BasicInfo->ChangeTime.QuadPart = FileName->ChangeTime;
119
120 NtfsFileFlagsToAttributes(FileName->FileAttributes, &BasicInfo->FileAttributes);
121
123
124 return STATUS_SUCCESS;
125}
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:944
LARGE_INTEGER CreationTime
Definition: nt_native.h:942
LARGE_INTEGER ChangeTime
Definition: nt_native.h:945
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:943
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by NtfsQueryInformation().

◆ NtfsGetEaInformation()

static NTSTATUS NtfsGetEaInformation ( PNTFS_FCB  Fcb,
PFILE_EA_INFORMATION  EaInfo,
PULONG  BufferLength 
)
static

Definition at line 155 of file finfo.c.

158{
160
161 DPRINT("NtfsGetEaInformation(%p, %p, %p)\n", Fcb, EaInfo, BufferLength);
162
163 if (*BufferLength < sizeof(FILE_EA_INFORMATION))
165
166 /* We do not support extended attributes yet, so there are none */
167 EaInfo->EaSize = 0;
168
170
171 return STATUS_SUCCESS;
172}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION

Referenced by NtfsQueryInformation().

◆ NtfsGetInternalInformation()

static NTSTATUS NtfsGetInternalInformation ( PNTFS_FCB  Fcb,
PFILE_INTERNAL_INFORMATION  InternalInfo,
PULONG  BufferLength 
)
static

Definition at line 227 of file finfo.c.

230{
231 DPRINT1("NtfsGetInternalInformation(%p, %p, %p)\n", Fcb, InternalInfo, BufferLength);
232
233 ASSERT(InternalInfo);
234 ASSERT(Fcb);
235
238
239 InternalInfo->IndexNumber.QuadPart = Fcb->MFTIndex;
240
242
243 return STATUS_SUCCESS;
244}
#define DPRINT1
Definition: precomp.h:8
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
#define ASSERT(a)
Definition: mode.c:44

Referenced by NtfsQueryInformation().

◆ NtfsGetNameInformation()

static NTSTATUS NtfsGetNameInformation ( PFILE_OBJECT  FileObject,
PNTFS_FCB  Fcb,
PDEVICE_OBJECT  DeviceObject,
PFILE_NAME_INFORMATION  NameInfo,
PULONG  BufferLength 
)
static

Definition at line 180 of file finfo.c.

185{
187
190
191 DPRINT("NtfsGetNameInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, NameInfo, BufferLength);
192
193 ASSERT(NameInfo != NULL);
194 ASSERT(Fcb != NULL);
195
196 /* If buffer can't hold at least the file name length, bail out */
199
200 /* Save file name length, and as much file len, as buffer length allows */
201 NameInfo->FileNameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
202
203 /* Calculate amount of bytes to copy not to overflow the buffer */
204 BytesToCopy = min(NameInfo->FileNameLength,
206
207 /* Fill in the bytes */
209
210 /* Check if we could write more but are not able to */
211 if (*BufferLength < NameInfo->FileNameLength + (ULONG)FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
212 {
213 /* Return number of bytes written */
216 }
217
218 /* We filled up as many bytes, as needed */
220
221 return STATUS_SUCCESS;
222}
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
Definition: fltkernel.h:1129
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66

Referenced by NtfsQueryInformation().

◆ NtfsGetNetworkOpenInformation()

static NTSTATUS NtfsGetNetworkOpenInformation ( PNTFS_FCB  Fcb,
PDEVICE_EXTENSION  DeviceExt,
PFILE_NETWORK_OPEN_INFORMATION  NetworkInfo,
PULONG  BufferLength 
)
static

Definition at line 248 of file finfo.c.

252{
254
255 DPRINT("NtfsGetNetworkOpenInformation(%p, %p, %p, %p)\n", Fcb, DeviceExt, NetworkInfo, BufferLength);
256
259
260 NetworkInfo->CreationTime.QuadPart = FileName->CreationTime;
261 NetworkInfo->LastAccessTime.QuadPart = FileName->LastAccessTime;
262 NetworkInfo->LastWriteTime.QuadPart = FileName->LastWriteTime;
263 NetworkInfo->ChangeTime.QuadPart = FileName->ChangeTime;
264
265 NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
266 NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
267
268 NtfsFileFlagsToAttributes(FileName->FileAttributes, &NetworkInfo->FileAttributes);
269
271 return STATUS_SUCCESS;
272}
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:593
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755

Referenced by NtfsQueryInformation().

◆ NtfsGetPositionInformation()

static NTSTATUS NtfsGetPositionInformation ( PFILE_OBJECT  FileObject,
PFILE_POSITION_INFORMATION  PositionInfo,
PULONG  BufferLength 
)
static

Definition at line 78 of file finfo.c.

81{
82 DPRINT1("NtfsGetPositionInformation(%p, %p, %p)\n", FileObject, PositionInfo, BufferLength);
83
86
87 PositionInfo->CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
88
89 DPRINT("Getting position %I64x\n",
90 PositionInfo->CurrentByteOffset.QuadPart);
91
93
94 return STATUS_SUCCESS;
95}
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:958

Referenced by NtfsQueryInformation().

◆ NtfsGetStandardInformation()

static NTSTATUS NtfsGetStandardInformation ( PNTFS_FCB  Fcb,
PDEVICE_OBJECT  DeviceObject,
PFILE_STANDARD_INFORMATION  StandardInfo,
PULONG  BufferLength 
)
static

Definition at line 45 of file finfo.c.

49{
51
52 DPRINT("NtfsGetStandardInformation(%p, %p, %p, %p)\n", Fcb, DeviceObject, StandardInfo, BufferLength);
53
56
57 /* PRECONDITION */
58 ASSERT(StandardInfo != NULL);
59 ASSERT(Fcb != NULL);
60
61 RtlZeroMemory(StandardInfo,
63
64 StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
65 StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
66 StandardInfo->NumberOfLinks = Fcb->LinkCount;
68 StandardInfo->Directory = NtfsFCBIsDirectory(Fcb);
69
71
72 return STATUS_SUCCESS;
73}
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
ULONG Flags
Definition: ntfs.h:618
USHORT LinkCount
Definition: ntfs.h:623
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54

Referenced by NtfsQueryInformation().

◆ NtfsGetStreamInformation()

static NTSTATUS NtfsGetStreamInformation ( PNTFS_FCB  Fcb,
PDEVICE_EXTENSION  DeviceExt,
PFILE_STREAM_INFORMATION  StreamInfo,
PULONG  BufferLength 
)
static

Definition at line 276 of file finfo.c.

280{
281 ULONG CurrentSize;
283 PNTFS_ATTR_RECORD Attribute;
284 NTSTATUS Status, BrowseStatus;
285 PFILE_RECORD_HEADER FileRecord;
286 PFILE_STREAM_INFORMATION CurrentInfo = StreamInfo, Previous = NULL;
287
290
291 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
292 if (FileRecord == NULL)
293 {
294 DPRINT1("Not enough memory!\n");
296 }
297
298 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
299 if (!NT_SUCCESS(Status))
300 {
301 DPRINT1("Can't find record!\n");
302 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
303 return Status;
304 }
305
306 BrowseStatus = FindFirstAttribute(&Context, DeviceExt, FileRecord, FALSE, &Attribute);
307 while (NT_SUCCESS(BrowseStatus))
308 {
309 if (Attribute->Type == AttributeData)
310 {
311 CurrentSize = FIELD_OFFSET(FILE_STREAM_INFORMATION, StreamName) + Attribute->NameLength * sizeof(WCHAR) + wcslen(L"::$DATA") * sizeof(WCHAR);
312
313 if (CurrentSize > *BufferLength)
314 {
316 break;
317 }
318
319 CurrentInfo->NextEntryOffset = 0;
320 CurrentInfo->StreamNameLength = (Attribute->NameLength + wcslen(L"::$DATA")) * sizeof(WCHAR);
321 CurrentInfo->StreamSize.QuadPart = AttributeDataLength(Attribute);
323 CurrentInfo->StreamName[0] = L':';
324 RtlMoveMemory(&CurrentInfo->StreamName[1], (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset), CurrentInfo->StreamNameLength);
325 RtlMoveMemory(&CurrentInfo->StreamName[Attribute->NameLength + 1], L":$DATA", sizeof(L":$DATA") - sizeof(UNICODE_NULL));
326
327 if (Previous != NULL)
328 {
329 Previous->NextEntryOffset = (ULONG_PTR)CurrentInfo - (ULONG_PTR)Previous;
330 }
331 Previous = CurrentInfo;
332 CurrentInfo = (PFILE_STREAM_INFORMATION)((ULONG_PTR)CurrentInfo + CurrentSize);
333 *BufferLength -= CurrentSize;
334 }
335
336 BrowseStatus = FindNextAttribute(&Context, &Attribute);
337 }
338
340 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
341 return Status;
342}
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1413
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1495
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1461
@ AttributeData
Definition: ntfs.h:195
#define ULONG_PTR
Definition: config.h:101
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING StreamName
Definition: fsrtlfuncs.h:741
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
ULONGLONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:249
USHORT NameOffset
Definition: ntfs.h:138
UCHAR NameLength
Definition: ntfs.h:137
LARGE_INTEGER StreamSize
Definition: winternl.h:1700
LARGE_INTEGER StreamAllocationSize
Definition: winternl.h:1701
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
struct _FILE_STREAM_INFORMATION * PFILE_STREAM_INFORMATION

Referenced by NtfsQueryInformation().

◆ NtfsIsValidFileName()

static BOOLEAN NtfsIsValidFileName ( _In_ PCUNICODE_STRING  Name)
static

Definition at line 1007 of file finfo.c.

1009{
1010 USHORT i;
1011
1012 if (Name->Length == 0 ||
1013 Name->Length > NTFS_MAX_NAME_LENGTH * sizeof(WCHAR) ||
1014 (Name->Length % sizeof(WCHAR)) != 0)
1015 {
1016 return FALSE;
1017 }
1018
1019 if ((Name->Length == sizeof(WCHAR) && Name->Buffer[0] == L'.') ||
1020 (Name->Length == 2 * sizeof(WCHAR) && Name->Buffer[0] == L'.' && Name->Buffer[1] == L'.'))
1021 {
1022 return FALSE;
1023 }
1024
1025 for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
1026 {
1027 WCHAR Char = Name->Buffer[i];
1028
1029 if (Char < 0x20 || wcschr(L"\\/:*?\"<>|", Char) != NULL)
1030 return FALSE;
1031 }
1032
1033 return TRUE;
1034}
#define wcschr
Definition: compat.h:17
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NTFS_MAX_NAME_LENGTH
Definition: finfo.c:36

Referenced by NtfsBuildRenamePath().

◆ NtfsQueryInformation()

NTSTATUS NtfsQueryInformation ( PNTFS_IRP_CONTEXT  IrpContext)

Definition at line 470 of file finfo.c.

471{
476 PVOID SystemBuffer;
478 PIRP Irp;
481
482 DPRINT("NtfsQueryInformation(%p)\n", IrpContext);
483
484 Irp = IrpContext->Irp;
485 Stack = IrpContext->Stack;
486 DeviceObject = IrpContext->DeviceObject;
487 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
488 FileObject = IrpContext->FileObject;
489 Fcb = FileObject->FsContext;
490
491 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
492 BufferLength = Stack->Parameters.QueryFile.Length;
493
496 {
497 return NtfsMarkIrpContextForQueue(IrpContext);
498 }
499
500 switch (FileInformationClass)
501 {
505 SystemBuffer,
506 &BufferLength);
507 break;
508
511 SystemBuffer,
512 &BufferLength);
513 break;
514
517 SystemBuffer,
518 &BufferLength);
519 break;
520
523 Fcb,
525 SystemBuffer,
526 &BufferLength);
527 break;
528
531 Fcb,
533 SystemBuffer,
534 &BufferLength);
535 break;
536
539 SystemBuffer,
540 &BufferLength);
541 break;
542
545 DeviceObject->DeviceExtension,
546 SystemBuffer,
547 &BufferLength);
548 break;
549
552 DeviceObject->DeviceExtension,
553 SystemBuffer,
554 &BufferLength);
555 break;
556
559 SystemBuffer,
560 &BufferLength);
561 break;
562
565 DPRINT1("Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
567 break;
568
569 default:
570 DPRINT1("Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
572 }
573
575
576 if (NT_SUCCESS(Status))
577 Irp->IoStatus.Information =
578 Stack->Parameters.QueryFile.Length - BufferLength;
579 else
580 Irp->IoStatus.Information = 0;
581
582 return Status;
583}
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
Definition: ntfs.h:652
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:505
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileAllInformation
Definition: from_kernel.h:79
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileAttributeTagInformation
Definition: from_kernel.h:96
@ FileEaInformation
Definition: from_kernel.h:68
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileNameInformation
Definition: from_kernel.h:70
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileStreamInformation
Definition: from_kernel.h:83
@ FileBasicInformation
Definition: from_kernel.h:65
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
_In_ PIRP Irp
Definition: kse.h:79
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:100
static NTSTATUS NtfsGetAttributeTagInformation(PNTFS_FCB Fcb, PFILE_ATTRIBUTE_TAG_INFORMATION AttributeTagInfo, PULONG BufferLength)
Definition: finfo.c:129
static NTSTATUS NtfsGetNameInformation(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
Definition: finfo.c:180
static NTSTATUS NtfsGetStreamInformation(PNTFS_FCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_STREAM_INFORMATION StreamInfo, PULONG BufferLength)
Definition: finfo.c:276
static NTSTATUS NtfsGetPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo, PULONG BufferLength)
Definition: finfo.c:78
const PCSTR GetInfoClassName(FILE_INFORMATION_CLASS infoClass)
Definition: finfo.c:346
static NTSTATUS NtfsGetStandardInformation(PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
Definition: finfo.c:45
static NTSTATUS NtfsGetNetworkOpenInformation(PNTFS_FCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_NETWORK_OPEN_INFORMATION NetworkInfo, PULONG BufferLength)
Definition: finfo.c:248
static NTSTATUS NtfsGetInternalInformation(PNTFS_FCB Fcb, PFILE_INTERNAL_INFORMATION InternalInfo, PULONG BufferLength)
Definition: finfo.c:227
static NTSTATUS NtfsGetBasicInformation(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
Definition: finfo.c:100
static NTSTATUS NtfsGetEaInformation(PNTFS_FCB Fcb, PFILE_EA_INFORMATION EaInfo, PULONG BufferLength)
Definition: finfo.c:155
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define FileStandardInformation
Definition: propsheet.cpp:61
PFILE_OBJECT FileObject
Definition: ntfs.h:564
ULONG Flags
Definition: ntfs.h:556
PIO_STACK_LOCATION Stack
Definition: ntfs.h:557
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:563
ERESOURCE MainResource
Definition: ntfs.h:607
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by NtfsDispatch().

◆ NtfsRelinkFileNames()

static VOID NtfsRelinkFileNames ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PFILE_RECORD_HEADER  FileRecord,
_In_ ULONGLONG  FileReference,
_In_ ULONG  Count,
_In_ BOOLEAN  CaseSensitive 
)
static

Definition at line 1224 of file finfo.c.

1230{
1231 PNTFS_ATTR_RECORD Attribute;
1232 ULONG Offset = FileRecord->AttributeOffset;
1233
1234 while (Count != 0 && Offset + sizeof(ULONG) <= DeviceExt->NtfsInfo.BytesPerFileRecord)
1235 {
1236 Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + Offset);
1237 if (Attribute->Type == AttributeEnd || Attribute->Length == 0)
1238 break;
1239
1240 if (Attribute->Type == AttributeFileName && !Attribute->IsNonResident)
1241 {
1242 PFILENAME_ATTRIBUTE Name = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1243
1245 Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK,
1246 FileReference,
1247 Name,
1248 CaseSensitive)))
1249 {
1250 DPRINT1("Couldn't restore '%.*S' in directory %I64u\n",
1251 Name->NameLength, Name->Name, Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK);
1252 }
1253
1254 Count--;
1255 }
1256
1257 Offset += Attribute->Length;
1258 }
1259}
int Count
Definition: noreturn.cpp:7

Referenced by NtfsCommitRename().

◆ NtfsRenameFcbs()

static VOID NtfsRenameFcbs ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PNTFS_FCB  Fcb,
_In_ PCWSTR  NewPath 
)
static

Definition at line 1143 of file finfo.c.

1147{
1148 WCHAR OldPath[MAX_PATH];
1149 WCHAR Rebuilt[MAX_PATH];
1150 SIZE_T OldLength;
1152 KIRQL OldIrql;
1153
1154 wcscpy(OldPath, Fcb->PathName);
1155 OldLength = wcslen(OldPath);
1156
1157 KeAcquireSpinLock(&DeviceExt->FcbListLock, &OldIrql);
1158
1159 for (Entry = DeviceExt->FcbListHead.Flink; Entry != &DeviceExt->FcbListHead; Entry = Entry->Flink)
1160 {
1162
1163 if (_wcsnicmp(Other->PathName, OldPath, OldLength) != 0 ||
1164 (Other->PathName[OldLength] != UNICODE_NULL && Other->PathName[OldLength] != L'\\'))
1165 {
1166 continue;
1167 }
1168
1169 /* NtfsCheckRenamePaths() already made sure this fits */
1170 wcscpy(Rebuilt, NewPath);
1171 wcscat(Rebuilt, Other->PathName + OldLength);
1172 wcscpy(Other->PathName, Rebuilt);
1173 Other->ObjectName = wcsrchr(Other->PathName, L'\\');
1174 }
1175
1176 KeReleaseSpinLock(&DeviceExt->FcbListLock, OldIrql);
1177}
#define wcsrchr
Definition: compat.h:16
wcscat
wcscpy

Referenced by NtfsSetRenameInformation().

◆ NtfsSetAllocationInformation()

static NTSTATUS NTAPI NtfsSetAllocationInformation ( _In_ PNTFS_FCB  Fcb,
_In_ PFILE_OBJECT  FileObject,
_In_ PDEVICE_EXTENSION  DeviceExt,
_In_ ULONG  IrpFlags,
_In_ BOOLEAN  CaseSensitive,
_In_ PLARGE_INTEGER  AllocationSize 
)
static

Definition at line 747 of file finfo.c.

754{
756
757 if ((Fcb->Flags & FCB_IS_VOLUME) || NtfsFCBIsDirectory(Fcb) || AllocationSize->QuadPart < 0)
759
760 if (AllocationSize->QuadPart < Fcb->RFCB.FileSize.QuadPart)
761 {
762 Status = NtfsSetEndOfFile(Fcb, FileObject, DeviceExt, IrpFlags, CaseSensitive, AllocationSize);
763 if (!NT_SUCCESS(Status))
764 return Status;
765 }
766
769 CaseSensitive,
770 ROUND_UP(AllocationSize->QuadPart, DeviceExt->NtfsInfo.BytesPerCluster));
771}
_In_ ULONG AllocationSize
Definition: dispmprt.h:712
#define FCB_IS_VOLUME
Definition: ntfs.h:585
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
NTSTATUS NtfsResizeAllocation(_In_ PNTFS_FCB Fcb, _In_ PFILE_OBJECT FileObject, _In_ BOOLEAN CaseSensitive, _In_ ULONGLONG AllocationSize)
Definition: mft.c:924
NTSTATUS NtfsSetEndOfFile(PNTFS_FCB Fcb, PFILE_OBJECT FileObject, PDEVICE_EXTENSION DeviceExt, ULONG IrpFlags, BOOLEAN CaseSensitive, PLARGE_INTEGER NewFileSize)
Definition: finfo.c:625

Referenced by NtfsSetInformation().

◆ NtfsSetBasicInformation()

static NTSTATUS NtfsSetBasicInformation ( PDEVICE_EXTENSION  DeviceExt,
PNTFS_FCB  Fcb,
BOOLEAN  CaseSensitive,
PFILE_BASIC_INFORMATION  BasicInfo 
)
static

Definition at line 830 of file finfo.c.

834{
835 PFILE_RECORD_HEADER FileRecord;
836 PSTANDARD_INFORMATION StdInfo;
838
839 DPRINT("NtfsSetBasicInformation(%p, %p, %p)\n", DeviceExt, Fcb, BasicInfo);
840
841 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
842 if (FileRecord == NULL)
843 {
844 DPRINT1("Not enough memory!\n");
846 }
847
848 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
849 if (!NT_SUCCESS(Status))
850 {
851 DPRINT1("Can't find record for %wS!\n", Fcb->ObjectName);
852 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
853 return Status;
854 }
855
856 StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
857 if (StdInfo == NULL)
858 {
859 DPRINT1("No $STANDARD_INFORMATION for %wS!\n", Fcb->ObjectName);
860 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
862 }
863
864 if (BasicInfo->CreationTime.QuadPart > 0)
865 StdInfo->CreationTime = BasicInfo->CreationTime.QuadPart;
866
867 if (BasicInfo->LastAccessTime.QuadPart > 0)
868 StdInfo->LastAccessTime = BasicInfo->LastAccessTime.QuadPart;
869
870 if (BasicInfo->LastWriteTime.QuadPart > 0)
871 StdInfo->LastWriteTime = BasicInfo->LastWriteTime.QuadPart;
872
873 if (BasicInfo->ChangeTime.QuadPart > 0)
874 StdInfo->ChangeTime = BasicInfo->ChangeTime.QuadPart;
875
876 if (BasicInfo->FileAttributes != 0)
877 {
878 ULONG Attributes = BasicInfo->FileAttributes;
879
880 /* Whether this is a directory isn't the caller's to say */
882
883 /* NORMAL only means anything on its own */
886
887 StdInfo->FileAttribute = Attributes;
888 }
889
890 /* Everything else NTFS keeps a second and third copy of goes out through the one funnel,
891 * which also writes the file record back. */
893 FileRecord,
894 Fcb->MFTIndex,
897 CaseSensitive);
898 if (!NT_SUCCESS(Status))
899 {
900 DPRINT1("Failed to refresh the duplicated information for %wS (Status %lx)\n",
902 }
903
904 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
905
906 return Status;
907}
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
PSTANDARD_INFORMATION GetStandardInformationFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:1970
#define NTFS_FILENAME_UPDATE_ATTRS
Definition: ntfs.h:1334
#define NTFS_FILE_TYPE_DIRECTORY
Definition: ntfs.h:259
#define NTFS_FILENAME_UPDATE_TIMES
Definition: ntfs.h:1333
NTSTATUS NtfsUpdateDuplicatedInformation(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, ULONGLONG MFTIndex, ULONG Flags, BOOLEAN CaseSensitive)
Definition: mft.c:1995
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
ULONGLONG LastAccessTime
Definition: ntfs.h:364
ULONGLONG ChangeTime
Definition: ntfs.h:363
ULONGLONG LastWriteTime
Definition: ntfs.h:362
ULONG FileAttribute
Definition: ntfs.h:365
ULONGLONG CreationTime
Definition: ntfs.h:361

Referenced by NtfsSetInformation().

◆ NtfsSetDispositionInformation()

static NTSTATUS NtfsSetDispositionInformation ( PDEVICE_EXTENSION  DeviceExt,
PNTFS_FCB  Fcb,
PFILE_OBJECT  FileObject,
BOOLEAN  CaseSensitive,
PFILE_DISPOSITION_INFORMATION  DispositionInfo 
)
static

Definition at line 941 of file finfo.c.

946{
947 DPRINT("NtfsSetDispositionInformation(%p, %p, %p, %s, %p)\n",
948 DeviceExt, Fcb, FileObject, CaseSensitive ? "TRUE" : "FALSE", DispositionInfo);
949
950 if (!DispositionInfo->DeleteFile)
951 {
952 Fcb->Flags &= ~FCB_DELETE_PENDING;
953 FileObject->DeletePending = FALSE;
954 return STATUS_SUCCESS;
955 }
956
958 {
959 DPRINT1("NTFS write-support is EXPERIMENTAL and is disabled by default!\n");
961 }
962
963 /* The volume root has no parent index to be removed from */
964 if (NtfsFCBIsRoot(Fcb))
966
969
971 {
974
975 /* A lookup treats an unreadable sub-node as a miss, which here would
976 * delete a directory that still has children. This check fails instead. */
978 ExAcquireResourceSharedLite(&DeviceExt->IndexResource, TRUE);
980 ExReleaseResourceLite(&DeviceExt->IndexResource);
982
983 if (!NT_SUCCESS(Status))
984 return Status;
985
986 if (!Empty)
988 }
989
990 /* Deleting a mapped file would free its record out from under the section */
991 if (!MmFlushImageSection(&Fcb->SectionObjectPointers, MmFlushForDelete))
993
995 FileObject->DeletePending = TRUE;
996
997 return STATUS_SUCCESS;
998}
@ Empty
Definition: npfs.h:126
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
#define NTFS_FILE_TYPE_READ_ONLY
Definition: ntfs.h:249
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
NTSTATUS NtfsIsDirectoryEmpty(_In_ PDEVICE_EXTENSION Vcb, _In_ ULONGLONG MftIndex, _Out_ PBOOLEAN Empty)
Definition: mft.c:4554
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4413
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
ULONG FileAttributes
Definition: ntfs.h:398
BOOLEAN EnableWriteSupport
Definition: ntfs.h:182
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:597
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167

Referenced by NtfsSetInformation().

◆ NtfsSetEndOfFile()

NTSTATUS NtfsSetEndOfFile ( PNTFS_FCB  Fcb,
PFILE_OBJECT  FileObject,
PDEVICE_EXTENSION  DeviceExt,
ULONG  IrpFlags,
BOOLEAN  CaseSensitive,
PLARGE_INTEGER  NewFileSize 
)

Definition at line 625 of file finfo.c.

631{
632 LARGE_INTEGER CurrentFileSize;
633 PFILE_RECORD_HEADER FileRecord;
634 PNTFS_ATTR_CONTEXT DataContext;
635 ULONG AttributeOffset;
637 PFILENAME_ATTRIBUTE FileNameAttribute;
638
639
640 // Allocate non-paged memory for the file record
641 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
642 if (FileRecord == NULL)
643 {
644 DPRINT1("Couldn't allocate memory for file record!");
646 }
647
648 // read the file record
649 DPRINT("Reading file record...\n");
650 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
651 if (!NT_SUCCESS(Status))
652 {
653 // We couldn't get the file's record. Free the memory and return the error
654 DPRINT1("Can't find record for %wS!\n", Fcb->ObjectName);
655 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
656 return Status;
657 }
658
659 DPRINT("Found record for %wS\n", Fcb->ObjectName);
660
661 CurrentFileSize.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, NULL);
662
663 // Are we trying to decrease the file size?
664 if (NewFileSize->QuadPart < CurrentFileSize.QuadPart)
665 {
666 // Is the file mapped?
667 if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
669 {
670 DPRINT1("Couldn't decrease file size!\n");
671 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
673 }
674 }
675
676 // Find the attribute with the data stream for our file
677 DPRINT("Finding Data Attribute...\n");
678 Status = FindAttribute(DeviceExt,
679 FileRecord,
681 Fcb->Stream,
682 wcslen(Fcb->Stream),
683 &DataContext,
684 &AttributeOffset);
685
686 // Did we fail to find the attribute?
687 if (!NT_SUCCESS(Status))
688 {
689 DPRINT1("No '%S' data stream associated with file!\n", Fcb->Stream);
690 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
691 return Status;
692 }
693
694 // Get the size of the data attribute
695 CurrentFileSize.QuadPart = AttributeDataLength(DataContext->pRecord);
696
697 // Are we enlarging the attribute?
698 if (NewFileSize->QuadPart > CurrentFileSize.QuadPart)
699 {
700 // is increasing the stream size not allowed?
701 if ((Fcb->Flags & FCB_IS_VOLUME) ||
702 (IrpFlags & IRP_PAGING_IO))
703 {
704 // TODO - just fail for now
705 ReleaseAttributeContext(DataContext);
706 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
708 }
709 }
710
711 // set the attribute data length
712 Status = SetAttributeDataLength(FileObject, Fcb, DataContext, AttributeOffset, FileRecord, NewFileSize);
713 if (!NT_SUCCESS(Status))
714 {
715 ReleaseAttributeContext(DataContext);
716 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
717 return Status;
718 }
719
720 // now we need to update this file's size in every directory index entry that references it
721 // TODO: expand to work with every filename / hardlink stored in the file record.
722 FileNameAttribute = GetBestFileNameFromRecord(Fcb->Vcb, FileRecord);
723 if (FileNameAttribute == NULL)
724 {
725 DPRINT1("Unable to find FileName attribute associated with file!\n");
726 ReleaseAttributeContext(DataContext);
727 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
729 }
730
732 FileRecord,
733 Fcb->MFTIndex,
735 CaseSensitive);
736
737 ReleaseAttributeContext(DataContext);
738 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
739
740 return Status;
741}
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:2015
#define NTFS_FILENAME_UPDATE_SIZES
Definition: ntfs.h:1332
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
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
NTSTATUS SetAttributeDataLength(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
Definition: mft.c:615
ULONGLONG NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, PCWSTR Stream, ULONG StreamLength, PULONGLONG AllocatedSize)
Definition: dirctl.c:38
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:833
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4312
PVCB Vcb
Definition: cdstruc.h:933
WCHAR Stream[MAX_PATH]
Definition: ntfs.h:602
#define IRP_PAGING_IO
_In_opt_ PLARGE_INTEGER NewFileSize
Definition: mmfuncs.h:608

Referenced by NtfsSetAllocationInformation(), and NtfsSetInformation().

◆ NtfsSetFileNameAttribute()

static NTSTATUS NtfsSetFileNameAttribute ( _In_ PDEVICE_EXTENSION  DeviceExt,
_Inout_ PFILE_RECORD_HEADER  FileRecord,
_In_ PFILENAME_ATTRIBUTE  Value,
_In_ ULONG  ValueLength 
)
static

Definition at line 1048 of file finfo.c.

1053{
1054 ULONG RecordSize = DeviceExt->NtfsInfo.BytesPerFileRecord;
1055 ULONG HeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
1057 PFILE_RECORD_HEADER NewRecord;
1059 PNTFS_ATTR_RECORD Dest;
1060 ULONG SourceOffset = FileRecord->AttributeOffset;
1061 ULONG DestOffset = FileRecord->AttributeOffset;
1062 BOOLEAN Inserted = FALSE;
1064
1065 NewRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
1066 if (NewRecord == NULL)
1068
1069 RtlZeroMemory(NewRecord, RecordSize);
1070 RtlCopyMemory(NewRecord, FileRecord, FileRecord->AttributeOffset);
1071
1072 for (;;)
1073 {
1074 BOOLEAN AtEnd;
1075
1077 AtEnd = (SourceOffset + sizeof(ULONG) > RecordSize || Source->Type == AttributeEnd);
1078
1079 /* The new name goes ahead of the first attribute that sorts after it */
1080 if (!Inserted && (AtEnd || Source->Type > AttributeFileName))
1081 {
1082 if (DestOffset + NewLength + 2 * sizeof(ULONG) > RecordSize)
1083 {
1085 break;
1086 }
1087
1088 Dest = (PNTFS_ATTR_RECORD)((ULONG_PTR)NewRecord + DestOffset);
1089 Dest->Type = AttributeFileName;
1090 Dest->Length = NewLength;
1091 Dest->Instance = NewRecord->NextAttributeNumber++;
1092 Dest->Resident.ValueLength = ValueLength;
1093 Dest->Resident.ValueOffset = (USHORT)HeaderLength;
1094 Dest->Resident.Flags = RA_INDEXED;
1095 RtlCopyMemory((PUCHAR)Dest + HeaderLength, Value, ValueLength);
1096
1097 DestOffset += NewLength;
1098 Inserted = TRUE;
1099 }
1100
1101 if (AtEnd)
1102 break;
1103
1104 if (Source->Length == 0 || SourceOffset + Source->Length > RecordSize)
1105 {
1107 break;
1108 }
1109
1110 if (Source->Type != AttributeFileName)
1111 {
1112 if (DestOffset + Source->Length + 2 * sizeof(ULONG) > RecordSize)
1113 {
1115 break;
1116 }
1117
1118 RtlCopyMemory((PUCHAR)NewRecord + DestOffset, Source, Source->Length);
1119 DestOffset += Source->Length;
1120 }
1121
1122 SourceOffset += Source->Length;
1123 }
1124
1125 if (NT_SUCCESS(Status))
1126 {
1127 SetFileRecordEnd(NewRecord, (PNTFS_ATTR_RECORD)((ULONG_PTR)NewRecord + DestOffset), FILE_RECORD_END);
1128 RtlCopyMemory(FileRecord, NewRecord, RecordSize);
1129 }
1130
1131 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, NewRecord);
1132 return Status;
1133}
#define ALIGN_UP_BY(size, align)
@ Resident
Definition: data.h:23
#define FILE_RECORD_END
Definition: ntfs.h:209
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:351
#define RA_INDEXED
Definition: ntfs.h:266
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
USHORT Instance
Definition: ntfs.h:140
USHORT NextAttributeNumber
Definition: ntfs.h:291
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFMEMORY _In_ size_t SourceOffset
Definition: wdfmemory.h:320
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275

Referenced by NtfsCommitRename().

◆ NtfsSetInformation()

NTSTATUS NtfsSetInformation ( PNTFS_IRP_CONTEXT  IrpContext)

Definition at line 1748 of file finfo.c.

1749{
1752 PDEVICE_EXTENSION DeviceExt;
1754 PNTFS_FCB Fcb;
1755 PVOID SystemBuffer;
1757 PIRP Irp;
1760
1761 DPRINT("NtfsSetInformation(%p)\n", IrpContext);
1762
1763 Irp = IrpContext->Irp;
1764 Stack = IrpContext->Stack;
1765 DeviceObject = IrpContext->DeviceObject;
1766 DeviceExt = DeviceObject->DeviceExtension;
1767 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
1768 FileObject = IrpContext->FileObject;
1769 Fcb = FileObject->FsContext;
1770
1771 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
1772 BufferLength = Stack->Parameters.QueryFile.Length;
1773
1774 /* A rename changes two directories and the FCB table, which creates rely
1775 * on under DirResource. Take it first, the same order create does. */
1777 !ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
1778 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1779 {
1780 return NtfsMarkIrpContextForQueue(IrpContext);
1781 }
1782
1783 /* Every class below rewrites the file record from a copy it reads, so
1784 * two of them at once on the same file would lose one update */
1786 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1787 {
1789 ExReleaseResourceLite(&DeviceExt->DirResource);
1790
1791 return NtfsMarkIrpContextForQueue(IrpContext);
1792 }
1793
1794 switch (FileInformationClass)
1795 {
1796 PFILE_END_OF_FILE_INFORMATION EndOfFileInfo;
1797
1800 {
1802 break;
1803 }
1804
1805 /* A directory's record carries its index, which a create in it
1806 * could be changing; IndexResource keeps the two apart */
1808 ExAcquireResourceExclusiveLite(&DeviceExt->IndexResource, TRUE);
1809 Status = NtfsSetBasicInformation(DeviceExt,
1810 Fcb,
1812 (PFILE_BASIC_INFORMATION)SystemBuffer);
1813 ExReleaseResourceLite(&DeviceExt->IndexResource);
1815 break;
1816
1819 {
1821 break;
1822 }
1823
1825 FileObject,
1826 DeviceExt,
1827 Irp->Flags,
1829 &((PFILE_ALLOCATION_INFORMATION)SystemBuffer)->AllocationSize);
1830 break;
1831
1833 EndOfFileInfo = (PFILE_END_OF_FILE_INFORMATION)SystemBuffer;
1835 FileObject,
1836 DeviceExt,
1837 Irp->Flags,
1839 &EndOfFileInfo->EndOfFile);
1840 break;
1841
1844 {
1846 break;
1847 }
1848
1850 Fcb,
1851 FileObject,
1853 (PFILE_DISPOSITION_INFORMATION)SystemBuffer);
1854 break;
1855
1858 {
1860 break;
1861 }
1862
1863 Status = NtfsSetRenameInformation(DeviceExt,
1864 Fcb,
1865 Stack->Parameters.SetFile.FileObject,
1866 Stack->Parameters.SetFile.ReplaceIfExists,
1868 (PFILE_RENAME_INFORMATION)SystemBuffer,
1869 BufferLength);
1870 break;
1871
1872 // TODO: all other information classes
1873
1874 default:
1875 DPRINT1("FIXME: Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
1877 }
1878
1880
1882 ExReleaseResourceLite(&DeviceExt->DirResource);
1883
1884 if (NT_SUCCESS(Status))
1885 Irp->IoStatus.Information =
1886 Stack->Parameters.QueryFile.Length - BufferLength;
1887 else
1888 Irp->IoStatus.Information = 0;
1889
1890 return Status;
1891}
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileDispositionInformation
Definition: from_kernel.h:74
struct _FILE_END_OF_FILE_INFORMATION * PFILE_END_OF_FILE_INFORMATION
static NTSTATUS NtfsSetBasicInformation(PDEVICE_EXTENSION DeviceExt, PNTFS_FCB Fcb, BOOLEAN CaseSensitive, PFILE_BASIC_INFORMATION BasicInfo)
Definition: finfo.c:830
static NTSTATUS NTAPI NtfsSetAllocationInformation(_In_ PNTFS_FCB Fcb, _In_ PFILE_OBJECT FileObject, _In_ PDEVICE_EXTENSION DeviceExt, _In_ ULONG IrpFlags, _In_ BOOLEAN CaseSensitive, _In_ PLARGE_INTEGER AllocationSize)
Definition: finfo.c:747
static NTSTATUS NtfsSetRenameInformation(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_opt_ PFILE_OBJECT TargetFileObject, _In_ BOOLEAN ReplaceIfExists, _In_ BOOLEAN CaseSensitive, _In_ PFILE_RENAME_INFORMATION RenameInfo, _In_ ULONG BufferLength)
Definition: finfo.c:1651
static NTSTATUS NtfsSetDispositionInformation(PDEVICE_EXTENSION DeviceExt, PNTFS_FCB Fcb, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PFILE_DISPOSITION_INFORMATION DispositionInfo)
Definition: finfo.c:941
PFILE_OBJECT FileObject
Definition: ntfs.h:599
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820

Referenced by NtfsDispatch().

◆ NtfsSetRenameInformation()

static NTSTATUS NtfsSetRenameInformation ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PNTFS_FCB  Fcb,
_In_opt_ PFILE_OBJECT  TargetFileObject,
_In_ BOOLEAN  ReplaceIfExists,
_In_ BOOLEAN  CaseSensitive,
_In_ PFILE_RENAME_INFORMATION  RenameInfo,
_In_ ULONG  BufferLength 
)
static

Definition at line 1651 of file finfo.c.

1659{
1661 WCHAR NewPath[MAX_PATH];
1662 ULONGLONG TargetDirMft;
1663 ULONGLONG OldParentMft;
1664 PFILE_RECORD_HEADER FileRecord = NULL;
1665 PFILE_RECORD_HEADER Original = NULL;
1666 PFILENAME_ATTRIBUTE OldName;
1667 PFILENAME_ATTRIBUTE NewValue = NULL;
1668 ULONG NewValueLength;
1670
1672 return STATUS_ACCESS_DENIED;
1673
1676
1677 /* Renaming an alternate stream is a different operation */
1678 if (Fcb->Stream[0] != UNICODE_NULL)
1680
1681 Status = NtfsBuildRenamePath(Fcb, TargetFileObject, RenameInfo, BufferLength, &NewName, NewPath, &TargetDirMft);
1682 if (!NT_SUCCESS(Status))
1683 return Status;
1684
1685 Status = NtfsCheckRenamePaths(DeviceExt, Fcb, NewPath);
1686 if (!NT_SUCCESS(Status))
1687 return Status;
1688
1689 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
1690 Original = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
1691 if (FileRecord == NULL || Original == NULL)
1692 {
1694 goto Quit;
1695 }
1696
1697 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
1698 if (!NT_SUCCESS(Status))
1699 goto Quit;
1700
1701 Status = NtfsFindLongFileName(DeviceExt, FileRecord, &OldName, &OldParentMft);
1702 if (!NT_SUCCESS(Status))
1703 goto Quit;
1704
1705 if (TargetFileObject == NULL)
1706 TargetDirMft = OldParentMft;
1707
1708 /* Original is scratch space until it holds the backup below */
1709 Status = NtfsClearRenameTarget(DeviceExt, Fcb, TargetDirMft, &NewName, NewPath, ReplaceIfExists, CaseSensitive, Original);
1710 if (!NT_SUCCESS(Status))
1711 goto Quit;
1712
1713 Status = NtfsBuildRenamedFileName(DeviceExt, OldName, TargetDirMft, &NewName, CaseSensitive, Original, &NewValue, &NewValueLength);
1714 if (!NT_SUCCESS(Status))
1715 goto Quit;
1716
1717 RtlCopyMemory(Original, FileRecord, DeviceExt->NtfsInfo.BytesPerFileRecord);
1718
1719 Status = NtfsCommitRename(DeviceExt,
1720 Fcb,
1721 FileRecord,
1722 Original,
1723 OldParentMft,
1724 TargetDirMft,
1725 NewValue,
1726 NewValueLength,
1727 CaseSensitive);
1728 if (!NT_SUCCESS(Status))
1729 goto Quit;
1730
1731 NtfsRenameFcbs(DeviceExt, Fcb, NewPath);
1732
1733 RtlCopyMemory(&Fcb->Entry, NewValue, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
1734 Fcb->Entry.NameType = NewValue->NameType;
1735
1736Quit:
1737 if (NewValue != NULL)
1738 ExFreePoolWithTag(NewValue, TAG_NTFS);
1739 if (Original != NULL)
1740 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, Original);
1741 if (FileRecord != NULL)
1742 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
1743
1744 return Status;
1745}
#define FCB_IS_VOLUME_STREAM
Definition: ntfs.h:584
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static NTSTATUS NtfsBuildRenamedFileName(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILENAME_ATTRIBUTE OldName, _In_ ULONGLONG TargetDirMft, _In_ PUNICODE_STRING NewName, _In_ BOOLEAN CaseSensitive, _Out_ PFILE_RECORD_HEADER Scratch, _Outptr_ PFILENAME_ATTRIBUTE *NewValue, _Out_ PULONG NewValueLength)
Definition: finfo.c:1466
static VOID NtfsRenameFcbs(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ PCWSTR NewPath)
Definition: finfo.c:1143
static NTSTATUS NtfsCommitRename(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ PFILE_RECORD_HEADER Original, _In_ ULONGLONG OldParentMft, _In_ ULONGLONG TargetDirMft, _In_ PFILENAME_ATTRIBUTE NewValue, _In_ ULONG NewValueLength, _In_ BOOLEAN CaseSensitive)
Definition: finfo.c:1569
static NTSTATUS NtfsFindLongFileName(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _Outptr_ PFILENAME_ATTRIBUTE *LongName, _Out_ PULONGLONG ParentMft)
Definition: finfo.c:1349
static NTSTATUS NtfsBuildRenamePath(_In_ PNTFS_FCB Fcb, _In_opt_ PFILE_OBJECT TargetFileObject, _In_ PFILE_RENAME_INFORMATION RenameInfo, _In_ ULONG BufferLength, _Out_ PUNICODE_STRING NewName, _Out_writes_z_(MAX_PATH) PWSTR NewPath, _Out_ PULONGLONG TargetDirMft)
Definition: finfo.c:1272
static NTSTATUS NtfsCheckRenamePaths(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ PCWSTR NewPath)
Definition: finfo.c:1186
static NTSTATUS NtfsClearRenameTarget(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ ULONGLONG TargetDirMft, _In_ PUNICODE_STRING NewName, _In_z_ PCWSTR NewPath, _In_ BOOLEAN ReplaceIfExists, _In_ BOOLEAN CaseSensitive, _Out_ PFILE_RECORD_HEADER Scratch)
Definition: finfo.c:1408
UCHAR NameType
Definition: ntfs.h:409

Referenced by NtfsSetInformation().

◆ NtfsUnlinkFileNames()

static NTSTATUS NtfsUnlinkFileNames ( _In_ PDEVICE_EXTENSION  DeviceExt,
_In_ PFILE_RECORD_HEADER  FileRecord,
_In_ ULONGLONG  ParentMft,
_In_ BOOLEAN  CaseSensitive,
_Out_ PULONG  Removed 
)
static

Definition at line 1518 of file finfo.c.

1524{
1525 PNTFS_ATTR_RECORD Attribute;
1526 ULONG Offset = FileRecord->AttributeOffset;
1528
1529 *Removed = 0;
1530
1531 while (Offset + sizeof(ULONG) <= DeviceExt->NtfsInfo.BytesPerFileRecord)
1532 {
1533 Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + Offset);
1534 if (Attribute->Type == AttributeEnd || Attribute->Length == 0)
1535 break;
1536
1537 if (Attribute->Type == AttributeFileName && !Attribute->IsNonResident)
1538 {
1540 ParentMft,
1541 (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset),
1542 CaseSensitive);
1543 if (!NT_SUCCESS(Status))
1544 break;
1545
1546 (*Removed)++;
1547 }
1548
1549 Offset += Attribute->Length;
1550 }
1551
1552 return Status;
1553}
NTSTATUS NtfsRemoveFilenameFromDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
Definition: mft.c:3297

Referenced by NtfsCommitRename().