ReactOS  0.4.15-dev-3207-ga415bd4
create.c File Reference
#include "ntfs.h"
#include <debug.h>
Include dependency graph for create.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS NtfsMakeAbsoluteFilename (PFILE_OBJECT pFileObject, PWSTR pRelativeFileName, PWSTR *pAbsoluteFilename)
 
static NTSTATUS NtfsMoonWalkID (PDEVICE_EXTENSION DeviceExt, ULONGLONG Id, PUNICODE_STRING OutPath)
 
static NTSTATUS NtfsOpenFileById (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, ULONGLONG MftId, PNTFS_FCB *FoundFCB)
 
static NTSTATUS NtfsOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR FileName, BOOLEAN CaseSensitive, PNTFS_FCB *FoundFCB)
 
static NTSTATUS NtfsCreateFile (PDEVICE_OBJECT DeviceObject, PNTFS_IRP_CONTEXT IrpContext)
 
NTSTATUS NtfsCreate (PNTFS_IRP_CONTEXT IrpContext)
 
NtfsCreateDirectory()

@implemented

Creates a file record for a new directory and saves it to the MFT. Adds the filename attribute of the created directory to the parent directory's index.

Parameters
DeviceExtPoints to the target disk's DEVICE_EXTENSION
FileObjectPointer to a FILE_OBJECT describing the directory to be created
CaseSensitiveBoolean indicating if the function should operate in case-sensitive mode. This will be TRUE if an application created the folder with the FILE_FLAG_POSIX_SEMANTICS flag.
CanWaitBoolean indicating if the function is allowed to wait for exclusive access to the master file table. This will only be relevant if the MFT doesn't have any free file records and needs to be enlarged.
Returns
STATUS_SUCCESS on success. STATUS_INSUFFICIENT_RESOURCES if unable to allocate memory for the file record. STATUS_CANT_WAIT if CanWait was FALSE and the function needed to resize the MFT but couldn't get immediate, exclusive access to it.
NTSTATUS NtfsCreateDirectory (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, BOOLEAN CanWait)
 
NtfsCreateEmptyFileRecord

@implemented

Creates a new, empty file record, with no attributes.

Parameters
DeviceExtPointer to the DEVICE_EXTENSION of the target volume the file record will be stored on.
Returns
A pointer to the newly-created FILE_RECORD_HEADER if the function succeeds, NULL otherwise.
PFILE_RECORD_HEADER NtfsCreateEmptyFileRecord (PDEVICE_EXTENSION DeviceExt)
 
NtfsCreateFileRecord()

@implemented

Creates a file record and saves it to the MFT. Adds the filename attribute of the created file to the parent directory's index.

Parameters
DeviceExtPoints to the target disk's DEVICE_EXTENSION
FileObjectPointer to a FILE_OBJECT describing the file to be created
CanWaitBoolean indicating if the function is allowed to wait for exclusive access to the master file table. This will only be relevant if the MFT doesn't have any free file records and needs to be enlarged.
Returns
STATUS_SUCCESS on success. STATUS_INSUFFICIENT_RESOURCES if unable to allocate memory for the file record. STATUS_CANT_WAIT if CanWait was FALSE and the function needed to resize the MFT but couldn't get immediate, exclusive access to it.
NTSTATUS NtfsCreateFileRecord (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, BOOLEAN CanWait)
 

Variables

static PCWSTR MftIdToName []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 31 of file create.c.

Function Documentation

◆ NtfsCreate()

NTSTATUS NtfsCreate ( PNTFS_IRP_CONTEXT  IrpContext)

Definition at line 622 of file create.c.

623 {
624  PDEVICE_EXTENSION DeviceExt;
627 
628  DeviceObject = IrpContext->DeviceObject;
630  {
631  /* DeviceObject represents FileSystem instead of logical volume */
632  DPRINT("Opening file system\n");
633  IrpContext->Irp->IoStatus.Information = FILE_OPENED;
634  return STATUS_SUCCESS;
635  }
636 
637  DeviceExt = DeviceObject->DeviceExtension;
638 
639  if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
640  {
641  return NtfsMarkIrpContextForQueue(IrpContext);
642  }
643 
644  ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
645  TRUE);
647  IrpContext);
648  ExReleaseResourceLite(&DeviceExt->DirResource);
649 
650  return Status;
651 }
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:488
Iosb Status
Definition: create.c:4287
static NTSTATUS NtfsCreateFile(PDEVICE_OBJECT DeviceObject, PNTFS_IRP_CONTEXT IrpContext)
Definition: create.c:328
#define TRUE
Definition: types.h:120
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
Definition: ntfs.h:569
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_OPENED
Definition: nt_native.h:769
IO_STATUS_BLOCK IoStatus
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:575
Status
Definition: gdiplustypes.h:24
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
ULONG Flags
Definition: ntfs.h:481
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:148
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

Referenced by NtfsDispatch().

◆ NtfsCreateDirectory()

NTSTATUS NtfsCreateDirectory ( PDEVICE_EXTENSION  DeviceExt,
PFILE_OBJECT  FileObject,
BOOLEAN  CaseSensitive,
BOOLEAN  CanWait 
)

Definition at line 681 of file create.c.

685 {
686 
688  PFILE_RECORD_HEADER FileRecord;
689  PNTFS_ATTR_RECORD NextAttribute;
690  PFILENAME_ATTRIBUTE FilenameAttribute;
691  ULONGLONG ParentMftIndex;
692  ULONGLONG FileMftIndex;
693  PB_TREE Tree;
694  PINDEX_ROOT_ATTRIBUTE NewIndexRoot;
695  ULONG MaxIndexRootSize;
696  ULONG RootLength;
697 
698  DPRINT("NtfsCreateFileRecord(%p, %p, %s, %s)\n",
699  DeviceExt,
700  FileObject,
701  CaseSensitive ? "TRUE" : "FALSE",
702  CanWait ? "TRUE" : "FALSE");
703 
704  // Start with an empty file record
705  FileRecord = NtfsCreateEmptyFileRecord(DeviceExt);
706  if (!FileRecord)
707  {
708  DPRINT1("ERROR: Unable to allocate memory for file record!\n");
710  }
711 
712  // Set the directory flag
713  FileRecord->Flags |= FRH_DIRECTORY;
714 
715  // find where the first attribute will be added
716  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
717 
718  // add first attribute, $STANDARD_INFORMATION
719  AddStandardInformation(FileRecord, NextAttribute);
720 
721  // advance NextAttribute pointer to the next attribute
722  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)NextAttribute + (ULONG_PTR)NextAttribute->Length);
723 
724  // Add the $FILE_NAME attribute
725  AddFileName(FileRecord, NextAttribute, DeviceExt, FileObject, CaseSensitive, &ParentMftIndex);
726 
727  // save a pointer to the filename attribute
728  FilenameAttribute = (PFILENAME_ATTRIBUTE)((ULONG_PTR)NextAttribute + NextAttribute->Resident.ValueOffset);
729 
730  // advance NextAttribute pointer to the next attribute
731  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)NextAttribute + (ULONG_PTR)NextAttribute->Length);
732 
733  // Create an empty b-tree to represent our new index
735  if (!NT_SUCCESS(Status))
736  {
737  DPRINT1("ERROR: Failed to create empty B-Tree!\n");
738  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
739  return Status;
740  }
741 
742  // Calculate maximum size of index root
743  MaxIndexRootSize = DeviceExt->NtfsInfo.BytesPerFileRecord
744  - ((ULONG_PTR)NextAttribute - (ULONG_PTR)FileRecord)
745  - sizeof(ULONG) * 2;
746 
747  // Create a new index record from the tree
748  Status = CreateIndexRootFromBTree(DeviceExt,
749  Tree,
750  MaxIndexRootSize,
751  &NewIndexRoot,
752  &RootLength);
753  if (!NT_SUCCESS(Status))
754  {
755  DPRINT1("ERROR: Unable to create empty index root!\n");
757  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
758  return Status;
759  }
760 
761  // We're done with the B-Tree
763 
764  // add the $INDEX_ROOT attribute
765  Status = AddIndexRoot(DeviceExt, FileRecord, NextAttribute, NewIndexRoot, RootLength, L"$I30", 4);
766  if (!NT_SUCCESS(Status))
767  {
768  DPRINT1("ERROR: Failed to add index root to new file record!\n");
769  ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
770  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
771  return Status;
772  }
773 
774 
775 #ifndef NDEBUG
776  NtfsDumpFileRecord(DeviceExt, FileRecord);
777 #endif
778 
779  // Now that we've built the file record in memory, we need to store it in the MFT.
780  Status = AddNewMftEntry(FileRecord, DeviceExt, &FileMftIndex, CanWait);
781  if (NT_SUCCESS(Status))
782  {
783  // The highest 2 bytes should be the sequence number, unless the parent happens to be root
784  if (FileMftIndex == NTFS_FILE_ROOT)
785  FileMftIndex = FileMftIndex + ((ULONGLONG)NTFS_FILE_ROOT << 48);
786  else
787  FileMftIndex = FileMftIndex + ((ULONGLONG)FileRecord->SequenceNumber << 48);
788 
789  DPRINT1("New File Reference: 0x%016I64x\n", FileMftIndex);
790 
791  // Add the filename attribute to the filename-index of the parent directory
793  ParentMftIndex,
794  FileMftIndex,
795  FilenameAttribute,
796  CaseSensitive);
797  }
798 
799  ExFreePoolWithTag(NewIndexRoot, TAG_NTFS);
800  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
801 
802  return Status;
803 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Iosb Status
Definition: create.c:4287
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
NTSTATUS NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
Definition: mft.c:2192
NTSTATUS AddStandardInformation(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
Definition: attrib.c:766
LONG NTSTATUS
Definition: precomp.h:26
USHORT SequenceNumber
Definition: ntfs.h:253
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS CreateEmptyBTree(PB_TREE *NewTree)
Definition: btree.c:348
NTSTATUS AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, PULONGLONG DestinationIndex, BOOLEAN CanWait)
Definition: mft.c:2022
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
ULONG Length
Definition: ntfs.h:123
USHORT AttributeOffset
Definition: ntfs.h:255
#define FRH_DIRECTORY
Definition: ntfs.h:268
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
struct NTFS_ATTR_RECORD::@164::@166 Resident
CRegistryTree Tree
#define TAG_NTFS
Definition: ntfs.h:12
NTSTATUS AddIndexRoot(PNTFS_VCB Vcb, PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PINDEX_ROOT_ATTRIBUTE NewIndexRoot, ULONG RootLength, PCWSTR Name, USHORT NameLength)
Definition: attrib.c:495
NTSTATUS CreateIndexRootFromBTree(PDEVICE_EXTENSION DeviceExt, PB_TREE Tree, ULONG MaxIndexSize, PINDEX_ROOT_ATTRIBUTE *IndexRoot, ULONG *Length)
Definition: btree.c:910
VOID NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:3334
static const WCHAR L[]
Definition: oid.c:1250
VOID DestroyBTree(PB_TREE Tree)
Definition: btree.c:1542
PFILE_RECORD_HEADER NtfsCreateEmptyFileRecord(PDEVICE_EXTENSION DeviceExt)
Definition: create.c:818
USHORT Flags
Definition: ntfs.h:256
Definition: ntfs.h:453
#define DPRINT1
Definition: precomp.h:8
NTSTATUS AddFileName(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PULONGLONG ParentMftIndex)
Definition: attrib.c:230
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define NTFS_FILE_ROOT
Definition: ntfs.h:28

Referenced by NtfsCreateFile().

◆ NtfsCreateEmptyFileRecord()

PFILE_RECORD_HEADER NtfsCreateEmptyFileRecord ( PDEVICE_EXTENSION  DeviceExt)

Definition at line 818 of file create.c.

819 {
820  PFILE_RECORD_HEADER FileRecord;
821  PNTFS_ATTR_RECORD NextAttribute;
822 
823  DPRINT("NtfsCreateEmptyFileRecord(%p)\n", DeviceExt);
824 
825  // allocate memory for file record
826  FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
827  if (!FileRecord)
828  {
829  DPRINT1("ERROR: Unable to allocate memory for file record!\n");
830  return NULL;
831  }
832 
833  RtlZeroMemory(FileRecord, DeviceExt->NtfsInfo.BytesPerFileRecord);
834 
835  FileRecord->Ntfs.Type = NRH_FILE_TYPE;
836 
837  // calculate USA offset and count
838  FileRecord->Ntfs.UsaOffset = FIELD_OFFSET(FILE_RECORD_HEADER, MFTRecordNumber) + sizeof(ULONG);
839 
840  // size of USA (in ULONG's) will be 1 (for USA number) + 1 for every sector the file record uses
841  FileRecord->BytesAllocated = DeviceExt->NtfsInfo.BytesPerFileRecord;
842  FileRecord->Ntfs.UsaCount = (FileRecord->BytesAllocated / DeviceExt->NtfsInfo.BytesPerSector) + 1;
843 
844  // setup other file record fields
845  FileRecord->SequenceNumber = 1;
846  FileRecord->AttributeOffset = FileRecord->Ntfs.UsaOffset + (2 * FileRecord->Ntfs.UsaCount);
848  FileRecord->Flags = FRH_IN_USE;
849  FileRecord->BytesInUse = FileRecord->AttributeOffset + sizeof(ULONG) * 2;
850 
851  // find where the first attribute will be added
852  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
853 
854  // mark the (temporary) end of the file-record
855  NextAttribute->Type = AttributeEnd;
856  NextAttribute->Length = FILE_RECORD_END;
857 
858  return FileRecord;
859 }
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define FILE_RECORD_END
Definition: ntfs.h:182
ULONG BytesInUse
Definition: ntfs.h:257
ULONG Type
Definition: ntfs.h:122
USHORT SequenceNumber
Definition: ntfs.h:253
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FRH_IN_USE
Definition: ntfs.h:267
ULONG Length
Definition: ntfs.h:123
USHORT AttributeOffset
Definition: ntfs.h:255
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:320
ULONG BytesAllocated
Definition: ntfs.h:258
USHORT UsaCount
Definition: ntfs.h:241
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
USHORT Flags
Definition: ntfs.h:256
#define DPRINT1
Definition: precomp.h:8
#define NRH_FILE_TYPE
Definition: ntfs.h:246
NTFS_RECORD_HEADER Ntfs
Definition: ntfs.h:252
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ALIGN_UP_BY(size, align)
USHORT UsaOffset
Definition: ntfs.h:240
#define DPRINT
Definition: sndvol32.h:71

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

◆ NtfsCreateFile()

static NTSTATUS NtfsCreateFile ( PDEVICE_OBJECT  DeviceObject,
PNTFS_IRP_CONTEXT  IrpContext 
)
static

Definition at line 328 of file create.c.

330 {
331  PDEVICE_EXTENSION DeviceExt;
334  ULONG RequestedDisposition;
335  ULONG RequestedOptions;
336  PNTFS_FCB Fcb = NULL;
337 // PWSTR FileName;
339  UNICODE_STRING FullPath;
340  PIRP Irp = IrpContext->Irp;
341 
342  DPRINT("NtfsCreateFile(%p, %p) called\n", DeviceObject, IrpContext);
343 
344  DeviceExt = DeviceObject->DeviceExtension;
345  ASSERT(DeviceExt);
347  ASSERT(Stack);
348 
349  RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
350  RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
351 // PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
352  if (RequestedOptions & FILE_DIRECTORY_FILE &&
353  RequestedDisposition == FILE_SUPERSEDE)
354  {
356  }
357 
358  /* Deny create if the volume is locked */
359  if (DeviceExt->Flags & VCB_VOLUME_LOCKED)
360  {
361  return STATUS_ACCESS_DENIED;
362  }
363 
364  FileObject = Stack->FileObject;
365 
366  if ((RequestedOptions & FILE_OPEN_BY_FILE_ID) == FILE_OPEN_BY_FILE_ID)
367  {
368  ULONGLONG MFTId;
369 
370  if (FileObject->FileName.Length != sizeof(ULONGLONG))
372 
373  MFTId = (*(PULONGLONG)FileObject->FileName.Buffer) & NTFS_MFT_MASK;
374  if (MFTId < NTFS_FILE_FIRST_USER_FILE)
375  {
376  Status = NtfsOpenFileById(DeviceExt, FileObject, MFTId, &Fcb);
377  }
378  else
379  {
380  Status = NtfsMoonWalkID(DeviceExt, MFTId, &FullPath);
381  }
382 
383  if (!NT_SUCCESS(Status))
384  {
385  return Status;
386  }
387 
388  DPRINT1("Open by ID: %I64x -> %wZ\n", (*(PULONGLONG)FileObject->FileName.Buffer) & NTFS_MFT_MASK, &FullPath);
389  }
390 
391  /* This a open operation for the volume itself */
392  if (FileObject->FileName.Length == 0 &&
393  (FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 != NULL))
394  {
395  if (RequestedDisposition != FILE_OPEN &&
396  RequestedDisposition != FILE_OPEN_IF)
397  {
398  return STATUS_ACCESS_DENIED;
399  }
400 
401  if (RequestedOptions & FILE_DIRECTORY_FILE)
402  {
403  return STATUS_NOT_A_DIRECTORY;
404  }
405 
406  NtfsAttachFCBToFileObject(DeviceExt, DeviceExt->VolumeFcb, FileObject);
407  DeviceExt->VolumeFcb->RefCount++;
408 
409  Irp->IoStatus.Information = FILE_OPENED;
410  return STATUS_SUCCESS;
411  }
412 
413  if (Fcb == NULL)
414  {
415  Status = NtfsOpenFile(DeviceExt,
416  FileObject,
417  ((RequestedOptions & FILE_OPEN_BY_FILE_ID) ? FullPath.Buffer : FileObject->FileName.Buffer),
419  &Fcb);
420 
421  if (RequestedOptions & FILE_OPEN_BY_FILE_ID)
422  {
423  ExFreePoolWithTag(FullPath.Buffer, TAG_NTFS);
424  }
425  }
426 
427  if (NT_SUCCESS(Status))
428  {
429  if (RequestedDisposition == FILE_CREATE)
430  {
431  Irp->IoStatus.Information = FILE_EXISTS;
432  NtfsCloseFile(DeviceExt, FileObject);
434  }
435 
436  if (RequestedOptions & FILE_NON_DIRECTORY_FILE &&
438  {
439  NtfsCloseFile(DeviceExt, FileObject);
441  }
442 
443  if (RequestedOptions & FILE_DIRECTORY_FILE &&
445  {
446  NtfsCloseFile(DeviceExt, FileObject);
447  return STATUS_NOT_A_DIRECTORY;
448  }
449 
450  /*
451  * If it is a reparse point & FILE_OPEN_REPARSE_POINT, then allow opening it
452  * as a normal file.
453  * Otherwise, attempt to read reparse data and hand them to the Io manager
454  * with status reparse to force a reparse.
455  */
456  if (NtfsFCBIsReparsePoint(Fcb) &&
457  ((RequestedOptions & FILE_OPEN_REPARSE_POINT) != FILE_OPEN_REPARSE_POINT))
458  {
459  PREPARSE_DATA_BUFFER ReparseData = NULL;
460 
461  Status = NtfsReadFCBAttribute(DeviceExt, Fcb,
462  AttributeReparsePoint, L"", 0,
463  (PVOID *)&Irp->Tail.Overlay.AuxiliaryBuffer);
464  if (NT_SUCCESS(Status))
465  {
466  ReparseData = (PREPARSE_DATA_BUFFER)Irp->Tail.Overlay.AuxiliaryBuffer;
467  if (ReparseData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
468  {
470  }
471  else
472  {
474  ExFreePoolWithTag(ReparseData, TAG_NTFS);
475  }
476  }
477 
478  Irp->IoStatus.Information = ((Status == STATUS_REPARSE) ? ReparseData->ReparseTag : 0);
479 
480  NtfsCloseFile(DeviceExt, FileObject);
481  return Status;
482  }
483 
484  if (RequestedDisposition == FILE_OVERWRITE ||
485  RequestedDisposition == FILE_OVERWRITE_IF ||
486  RequestedDisposition == FILE_SUPERSEDE)
487  {
488  PFILE_RECORD_HEADER fileRecord = NULL;
489  PNTFS_ATTR_CONTEXT dataContext = NULL;
490  ULONG DataAttributeOffset;
492  Zero.QuadPart = 0;
493 
495  {
496  DPRINT1("NTFS write-support is EXPERIMENTAL and is disabled by default!\n");
497  NtfsCloseFile(DeviceExt, FileObject);
498  return STATUS_ACCESS_DENIED;
499  }
500 
501  // TODO: check for appropriate access
502 
504 
505  fileRecord = ExAllocateFromNPagedLookasideList(&Fcb->Vcb->FileRecLookasideList);
506  if (fileRecord)
507  {
508 
510  Fcb->MFTIndex,
511  fileRecord);
512  if (!NT_SUCCESS(Status))
513  goto DoneOverwriting;
514 
515  // find the data attribute and set it's length to 0 (TODO: Handle Alternate Data Streams)
516  Status = FindAttribute(Fcb->Vcb, fileRecord, AttributeData, L"", 0, &dataContext, &DataAttributeOffset);
517  if (!NT_SUCCESS(Status))
518  goto DoneOverwriting;
519 
520  Status = SetAttributeDataLength(FileObject, Fcb, dataContext, DataAttributeOffset, fileRecord, &Zero);
521  }
522  else
523  {
525  }
526 
527  DoneOverwriting:
528  if (fileRecord)
529  ExFreeToNPagedLookasideList(&Fcb->Vcb->FileRecLookasideList, fileRecord);
530  if (dataContext)
531  ReleaseAttributeContext(dataContext);
532 
534 
535  if (!NT_SUCCESS(Status))
536  {
537  NtfsCloseFile(DeviceExt, FileObject);
538  return Status;
539  }
540 
541  if (RequestedDisposition == FILE_SUPERSEDE)
542  {
543  Irp->IoStatus.Information = FILE_SUPERSEDED;
544  }
545  else
546  {
547  Irp->IoStatus.Information = FILE_OVERWRITTEN;
548  }
549  }
550  }
551  else
552  {
553  /* HUGLY HACK: Can't create new files yet... */
554  if (RequestedDisposition == FILE_CREATE ||
555  RequestedDisposition == FILE_OPEN_IF ||
556  RequestedDisposition == FILE_OVERWRITE_IF ||
557  RequestedDisposition == FILE_SUPERSEDE)
558  {
560  {
561  DPRINT1("NTFS write-support is EXPERIMENTAL and is disabled by default!\n");
562  NtfsCloseFile(DeviceExt, FileObject);
563  return STATUS_ACCESS_DENIED;
564  }
565 
566  // Was the user trying to create a directory?
567  if (RequestedOptions & FILE_DIRECTORY_FILE)
568  {
569  // Create the directory on disk
570  Status = NtfsCreateDirectory(DeviceExt,
571  FileObject,
573  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT));
574  }
575  else
576  {
577  // Create the file record on disk
578  Status = NtfsCreateFileRecord(DeviceExt,
579  FileObject,
581  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT));
582  }
583 
584  if (!NT_SUCCESS(Status))
585  {
586  DPRINT1("ERROR: Couldn't create file record!\n");
587  return Status;
588  }
589 
590  // Before we open the file/directory we just created, we need to change the disposition (upper 8 bits of ULONG)
591  // from create to open, since we already created the file
592  Stack->Parameters.Create.Options = (ULONG)FILE_OPEN << 24 | RequestedOptions;
593 
594  // Now we should be able to open the file using NtfsCreateFile()
595  Status = NtfsCreateFile(DeviceObject, IrpContext);
596  if (NT_SUCCESS(Status))
597  {
598  // We need to change Irp->IoStatus.Information to reflect creation
599  Irp->IoStatus.Information = FILE_CREATED;
600  }
601  return Status;
602  }
603  }
604 
605  if (NT_SUCCESS(Status))
606  {
607  Fcb->OpenHandleCount++;
608  DeviceExt->OpenHandleCount++;
609  }
610 
611  /*
612  * If the directory containing the file to open doesn't exist then
613  * fail immediately
614  */
615  Irp->IoStatus.Information = (NT_SUCCESS(Status)) ? FILE_OPENED : 0;
616 
617  return Status;
618 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define NTFS_MFT_MASK
Definition: ntfs.h:198
#define FILE_EXISTS
Definition: nt_native.h:772
NTSTATUS NtfsCreateDirectory(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, BOOLEAN CanWait)
Definition: create.c:681
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
#define FILE_OPEN_IF
Definition: from_kernel.h:56
BOOLEAN NtfsFCBIsReparsePoint(PNTFS_FCB Fcb)
Definition: fcb.c:134
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
static NTSTATUS NtfsOpenFileById(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, ULONGLONG MftId, PNTFS_FCB *FoundFCB)
Definition: create.c:175
Iosb Status
Definition: create.c:4287
static NTSTATUS NtfsCreateFile(PDEVICE_OBJECT DeviceObject, PNTFS_IRP_CONTEXT IrpContext)
Definition: create.c:328
#define TRUE
Definition: types.h:120
Definition: cdstruc.h:902
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
if(OpenRequiringOplock &&(Iosb.Status==STATUS_SUCCESS))
Definition: create.c:4300
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OPENED
Definition: nt_native.h:769
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define FILE_OVERWRITE
Definition: from_kernel.h:57
NTSTATUS NtfsCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
Definition: close.c:40
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
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:127
ULONGLONG MFTIndex
Definition: ntfs.h:539
static NTSTATUS NtfsOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, PWSTR FileName, BOOLEAN CaseSensitive, PNTFS_FCB *FoundFCB)
Definition: create.c:242
NTSTATUS NtfsAttachFCBToFileObject(PNTFS_VCB Vcb, PNTFS_FCB Fcb, PFILE_OBJECT FileObject)
Definition: fcb.c:459
#define FILE_VALID_OPTION_FLAGS
Definition: nt_native.h:759
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7231
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
return STATUS_NOT_IMPLEMENTED
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT FileObject
Definition: create.c:4137
NTSTATUS NtfsReadFCBAttribute(PNTFS_VCB Vcb, PNTFS_FCB pFCB, ULONG Type, PCWSTR Name, ULONG NameLength, PVOID *Data)
Definition: fcb.c:730
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:575
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
NTSTATUS NtfsCreateFileRecord(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, BOOLEAN CanWait)
Definition: create.c:886
Status
Definition: gdiplustypes.h:24
ULONG OpenHandleCount
Definition: ntfs.h:537
#define ASSERT(a)
Definition: mode.c:44
#define NTFS_FILE_FIRST_USER_FILE
Definition: ntfs.h:196
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1998
#define TAG_NTFS
Definition: ntfs.h:12
static const WCHAR L[]
Definition: oid.c:1250
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
ULONG Flags
Definition: ntfs.h:481
static NTSTATUS NtfsMoonWalkID(PDEVICE_EXTENSION DeviceExt, ULONGLONG Id, PUNICODE_STRING OutPath)
Definition: create.c:104
ERESOURCE MainResource
Definition: ntfs.h:528
#define FILE_OPEN
Definition: from_kernel.h:54
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
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
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_REPARSE
Definition: ntstatus.h:83
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
#define NULL
Definition: types.h:112
#define FILE_CREATED
Definition: nt_native.h:770
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:411
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:780
#define DPRINT1
Definition: precomp.h:8
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
unsigned int ULONG
Definition: retypes.h:1
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
PVCB Vcb
Definition: cdstruc.h:933
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
BOOLEAN EnableWriteSupport
Definition: ntfs.h:155
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER

Referenced by NtfsCreate().

◆ NtfsCreateFileRecord()

NTSTATUS NtfsCreateFileRecord ( PDEVICE_EXTENSION  DeviceExt,
PFILE_OBJECT  FileObject,
BOOLEAN  CaseSensitive,
BOOLEAN  CanWait 
)

Definition at line 886 of file create.c.

890 {
892  PFILE_RECORD_HEADER FileRecord;
893  PNTFS_ATTR_RECORD NextAttribute;
894  PFILENAME_ATTRIBUTE FilenameAttribute;
895  ULONGLONG ParentMftIndex;
896  ULONGLONG FileMftIndex;
897 
898  DPRINT("NtfsCreateFileRecord(%p, %p, %s, %s)\n",
899  DeviceExt,
900  FileObject,
901  CaseSensitive ? "TRUE" : "FALSE",
902  CanWait ? "TRUE" : "FALSE");
903 
904  // allocate memory for file record
905  FileRecord = NtfsCreateEmptyFileRecord(DeviceExt);
906  if (!FileRecord)
907  {
908  DPRINT1("ERROR: Unable to allocate memory for file record!\n");
910  }
911 
912  // find where the first attribute will be added
913  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
914 
915  // add first attribute, $STANDARD_INFORMATION
916  AddStandardInformation(FileRecord, NextAttribute);
917 
918  // advance NextAttribute pointer to the next attribute
919  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)NextAttribute + (ULONG_PTR)NextAttribute->Length);
920 
921  // Add the $FILE_NAME attribute
922  AddFileName(FileRecord, NextAttribute, DeviceExt, FileObject, CaseSensitive, &ParentMftIndex);
923 
924  // save a pointer to the filename attribute
925  FilenameAttribute = (PFILENAME_ATTRIBUTE)((ULONG_PTR)NextAttribute + NextAttribute->Resident.ValueOffset);
926 
927  // advance NextAttribute pointer to the next attribute
928  NextAttribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)NextAttribute + (ULONG_PTR)NextAttribute->Length);
929 
930  // add the $DATA attribute
931  AddData(FileRecord, NextAttribute);
932 
933 #ifndef NDEBUG
934  // dump file record in memory (for debugging)
935  NtfsDumpFileRecord(DeviceExt, FileRecord);
936 #endif
937 
938  // Now that we've built the file record in memory, we need to store it in the MFT.
939  Status = AddNewMftEntry(FileRecord, DeviceExt, &FileMftIndex, CanWait);
940  if (NT_SUCCESS(Status))
941  {
942  // The highest 2 bytes should be the sequence number, unless the parent happens to be root
943  if (FileMftIndex == NTFS_FILE_ROOT)
944  FileMftIndex = FileMftIndex + ((ULONGLONG)NTFS_FILE_ROOT << 48);
945  else
946  FileMftIndex = FileMftIndex + ((ULONGLONG)FileRecord->SequenceNumber << 48);
947 
948  DPRINT1("New File Reference: 0x%016I64x\n", FileMftIndex);
949 
950  // Add the filename attribute to the filename-index of the parent directory
952  ParentMftIndex,
953  FileMftIndex,
954  FilenameAttribute,
955  CaseSensitive);
956  }
957 
958  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
959 
960  return Status;
961 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Iosb Status
Definition: create.c:4287
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
NTSTATUS NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
Definition: mft.c:2192
NTSTATUS AddStandardInformation(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
Definition: attrib.c:766
LONG NTSTATUS
Definition: precomp.h:26
USHORT SequenceNumber
Definition: ntfs.h:253
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, PULONGLONG DestinationIndex, BOOLEAN CanWait)
Definition: mft.c:2022
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
ULONG Length
Definition: ntfs.h:123
USHORT AttributeOffset
Definition: ntfs.h:255
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
NTSTATUS AddData(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress)
Definition: attrib.c:160
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
struct NTFS_ATTR_RECORD::@164::@166 Resident
VOID NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:3334
PFILE_RECORD_HEADER NtfsCreateEmptyFileRecord(PDEVICE_EXTENSION DeviceExt)
Definition: create.c:818
#define DPRINT1
Definition: precomp.h:8
NTSTATUS AddFileName(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttributeAddress, PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PULONGLONG ParentMftIndex)
Definition: attrib.c:230
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define NTFS_FILE_ROOT
Definition: ntfs.h:28

Referenced by NtfsCreateFile().

◆ NtfsMakeAbsoluteFilename()

static NTSTATUS NtfsMakeAbsoluteFilename ( PFILE_OBJECT  pFileObject,
PWSTR  pRelativeFileName,
PWSTR pAbsoluteFilename 
)
static

Definition at line 53 of file create.c.

56 {
57  PWSTR rcName;
58  PNTFS_FCB Fcb;
59 
60  DPRINT("try related for %S\n", pRelativeFileName);
61  Fcb = pFileObject->FsContext;
62  ASSERT(Fcb);
63 
64  if (Fcb->Flags & FCB_IS_VOLUME)
65  {
66  /* This is likely to be an opening by ID, return ourselves */
67  if (pRelativeFileName[0] == L'\\')
68  {
69  *pAbsoluteFilename = NULL;
70  return STATUS_SUCCESS;
71  }
72 
74  }
75 
76  /* verify related object is a directory and target name
77  don't start with \. */
78  if (NtfsFCBIsDirectory(Fcb) == FALSE ||
79  pRelativeFileName[0] == L'\\')
80  {
82  }
83 
84  /* construct absolute path name */
85  ASSERT(wcslen (Fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1 <= MAX_PATH);
87  if (!rcName)
88  {
90  }
91 
92  wcscpy(rcName, Fcb->PathName);
93  if (!NtfsFCBIsRoot(Fcb))
94  wcscat (rcName, L"\\");
95  wcscat (rcName, pRelativeFileName);
96  *pAbsoluteFilename = rcName;
97 
98  return STATUS_SUCCESS;
99 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Definition: cdstruc.h:902
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
WCHAR PathName[MAX_PATH]
Definition: ntfs.h:525
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:127
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
#define TAG_NTFS
Definition: ntfs.h:12
ULONG Flags
Definition: ntfs.h:536
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define FCB_IS_VOLUME
Definition: vfat.h:437
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
_In_ PFCB Fcb
Definition: cdprocs.h:159
BOOLEAN NtfsFCBIsRoot(PNTFS_FCB Fcb)
Definition: fcb.c:153

Referenced by NtfsOpenFile().

◆ NtfsMoonWalkID()

static NTSTATUS NtfsMoonWalkID ( PDEVICE_EXTENSION  DeviceExt,
ULONGLONG  Id,
PUNICODE_STRING  OutPath 
)
static

Definition at line 104 of file create.c.

107 {
109  PFILE_RECORD_HEADER MftRecord;
111  WCHAR FullPath[MAX_PATH];
112  ULONG WritePosition = MAX_PATH - 1;
113 
114  DPRINT("NtfsMoonWalkID(%p, %I64x, %p)\n", DeviceExt, Id, OutPath);
115 
116  RtlZeroMemory(FullPath, sizeof(FullPath));
117  MftRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
118  if (MftRecord == NULL)
119  {
121  }
122 
123  while (TRUE)
124  {
125  Status = ReadFileRecord(DeviceExt, Id, MftRecord);
126  if (!NT_SUCCESS(Status))
127  break;
128 
129  ASSERT(MftRecord->Ntfs.Type == NRH_FILE_TYPE);
130  if (!(MftRecord->Flags & FRH_IN_USE))
131  {
133  break;
134  }
135 
136  FileName = GetBestFileNameFromRecord(DeviceExt, MftRecord);
137  if (FileName == NULL)
138  {
139  DPRINT1("$FILE_NAME attribute not found for %I64x\n", Id);
141  break;
142  }
143 
144  WritePosition -= FileName->NameLength;
145  ASSERT(WritePosition < MAX_PATH);
146  RtlCopyMemory(FullPath + WritePosition, FileName->Name, FileName->NameLength * sizeof(WCHAR));
147  WritePosition -= 1;
148  ASSERT(WritePosition < MAX_PATH);
149  FullPath[WritePosition] = L'\\';
150 
151  Id = FileName->DirectoryFileReferenceNumber & NTFS_MFT_MASK;
152  if (Id == NTFS_FILE_ROOT)
153  break;
154  }
155 
156  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, MftRecord);
157 
158  if (!NT_SUCCESS(Status))
159  return Status;
160 
161  OutPath->Length = (MAX_PATH - WritePosition - 1) * sizeof(WCHAR);
162  OutPath->MaximumLength = (MAX_PATH - WritePosition) * sizeof(WCHAR);
164  if (OutPath->Buffer == NULL)
165  {
167  }
168  RtlCopyMemory(OutPath->Buffer, FullPath + WritePosition, OutPath->MaximumLength);
169 
170  return Status;
171 }
#define NTFS_MFT_MASK
Definition: ntfs.h:198
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:1985
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
Iosb Status
Definition: create.c:4287
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
DWORD Id
#define FRH_IN_USE
Definition: ntfs.h:267
Status
Definition: gdiplustypes.h:24
TCHAR Name[MAX_PATH]
Definition: filecomp.c:349
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define TAG_NTFS
Definition: ntfs.h:12
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
struct _FileName FileName
Definition: fatprocs.h:893
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1631
#define NULL
Definition: types.h:112
USHORT Flags
Definition: ntfs.h:256
#define DPRINT1
Definition: precomp.h:8
#define NRH_FILE_TYPE
Definition: ntfs.h:246
NTFS_RECORD_HEADER Ntfs
Definition: ntfs.h:252
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define DPRINT
Definition: sndvol32.h:71
#define NTFS_FILE_ROOT
Definition: ntfs.h:28

Referenced by NtfsCreateFile().

◆ NtfsOpenFile()

static NTSTATUS NtfsOpenFile ( PDEVICE_EXTENSION  DeviceExt,
PFILE_OBJECT  FileObject,
PWSTR  FileName,
BOOLEAN  CaseSensitive,
PNTFS_FCB FoundFCB 
)
static

Definition at line 242 of file create.c.

247 {
249  PNTFS_FCB Fcb;
251  PWSTR AbsFileName = NULL;
252 
253  DPRINT("NtfsOpenFile(%p, %p, %S, %s, %p)\n",
254  DeviceExt,
255  FileObject,
256  FileName,
257  CaseSensitive ? "TRUE" : "FALSE",
258  FoundFCB);
259 
260  *FoundFCB = NULL;
261 
262  if (FileObject->RelatedFileObject)
263  {
264  DPRINT("Converting relative filename to absolute filename\n");
265 
266  Status = NtfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
267  FileName,
268  &AbsFileName);
269  if (AbsFileName) FileName = AbsFileName;
270  if (!NT_SUCCESS(Status))
271  {
272  return Status;
273  }
274  }
275 
276  //FIXME: Get canonical path name (remove .'s, ..'s and extra separators)
277 
278  DPRINT("PathName to open: %S\n", FileName);
279 
280  /* try first to find an existing FCB in memory */
281  DPRINT("Checking for existing FCB in memory\n");
282  Fcb = NtfsGrabFCBFromTable(DeviceExt,
283  FileName);
284  if (Fcb == NULL)
285  {
286  DPRINT("No existing FCB found, making a new one if file exists.\n");
287  Status = NtfsGetFCBForFile(DeviceExt,
288  &ParentFcb,
289  &Fcb,
290  FileName,
291  CaseSensitive);
292  if (ParentFcb != NULL)
293  {
294  NtfsReleaseFCB(DeviceExt,
295  ParentFcb);
296  }
297 
298  if (!NT_SUCCESS(Status))
299  {
300  DPRINT("Could not make a new FCB, status: %x\n", Status);
301 
302  if (AbsFileName)
303  ExFreePoolWithTag(AbsFileName, TAG_NTFS);
304 
305  return Status;
306  }
307  }
308 
309  DPRINT("Attaching FCB to fileObject\n");
310  Status = NtfsAttachFCBToFileObject(DeviceExt,
311  Fcb,
312  FileObject);
313 
314  if (AbsFileName)
315  ExFreePool(AbsFileName);
316 
317  *FoundFCB = Fcb;
318 
319  return Status;
320 }
VOID NtfsReleaseFCB(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:177
Iosb Status
Definition: create.c:4287
Definition: cdstruc.h:902
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
PNTFS_FCB NtfsGrabFCBFromTable(PNTFS_VCB Vcb, PCWSTR FileName)
Definition: fcb.c:217
NTSTATUS NtfsAttachFCBToFileObject(PNTFS_VCB Vcb, PNTFS_FCB Fcb, PFILE_OBJECT FileObject)
Definition: fcb.c:459
static NTSTATUS NtfsMakeAbsoluteFilename(PFILE_OBJECT pFileObject, PWSTR pRelativeFileName, PWSTR *pAbsoluteFilename)
Definition: create.c:53
NTSTATUS NtfsGetFCBForFile(PNTFS_VCB Vcb, PNTFS_FCB *pParentFCB, PNTFS_FCB *pFCB, PCWSTR pFileName, BOOLEAN CaseSensitive)
Definition: fcb.c:598
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
#define TAG_NTFS
Definition: ntfs.h:12
#define NULL
Definition: types.h:112
#define DPRINT
Definition: sndvol32.h:71
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by NtfsCreateFile().

◆ NtfsOpenFileById()

static NTSTATUS NtfsOpenFileById ( PDEVICE_EXTENSION  DeviceExt,
PFILE_OBJECT  FileObject,
ULONGLONG  MftId,
PNTFS_FCB FoundFCB 
)
static

Definition at line 175 of file create.c.

179 {
181  PNTFS_FCB FCB;
182  PFILE_RECORD_HEADER MftRecord;
183 
184  DPRINT("NtfsOpenFileById(%p, %p, %I64x, %p)\n", DeviceExt, FileObject, MftId, FoundFCB);
185 
187  if (MftId > 0xb) /* No entries are used yet beyond this */
188  {
190  }
191 
192  MftRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
193  if (MftRecord == NULL)
194  {
196  }
197 
198  Status = ReadFileRecord(DeviceExt, MftId, MftRecord);
199  if (!NT_SUCCESS(Status))
200  {
201  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, MftRecord);
202  return Status;
203  }
204 
205  if (!(MftRecord->Flags & FRH_IN_USE))
206  {
207  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, MftRecord);
209  }
210 
211  FCB = NtfsGrabFCBFromTable(DeviceExt, MftIdToName[MftId]);
212  if (FCB == NULL)
213  {
215 
217  Status = NtfsMakeFCBFromDirEntry(DeviceExt, NULL, &Name, NULL, MftRecord, MftId, &FCB);
218  if (!NT_SUCCESS(Status))
219  {
220  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, MftRecord);
221  return Status;
222  }
223  }
224 
225  ASSERT(FCB != NULL);
226 
227  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, MftRecord);
228 
229  Status = NtfsAttachFCBToFileObject(DeviceExt,
230  FCB,
231  FileObject);
232  *FoundFCB = FCB;
233 
234  return Status;
235 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Iosb Status
Definition: create.c:4287
Definition: cdstruc.h:902
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb, PNTFS_FCB DirectoryFCB, PUNICODE_STRING Name, PCWSTR Stream, PFILE_RECORD_HEADER Record, ULONGLONG MFTIndex, PNTFS_FCB *fileFCB)
Definition: fcb.c:384
PNTFS_FCB NtfsGrabFCBFromTable(PNTFS_VCB Vcb, PCWSTR FileName)
Definition: fcb.c:217
NTSTATUS NtfsAttachFCBToFileObject(PNTFS_VCB Vcb, PNTFS_FCB Fcb, PFILE_OBJECT FileObject)
Definition: fcb.c:459
#define FRH_IN_USE
Definition: ntfs.h:267
struct NameRec_ * Name
Definition: cdprocs.h:459
struct _FCB FCB
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NTFS_FILE_FIRST_USER_FILE
Definition: ntfs.h:196
static PCWSTR MftIdToName[]
Definition: create.c:34
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1631
#define NULL
Definition: types.h:112
USHORT Flags
Definition: ntfs.h:256
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DPRINT
Definition: sndvol32.h:71

Referenced by NtfsCreateFile().

Variable Documentation

◆ MftIdToName

PCWSTR MftIdToName[]
static
Initial value:
= {
L"$MFT",
L"$MFTMirr",
L"$LogFile",
L"$Volume",
L"AttrDef",
L".",
L"$Bitmap",
L"$Boot",
L"$BadClus",
L"$Quota",
L"$UpCase",
L"$Extended",
}
static const WCHAR L[]
Definition: oid.c:1250

Definition at line 34 of file create.c.

Referenced by NtfsOpenFileById().