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

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static PCWSTR NtfsGetNextPathElement (PCWSTR FileName)
 
static VOID NtfsWSubString (PWCHAR pTarget, PCWSTR pSource, size_t pLength)
 
PNTFS_FCB NtfsCreateFCB (PCWSTR FileName, PCWSTR Stream, PNTFS_VCB Vcb)
 
VOID NtfsDestroyFCB (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsDirectory (PNTFS_FCB Fcb)
 
BOOLEAN NTAPI NtfsIsRegularFileObject (_In_ PFILE_OBJECT FileObject)
 
BOOLEAN NtfsFCBIsReparsePoint (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsCompressed (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsEncrypted (PNTFS_FCB Fcb)
 
BOOLEAN NtfsFCBIsRoot (PNTFS_FCB Fcb)
 
VOID NtfsGrabFCB (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
VOID NtfsReleaseFCB (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
VOID NtfsAddFCBToTable (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
NtfsRemoveFCBFromTable

Takes the FCB of a deleted file or directory out of the table, so a later open of the same path goes to the disk instead of finding it. The FCB lives on until its last reference is released.

VOID NtfsRemoveFCBFromTable (_In_ PNTFS_VCB Vcb, _In_ PNTFS_FCB Fcb)
 
PNTFS_FCB NtfsGrabFCBFromTable (PNTFS_VCB Vcb, PCWSTR FileName)
 
NTSTATUS NtfsFCBInitializeCache (PNTFS_VCB Vcb, PNTFS_FCB Fcb)
 
PNTFS_FCB NtfsMakeRootFCB (PNTFS_VCB Vcb)
 
PNTFS_FCB NtfsOpenRootFCB (PNTFS_VCB Vcb)
 
NTSTATUS NtfsMakeFCBFromDirEntry (PNTFS_VCB Vcb, PNTFS_FCB DirectoryFCB, PUNICODE_STRING Name, PCWSTR Stream, PFILE_RECORD_HEADER Record, ULONGLONG MFTIndex, PNTFS_FCB *fileFCB)
 
NTSTATUS NtfsAttachFCBToFileObject (PNTFS_VCB Vcb, PNTFS_FCB Fcb, PFILE_OBJECT FileObject)
 
static NTSTATUS NtfsDirFindFile (PNTFS_VCB Vcb, PNTFS_FCB DirectoryFcb, PWSTR FileToFind, BOOLEAN CaseSensitive, PNTFS_FCB *FoundFCB)
 
NTSTATUS NtfsGetFCBForFile (PNTFS_VCB Vcb, PNTFS_FCB *pParentFCB, PNTFS_FCB *pFCB, PCWSTR pFileName, BOOLEAN CaseSensitive)
 
NTSTATUS NtfsReadFCBAttribute (PNTFS_VCB Vcb, PNTFS_FCB pFCB, ULONG Type, PCWSTR Name, ULONG NameLength, PVOID *Data)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 32 of file fcb.c.

Function Documentation

◆ NtfsAddFCBToTable()

VOID NtfsAddFCBToTable ( PNTFS_VCB  Vcb,
PNTFS_FCB  Fcb 
)

Definition at line 250 of file fcb.c.

252{
253 KIRQL oldIrql;
254
255 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
256 Fcb->Vcb = Vcb;
257 InsertTailList(&Vcb->FcbListHead, &Fcb->FcbListEntry);
258 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
259}
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define InsertTailList(ListHead, Entry)
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
#define Vcb
Definition: cdprocs.h:1415
PVCB Vcb
Definition: cdstruc.h:933
LIST_ENTRY FcbListEntry
Definition: ntfs.h:612

Referenced by NtfsMakeFCBFromDirEntry(), and NtfsMakeRootFCB().

◆ NtfsAttachFCBToFileObject()

NTSTATUS NtfsAttachFCBToFileObject ( PNTFS_VCB  Vcb,
PNTFS_FCB  Fcb,
PFILE_OBJECT  FileObject 
)

Definition at line 533 of file fcb.c.

536{
537 PNTFS_CCB newCCB;
538
540 if (newCCB == NULL)
541 {
543 }
544
545 RtlZeroMemory(newCCB, sizeof(NTFS_CCB));
546
547 newCCB->Identifier.Type = NTFS_TYPE_CCB;
548 newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB);
549
550 FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
551 FileObject->FsContext = Fcb;
552 FileObject->FsContext2 = newCCB;
553 newCCB->PtrFileObject = FileObject;
554 Fcb->Vcb = Vcb;
555
556 /* Directories are excluded: they have no $DATA to map, and a data section on one gives Mm
557 * pages to fault in that we can never satisfy. */
559 {
561 {
564 FALSE,
566 Fcb);
567 }
569 {
570 FileObject->FsContext2 = NULL;
571 ExFreePoolWithTag(newCCB, TAG_CCB);
572 return _SEH2_GetExceptionCode();
573 }
574 _SEH2_END;
575
577 }
578
579 //DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL);
580
581 return STATUS_SUCCESS;
582}
#define TAG_CCB
Definition: cdprocs.h:85
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
#define FCB_CACHE_INITIALIZED
Definition: ntfs.h:583
#define NTFS_TYPE_CCB
Definition: ntfs.h:88
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:144
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG Type
Definition: ntfs.h:96
ULONG Size
Definition: ntfs.h:97
Definition: ntfs.h:151
PFILE_OBJECT PtrFileObject
Definition: ntfs.h:154
NTFSIDENTIFIER Identifier
Definition: ntfs.h:152
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks
Definition: ntfs.h:176
ULONG Flags
Definition: ntfs.h:618
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:593
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:597
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by NtfsCreateFile(), NtfsOpenFile(), NtfsOpenFileById(), and NtfsOpenTargetDirectory().

◆ NtfsCreateFCB()

PNTFS_FCB NtfsCreateFCB ( PCWSTR  FileName,
PCWSTR  Stream,
PNTFS_VCB  Vcb 
)

Definition at line 67 of file fcb.c.

70{
72
73 ASSERT(Vcb);
74 ASSERT(Vcb->Identifier.Type == NTFS_TYPE_VCB);
75
76 Fcb = ExAllocateFromNPagedLookasideList(&NtfsGlobalData->FcbLookasideList);
77 if (Fcb == NULL)
78 {
79 return NULL;
80 }
81
82 RtlZeroMemory(Fcb, sizeof(NTFS_FCB));
83
86
87 Fcb->Vcb = Vcb;
88
89 if (FileName)
90 {
92 if (wcsrchr(Fcb->PathName, '\\') != 0)
93 {
95 }
96 else
97 {
99 }
100 }
101
102 if (Stream)
103 {
105 }
106 else
107 {
108 Fcb->Stream[0] = UNICODE_NULL;
109 }
110
114
117
118 /* NtfsFastIoCheckIfPossible decides per request */
120
121 return Fcb;
122}
#define wcsrchr
Definition: compat.h:16
#define NTFS_TYPE_VCB
Definition: ntfs.h:90
#define NTFS_TYPE_FCB
Definition: ntfs.h:89
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1266
@ FastIoIsQuestionable
Definition: fsrtltypes.h:242
#define ASSERT(a)
Definition: mode.c:44
static IStream Stream
Definition: htmldoc.c:1115
#define UNICODE_NULL
wcscpy
NPAGED_LOOKASIDE_LIST FcbLookasideList
Definition: ntfs.h:180
Definition: cdstruc.h:902
WCHAR Stream[MAX_PATH]
Definition: ntfs.h:602
ERESOURCE PagingIoResource
Definition: ntfs.h:606
NTFSIDENTIFIER Identifier
Definition: ntfs.h:595
WCHAR * ObjectName
Definition: ntfs.h:603
FILE_LOCK FileLock
Definition: fatstruc.h:1071
WCHAR PathName[MAX_PATH]
Definition: ntfs.h:604
ERESOURCE MainResource
Definition: ntfs.h:607

Referenced by NtfsGetVolumeData(), NtfsMakeFCBFromDirEntry(), NtfsMakeRootFCB(), and NtfsMountVolume().

◆ NtfsDestroyFCB()

VOID NtfsDestroyFCB ( PNTFS_FCB  Fcb)

Definition at line 126 of file fcb.c.

127{
128 ASSERT(Fcb);
130
131 /* The volume stream belongs to the VCB */
134
138
139 ExFreeToNPagedLookasideList(&NtfsGlobalData->FcbLookasideList, Fcb);
140}
#define FCB_IS_VOLUME_STREAM
Definition: ntfs.h:584
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1283
PFILE_OBJECT FileObject
Definition: ntfs.h:599
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by NtfsReleaseFCB().

◆ NtfsDirFindFile()

static NTSTATUS NtfsDirFindFile ( PNTFS_VCB  Vcb,
PNTFS_FCB  DirectoryFcb,
PWSTR  FileToFind,
BOOLEAN  CaseSensitive,
PNTFS_FCB *  FoundFCB 
)
static

Definition at line 586 of file fcb.c.

591{
593 ULONGLONG CurrentDir;
595 PFILE_RECORD_HEADER FileRecord;
596 ULONGLONG MFTIndex;
597 PWSTR Colon, OldColon;
598 PNTFS_ATTR_CONTEXT DataContext;
599 USHORT Length = 0;
600
601 DPRINT("NtfsDirFindFile(%p, %p, %S, %s, %p)\n",
602 Vcb,
603 DirectoryFcb,
604 FileToFind,
605 CaseSensitive ? "TRUE" : "FALSE",
606 FoundFCB);
607
608 *FoundFCB = NULL;
609 RtlInitUnicodeString(&File, FileToFind);
610 CurrentDir = DirectoryFcb->MFTIndex;
611
612 Colon = wcsrchr(FileToFind, L':');
613 if (Colon != NULL)
614 {
615 Length = File.Length;
616 File.Length = (Colon - FileToFind) * sizeof(WCHAR);
617
618 if (_wcsicmp(Colon + 1, L"$DATA") == 0)
619 {
620 OldColon = Colon;
621 Colon[0] = UNICODE_NULL;
622 Colon = wcsrchr(FileToFind, L':');
623 if (Colon != NULL)
624 {
625 Length = File.Length;
626 File.Length = (Colon - FileToFind) * sizeof(WCHAR);
627 }
628 else
629 {
630 Colon = OldColon;
631 Colon[0] = L':';
632 }
633 }
634
635 /* Skip colon */
636 ++Colon;
637 DPRINT("Will now look for file '%wZ' with stream '%S'\n", &File, Colon);
638 }
639
640 Status = NtfsLookupFileAt(Vcb, &File, CaseSensitive, &FileRecord, &MFTIndex, CurrentDir);
641 if (!NT_SUCCESS(Status))
642 {
643 return Status;
644 }
645
646 if (Length != 0)
647 {
648 File.Length = Length;
649 }
650
651 if ((FileRecord->Flags & FRH_DIRECTORY) && Colon != 0)
652 {
653 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, FileRecord);
655 }
656 else if (Colon != 0)
657 {
658 Status = FindAttribute(Vcb, FileRecord, AttributeData, Colon, wcslen(Colon), &DataContext, NULL);
659 if (!NT_SUCCESS(Status))
660 {
662 }
663 ReleaseAttributeContext(DataContext);
664 }
665
666 Status = NtfsMakeFCBFromDirEntry(Vcb, DirectoryFcb, &File, Colon, FileRecord, MFTIndex, FoundFCB);
667 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, FileRecord);
668
669 return Status;
670}
@ Colon
Definition: asmpp.cpp:48
LONG NTSTATUS
Definition: precomp.h:26
Definition: File.h:16
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
#define L(x)
Definition: resources.c:13
#define FRH_DIRECTORY
Definition: ntfs.h:299
@ AttributeData
Definition: ntfs.h:195
Status
Definition: gdiplustypes.h:24
NTSTATUS NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, BOOLEAN CaseSensitive, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex)
Definition: mft.c:4236
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
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
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:458
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT
Definition: sndvol32.h:73
ULONGLONG MFTIndex
Definition: ntfs.h:622
USHORT Flags
Definition: ntfs.h:287
uint16_t * PWSTR
Definition: typedefs.h:56
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by NtfsGetFCBForFile().

◆ NtfsFCBInitializeCache()

NTSTATUS NtfsFCBInitializeCache ( PNTFS_VCB  Vcb,
PNTFS_FCB  Fcb 
)

Definition at line 334 of file fcb.c.

336{
339 PNTFS_CCB newCCB;
340
341 FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice);
342
344 if (newCCB == NULL)
345 {
347 }
348
349 RtlZeroMemory(newCCB, sizeof(NTFS_CCB));
350
351 newCCB->Identifier.Type = NTFS_TYPE_CCB;
352 newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB);
353
354 FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
355 FileObject->FsContext = Fcb;
356 FileObject->FsContext2 = newCCB;
357 newCCB->PtrFileObject = FileObject;
359 Fcb->Vcb = Vcb;
360
363 {
366 FALSE,
368 Fcb);
369 }
371 {
372 FileObject->FsContext2 = NULL;
373 ExFreePoolWithTag(newCCB, TAG_CCB);
376 return _SEH2_GetExceptionCode();
377 }
378 _SEH2_END;
379
380 /* The FCB keeps its reference, tearing down the cache map would otherwise free the stream */
382
383 return Status;
384}
PFILE_OBJECT NTAPI IoCreateStreamFileObject(IN PFILE_OBJECT FileObject, IN PDEVICE_OBJECT DeviceObject)
Definition: file.c:3186
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by NtfsMakeFCBFromDirEntry(), and NtfsMakeRootFCB().

◆ NtfsFCBIsCompressed()

BOOLEAN NtfsFCBIsCompressed ( PNTFS_FCB  Fcb)

Definition at line 173 of file fcb.c.

174{
176}
#define NTFS_FILE_TYPE_COMPRESSED
Definition: ntfs.h:256
ULONG FileAttributes
Definition: ntfs.h:398
FILENAME_ATTRIBUTE Entry
Definition: ntfs.h:625

Referenced by NtfsCachedRead(), NtfsCachedWrite(), NtfsFastIoCheckIfPossible(), NtfsQueryDirectory(), NtfsReadFile(), and NtfsWriteFile().

◆ NtfsFCBIsDirectory()

◆ NtfsFCBIsEncrypted()

BOOLEAN NtfsFCBIsEncrypted ( PNTFS_FCB  Fcb)

Definition at line 179 of file fcb.c.

180{
182}
#define NTFS_FILE_TYPE_ENCRYPTED
Definition: ntfs.h:258

Referenced by NtfsCachedRead(), NtfsFastIoCheckIfPossible(), and NtfsReadFile().

◆ NtfsFCBIsReparsePoint()

BOOLEAN NtfsFCBIsReparsePoint ( PNTFS_FCB  Fcb)

Definition at line 166 of file fcb.c.

167{
169}
#define NTFS_FILE_TYPE_REPARSE
Definition: ntfs.h:255

Referenced by NtfsCreateFile().

◆ NtfsFCBIsRoot()

BOOLEAN NtfsFCBIsRoot ( PNTFS_FCB  Fcb)

Definition at line 185 of file fcb.c.

186{
187 return (wcscmp(Fcb->PathName, L"\\") == 0);
188}
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977

Referenced by NtfsBuildRenamePath(), NtfsMakeAbsoluteFilename(), NtfsMakeFCBFromDirEntry(), NtfsSetDispositionInformation(), and NtfsSetRenameInformation().

◆ NtfsGetFCBForFile()

NTSTATUS NtfsGetFCBForFile ( PNTFS_VCB  Vcb,
PNTFS_FCB *  pParentFCB,
PNTFS_FCB *  pFCB,
PCWSTR  pFileName,
BOOLEAN  CaseSensitive 
)

Definition at line 674 of file fcb.c.

679{
681 WCHAR pathName [MAX_PATH];
682 WCHAR elementName [MAX_PATH];
683 PCWSTR currentElement;
685 PNTFS_FCB parentFCB;
686
687 DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S', %s)\n",
688 Vcb,
689 pParentFCB,
690 pFCB,
691 pFileName,
692 CaseSensitive ? "TRUE" : "FALSE");
693
694 /* Dummy code */
695// FCB = NtfsOpenRootFCB(Vcb);
696// *pFCB = FCB;
697// *pParentFCB = NULL;
698
699#if 1
700 /* Trivial case, open of the root directory on volume */
701 if (pFileName[0] == L'\0' || wcscmp(pFileName, L"\\") == 0)
702 {
703 DPRINT("returning root FCB\n");
704
706 *pFCB = FCB;
707 *pParentFCB = NULL;
708
710 }
711 else
712 {
713 currentElement = pFileName + 1;
714 wcscpy (pathName, L"\\");
716 }
717
718 parentFCB = NULL;
719
720 /* Parse filename and check each path element for existence and access */
721 while (NtfsGetNextPathElement(currentElement) != 0)
722 {
723 /* Skip blank directory levels */
724 if ((NtfsGetNextPathElement(currentElement) - currentElement) == 0)
725 {
726 currentElement++;
727 continue;
728 }
729
730 DPRINT("Parsing, currentElement:%S\n", currentElement);
731 DPRINT(" parentFCB:%p FCB:%p\n", parentFCB, FCB);
732
733 /* Descend to next directory level */
734 if (parentFCB)
735 {
736 NtfsReleaseFCB(Vcb, parentFCB);
737 parentFCB = NULL;
738 }
739
740 /* fail if element in FCB is not a directory */
742 {
743 DPRINT("Element in requested path is not a directory\n");
744
746 FCB = 0;
747 *pParentFCB = NULL;
748 *pFCB = NULL;
749
751 }
752
753 parentFCB = FCB;
754
755 /* Extract next directory level into dirName */
756 NtfsWSubString(pathName,
757 pFileName,
758 NtfsGetNextPathElement(currentElement) - pFileName);
759 DPRINT(" pathName:%S\n", pathName);
760
761 FCB = NtfsGrabFCBFromTable(Vcb, pathName);
762 if (FCB == NULL)
763 {
764 NtfsWSubString(elementName,
765 currentElement,
766 NtfsGetNextPathElement(currentElement) - currentElement);
767 DPRINT(" elementName:%S\n", elementName);
768
769 Status = NtfsDirFindFile(Vcb, parentFCB, elementName, CaseSensitive, &FCB);
771 {
772 *pParentFCB = parentFCB;
773 *pFCB = NULL;
774 currentElement = NtfsGetNextPathElement(currentElement);
775 if (*currentElement == L'\0' || NtfsGetNextPathElement(currentElement + 1) == 0)
776 {
778 }
779 else
780 {
782 }
783 }
784 else if (!NT_SUCCESS(Status))
785 {
786 NtfsReleaseFCB(Vcb, parentFCB);
787 *pParentFCB = NULL;
788 *pFCB = NULL;
789
790 return Status;
791 }
792 }
793
794 currentElement = NtfsGetNextPathElement(currentElement);
795 }
796
797 *pParentFCB = parentFCB;
798 *pFCB = FCB;
799#endif
800
801 return STATUS_SUCCESS;
802}
struct _FCB FCB
#define MAX_PATH
Definition: compat.h:34
static VOID NtfsWSubString(PWCHAR pTarget, PCWSTR pSource, size_t pLength)
Definition: fcb.c:57
PNTFS_FCB NtfsGrabFCBFromTable(PNTFS_VCB Vcb, PCWSTR FileName)
Definition: fcb.c:291
static NTSTATUS NtfsDirFindFile(PNTFS_VCB Vcb, PNTFS_FCB DirectoryFcb, PWSTR FileToFind, BOOLEAN CaseSensitive, PNTFS_FCB *FoundFCB)
Definition: fcb.c:586
PNTFS_FCB NtfsOpenRootFCB(PNTFS_VCB Vcb)
Definition: fcb.c:443
VOID NtfsReleaseFCB(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:209
static PCWSTR NtfsGetNextPathElement(PCWSTR FileName)
Definition: fcb.c:39
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151

Referenced by NtfsOpenFile(), and NtfsOpenTargetDirectory().

◆ NtfsGetNextPathElement()

static PCWSTR NtfsGetNextPathElement ( PCWSTR  FileName)
static

Definition at line 39 of file fcb.c.

40{
41 if (*FileName == L'\0')
42 {
43 return NULL;
44 }
45
46 while (*FileName != L'\0' && *FileName != L'\\')
47 {
48 FileName++;
49 }
50
51 return FileName;
52}
struct _FileName FileName
Definition: fatprocs.h:897

Referenced by NtfsGetFCBForFile().

◆ NtfsGrabFCB()

VOID NtfsGrabFCB ( PNTFS_VCB  Vcb,
PNTFS_FCB  Fcb 
)

Definition at line 192 of file fcb.c.

194{
195 KIRQL oldIrql;
196
197 DPRINT("grabbing FCB at %p: %S, refCount:%d\n",
198 Fcb,
199 Fcb->PathName,
200 Fcb->RefCount);
201
202 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
203 Fcb->RefCount++;
204 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
205}
LONG RefCount
Definition: ntfs.h:617

Referenced by NtfsMakeRootFCB().

◆ NtfsGrabFCBFromTable()

PNTFS_FCB NtfsGrabFCBFromTable ( PNTFS_VCB  Vcb,
PCWSTR  FileName 
)

Definition at line 291 of file fcb.c.

293{
294 KIRQL oldIrql;
296 PLIST_ENTRY current_entry;
297
298 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
299
300 if (FileName == NULL || *FileName == 0)
301 {
302 DPRINT("Return FCB for stream file object\n");
303 Fcb = Vcb->StreamFileObject->FsContext;
304 Fcb->RefCount++;
305 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
306 return Fcb;
307 }
308
309 current_entry = Vcb->FcbListHead.Flink;
310 while (current_entry != &Vcb->FcbListHead)
311 {
312 Fcb = CONTAINING_RECORD(current_entry, NTFS_FCB, FcbListEntry);
313
314 DPRINT("Comparing '%S' and '%S'\n", FileName, Fcb->PathName);
315 if (_wcsicmp(FileName, Fcb->PathName) == 0)
316 {
317 Fcb->RefCount++;
318 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
319 return Fcb;
320 }
321
322 //FIXME: need to compare against short name in FCB here
323
324 current_entry = current_entry->Flink;
325 }
326
327 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
328
329 return NULL;
330}
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by NtfsClearRenameTarget(), NtfsGetFCBForFile(), NtfsOpenFile(), NtfsOpenFileById(), NtfsOpenRootFCB(), and NtfsOpenTargetDirectory().

◆ NtfsIsRegularFileObject()

BOOLEAN NTAPI NtfsIsRegularFileObject ( _In_ PFILE_OBJECT  FileObject)

Definition at line 153 of file fcb.c.

155{
156 PNTFS_FCB Fcb = (PNTFS_FCB)FileObject->FsContext;
157
159 return FALSE;
160
161 return !(Fcb->Flags & FCB_IS_VOLUME) && !NtfsFCBIsDirectory(Fcb);
162}
struct _FCB * PNTFS_FCB
#define FCB_IS_VOLUME
Definition: ntfs.h:585
if(dx< 0)
Definition: linetemp.h:194

Referenced by NtfsCleanup(), NtfsFastIoCheckIfPossible(), NtfsFastIoRead(), NtfsFastIoWrite(), NtfsFlushBuffers(), NtfsLockControl(), NtfsRead(), and NtfsWrite().

◆ NtfsMakeFCBFromDirEntry()

NTSTATUS NtfsMakeFCBFromDirEntry ( PNTFS_VCB  Vcb,
PNTFS_FCB  DirectoryFCB,
PUNICODE_STRING  Name,
PCWSTR  Stream,
PFILE_RECORD_HEADER  Record,
ULONGLONG  MFTIndex,
PNTFS_FCB *  fileFCB 
)

Definition at line 458 of file fcb.c.

465{
466 WCHAR pathName[MAX_PATH];
468 PSTANDARD_INFORMATION StdInfo;
469 PNTFS_FCB rcFCB;
470 ULONGLONG Size, AllocatedSize;
471
472 DPRINT("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p, %p)\n", Vcb, DirectoryFCB, Name, Stream, Record, fileFCB);
473
475 if (!FileName)
476 {
477 return STATUS_OBJECT_NAME_NOT_FOUND; // Not sure that's the best here
478 }
479
480 if (DirectoryFCB && Name)
481 {
482 if (Name->Buffer[0] != 0 && wcslen(DirectoryFCB->PathName) +
483 sizeof(WCHAR) + Name->Length / sizeof(WCHAR) > MAX_PATH)
484 {
486 }
487
488 wcscpy(pathName, DirectoryFCB->PathName);
489 if (!NtfsFCBIsRoot(DirectoryFCB))
490 {
491 wcscat(pathName, L"\\");
492 }
493 wcscat(pathName, Name->Buffer);
494 }
495 else
496 {
497 RtlCopyMemory(pathName, FileName->Name, FileName->NameLength * sizeof (WCHAR));
498 pathName[FileName->NameLength] = UNICODE_NULL;
499 }
500
501 Size = NtfsGetFileSize(Vcb, Record, (Stream ? Stream : L""), (Stream ? wcslen(Stream) : 0), &AllocatedSize);
502
503 rcFCB = NtfsCreateFCB(pathName, Stream, Vcb);
504 if (!rcFCB)
505 {
507 }
508
509 memcpy(&rcFCB->Entry, FileName, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
510 rcFCB->Entry.NameType = FileName->NameType;
511 rcFCB->RFCB.FileSize.QuadPart = Size;
513 rcFCB->RFCB.AllocationSize.QuadPart = AllocatedSize;
514
516 if (StdInfo != NULL)
517 {
518 rcFCB->Entry.FileAttributes |= StdInfo->FileAttribute;
519 }
520
522 rcFCB->RefCount = 1;
523 rcFCB->MFTIndex = MFTIndex;
524 rcFCB->LinkCount = Record->LinkCount;
525 NtfsAddFCBToTable(Vcb, rcFCB);
526 *fileFCB = rcFCB;
527
528 return STATUS_SUCCESS;
529}
LPWSTR Name
Definition: desk.c:124
PSTANDARD_INFORMATION GetStandardInformationFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:1970
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:2015
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONGLONG NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, PCWSTR Stream, ULONG StreamLength, PULONGLONG AllocatedSize)
Definition: dirctl.c:38
BOOLEAN NtfsFCBIsRoot(PNTFS_FCB Fcb)
Definition: fcb.c:185
NTSTATUS NtfsFCBInitializeCache(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:334
PNTFS_FCB NtfsCreateFCB(PCWSTR FileName, PCWSTR Stream, PNTFS_VCB Vcb)
Definition: fcb.c:67
VOID NtfsAddFCBToTable(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:250
wcscat
UCHAR NameType
Definition: ntfs.h:409
ULONG FileAttribute
Definition: ntfs.h:365
USHORT LinkCount
Definition: ntfs.h:623
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
TCHAR Name[MAX_PATH]
Definition: filecomp.c:349
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:320

Referenced by NtfsDirFindFile(), and NtfsOpenFileById().

◆ NtfsMakeRootFCB()

PNTFS_FCB NtfsMakeRootFCB ( PNTFS_VCB  Vcb)

Definition at line 388 of file fcb.c.

389{
391 PFILE_RECORD_HEADER MftRecord;
393
394 MftRecord = ExAllocateFromNPagedLookasideList(&Vcb->FileRecLookasideList);
395 if (MftRecord == NULL)
396 {
397 return NULL;
398 }
399
400 if (!NT_SUCCESS(ReadFileRecord(Vcb, NTFS_FILE_ROOT, MftRecord)))
401 {
402 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, MftRecord);
403 return NULL;
404 }
405
407 if (!FileName)
408 {
409 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, MftRecord);
410 return NULL;
411 }
412
413 Fcb = NtfsCreateFCB(L"\\", NULL, Vcb);
414 if (!Fcb)
415 {
416 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, MftRecord);
417 return NULL;
418 }
419
421 Fcb->Entry.NameType = FileName->NameType;
422 Fcb->Entry.NameLength = 0;
424 Fcb->RefCount = 1;
425 Fcb->DirIndex = 0;
426 Fcb->RFCB.FileSize.QuadPart = FileName->DataSize;
428 Fcb->RFCB.AllocationSize.QuadPart = FileName->AllocatedSize;
430 Fcb->LinkCount = MftRecord->LinkCount;
431
435
436 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, MftRecord);
437
438 return Fcb;
439}
#define NTFS_FILE_NAME_WIN32
Definition: ntfs.h:64
#define NTFS_FILE_ROOT
Definition: ntfs.h:28
PFILENAME_ATTRIBUTE GetFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, UCHAR NameType)
Definition: attrib.c:1839
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1936
VOID NtfsGrabFCB(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:192
UCHAR NameLength
Definition: ntfs.h:408
WCHAR Name[1]
Definition: ntfs.h:410
ULONG DirIndex
Definition: ntfs.h:615
USHORT LinkCount
Definition: ntfs.h:285

Referenced by NtfsOpenRootFCB().

◆ NtfsOpenRootFCB()

PNTFS_FCB NtfsOpenRootFCB ( PNTFS_VCB  Vcb)

Definition at line 443 of file fcb.c.

444{
446
448 if (Fcb == NULL)
449 {
451 }
452
453 return Fcb;
454}
PNTFS_FCB NtfsMakeRootFCB(PNTFS_VCB Vcb)
Definition: fcb.c:388

Referenced by NtfsGetFCBForFile().

◆ NtfsReadFCBAttribute()

NTSTATUS NtfsReadFCBAttribute ( PNTFS_VCB  Vcb,
PNTFS_FCB  pFCB,
ULONG  Type,
PCWSTR  Name,
ULONG  NameLength,
PVOID *  Data 
)

Definition at line 806 of file fcb.c.

812{
814 PFILE_RECORD_HEADER FileRecord;
815 PNTFS_ATTR_CONTEXT AttrCtxt;
816 ULONGLONG AttrLength;
817
818 FileRecord = ExAllocateFromNPagedLookasideList(&Vcb->FileRecLookasideList);
819 if (FileRecord == NULL)
820 {
822 }
823
824 Status = ReadFileRecord(Vcb, pFCB->MFTIndex, FileRecord);
825 if (!NT_SUCCESS(Status))
826 {
827 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, FileRecord);
828 return Status;
829 }
830
831 Status = FindAttribute(Vcb, FileRecord, Type, Name, NameLength, &AttrCtxt, NULL);
832 if (!NT_SUCCESS(Status))
833 {
834 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, FileRecord);
835 return Status;
836 }
837
838 AttrLength = AttributeDataLength(AttrCtxt->pRecord);
840 if (*Data == NULL)
841 {
842 ReleaseAttributeContext(AttrCtxt);
843 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, FileRecord);
845 }
846
847 ReadAttribute(Vcb, AttrCtxt, 0, *Data, AttrLength);
848
849 ReleaseAttributeContext(AttrCtxt);
850 ExFreeToNPagedLookasideList(&Vcb->FileRecLookasideList, FileRecord);
851
852 return STATUS_SUCCESS;
853}
Type
Definition: Type.h:7
#define TAG_NTFS
Definition: ntfs.h:12
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
ULONG ReadAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
Definition: mft.c:1625

Referenced by NtfsCreateFile().

◆ NtfsReleaseFCB()

VOID NtfsReleaseFCB ( PNTFS_VCB  Vcb,
PNTFS_FCB  Fcb 
)

Definition at line 209 of file fcb.c.

211{
212 KIRQL oldIrql;
213
214 DPRINT("releasing FCB at %p: %S, refCount:%d\n",
215 Fcb,
216 Fcb->PathName,
217 Fcb->RefCount);
218
219 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
220 Fcb->RefCount--;
221 if (Fcb->RefCount <= 0 && (!NtfsFCBIsDirectory(Fcb) || (Fcb->Flags & FCB_DELETED)))
222 {
223 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
224
226
229 {
230 DPRINT("Keeping FCB %p (%S): still mapped\n", Fcb, Fcb->PathName);
231 return;
232 }
233
234 /* A deleted FCB already left the table */
235 KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
236 if (!(Fcb->Flags & FCB_DELETED))
238 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
239
241 }
242 else
243 {
244 KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
245 }
246}
#define FCB_DELETED
Definition: ntfs.h:587
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
VOID NtfsDestroyFCB(PNTFS_FCB Fcb)
Definition: fcb.c:126

Referenced by NtfsClearRenameTarget(), NtfsCloseFile(), NtfsFlushVolumeFiles(), NtfsGetFCBForFile(), NtfsOpenFile(), and NtfsOpenTargetDirectory().

◆ NtfsRemoveFCBFromTable()

VOID NtfsRemoveFCBFromTable ( _In_ PNTFS_VCB  Vcb,
_In_ PNTFS_FCB  Fcb 
)

Definition at line 270 of file fcb.c.

273{
275
276 KeAcquireSpinLock(&Vcb->FcbListLock, &OldIrql);
277
278 /* FCB_DELETED tells NtfsReleaseFCB() the entry is already unlinked */
279 if (!(Fcb->Flags & FCB_DELETED))
280 {
284 }
285
286 KeReleaseSpinLock(&Vcb->FcbListLock, OldIrql);
287}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by NtfsCleanupFile().

◆ NtfsWSubString()

static VOID NtfsWSubString ( PWCHAR  pTarget,
PCWSTR  pSource,
size_t  pLength 
)
static

Definition at line 57 of file fcb.c.

60{
61 wcsncpy(pTarget, pSource, pLength);
62 pTarget[pLength] = L'\0';
63}
FxIoTarget * pTarget
Definition: fxdeviceapi.cpp:97
wcsncpy

Referenced by NtfsGetFCBForFile().