[NTFS]
[reactos.git] / drivers / filesystems / ntfs / ntfs.h
index bb72e01..29a6c2a 100644 (file)
@@ -2,6 +2,13 @@
 #define NTFS_H
 
 #include <ntifs.h>
+#include <pseh/pseh2.h>
+
+#ifdef __GNUC__
+#define INIT_SECTION __attribute__((section ("INIT")))
+#else
+#define INIT_SECTION /* Done via alloc_text for MSC */
+#endif
 
 #define CACHEPAGESIZE(pDeviceExt) \
        ((pDeviceExt)->NtfsInfo.UCHARsPerCluster > PAGE_SIZE ? \
@@ -61,6 +68,7 @@ typedef struct _NTFS_INFO
     ULONG SectorsPerCluster;
     ULONG BytesPerCluster;
     ULONGLONG SectorCount;
+    ULONGLONG ClusterCount;
     ULARGE_INTEGER MftStart;
     ULARGE_INTEGER MftMirrStart;
     ULONG BytesPerFileRecord;
@@ -73,12 +81,13 @@ typedef struct _NTFS_INFO
     UCHAR MinorVersion;
     USHORT Flags;
 
+    ULONG MftZoneReservation;
 } NTFS_INFO, *PNTFS_INFO;
 
 #define NTFS_TYPE_CCB         '20SF'
 #define NTFS_TYPE_FCB         '30SF'
-#define        NTFS_TYPE_VCB         '50SF'
-#define NTFS_TYPE_IRP_CONTEST '60SF'
+#define NTFS_TYPE_VCB         '50SF'
+#define NTFS_TYPE_IRP_CONTEXT '60SF'
 #define NTFS_TYPE_GLOBAL_DATA '70SF'
 
 typedef struct
@@ -107,8 +116,13 @@ typedef struct
 
     NTFS_INFO NtfsInfo;
 
+    ULONG Flags;
+    ULONG OpenHandleCount;
+
 } DEVICE_EXTENSION, *PDEVICE_EXTENSION, NTFS_VCB, *PNTFS_VCB;
 
+#define VCB_VOLUME_LOCKED       0x0001
+
 typedef struct
 {
     NTFSIDENTIFIER Identifier;
@@ -124,6 +138,7 @@ typedef struct
 } NTFS_CCB, *PNTFS_CCB;
 
 #define TAG_CCB 'BCCI'
+#define TAG_FCB 'BCFI'
 
 typedef struct
 {
@@ -133,6 +148,9 @@ typedef struct
     PDEVICE_OBJECT DeviceObject;
     CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
     ULONG Flags;
+    FAST_IO_DISPATCH FastIoDispatch;
+    NPAGED_LOOKASIDE_LIST IrpContextLookasideList;
+    NPAGED_LOOKASIDE_LIST FcbLookasideList;
 } NTFS_GLOBAL_DATA, *PNTFS_GLOBAL_DATA;
 
 
@@ -157,6 +175,10 @@ typedef enum
     AttributeEnd = 0xFFFFFFFF
 } ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
 
+// FILE_RECORD_END seems to follow AttributeEnd in every file record starting with $Quota.
+// No clue what data is being represented here.
+#define FILE_RECORD_END              0x11477982 
+
 #define NTFS_FILE_MFT                0
 #define NTFS_FILE_MFTMIRR            1
 #define NTFS_FILE_LOGFILE            2
@@ -223,7 +245,7 @@ typedef struct _FILE_RECORD_HEADER
     ULONG BytesAllocated;         /* Allocated size of the FILE record */
     ULONGLONG BaseFileRecord;     /* File reference to the base FILE record */
     USHORT NextAttributeNumber;   /* Next Attribute Id */
-    USHORT Pading;                /* Align to 4 UCHAR boundary (XP) */
+    USHORT Padding;               /* Align to 4 UCHAR boundary (XP) */
     ULONG MFTRecordNumber;        /* Number of this MFT Record (XP) */
 } FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;
 
@@ -387,17 +409,24 @@ typedef struct {
     UCHAR Data[1];
 } REPARSE_POINT_ATTRIBUTE, *PREPARSE_POINT_ATTRIBUTE;
 
+#define IRPCONTEXT_CANWAIT 0x1
+#define IRPCONTEXT_COMPLETE 0x2
+#define IRPCONTEXT_QUEUE 0x4
+
 typedef struct
 {
     NTFSIDENTIFIER Identifier;
     ULONG Flags;
+    PIO_STACK_LOCATION Stack;
     UCHAR MajorFunction;
     UCHAR MinorFunction;
     WORK_QUEUE_ITEM WorkQueueItem;
     PIRP Irp;
     BOOLEAN IsTopLevel;
     PDEVICE_OBJECT DeviceObject;
+    PFILE_OBJECT FileObject;
     NTSTATUS SavedExceptionCode;
+    CCHAR PriorityBoost;
 } NTFS_IRP_CONTEXT, *PNTFS_IRP_CONTEXT;
 
 typedef struct _NTFS_ATTR_CONTEXT
@@ -408,6 +437,7 @@ typedef struct _NTFS_ATTR_CONTEXT
     ULONGLONG            CacheRunLength;
     LONGLONG            CacheRunLastLCN;
     ULONGLONG            CacheRunCurrentOffset;
+    ULONGLONG           FileMFTIndex;
     NTFS_ATTR_RECORD    Record;
 } NTFS_ATTR_CONTEXT, *PNTFS_ATTR_CONTEXT;
 
@@ -426,6 +456,7 @@ typedef struct _FCB
     PFILE_OBJECT FileObject;
     PNTFS_VCB Vcb;
 
+    WCHAR Stream[MAX_PATH];
     WCHAR *ObjectName;         /* point on filename (250 chars max) in PathName */
     WCHAR PathName[MAX_PATH];  /* path+filename 260 max */
 
@@ -439,37 +470,126 @@ typedef struct _FCB
 
     LONG RefCount;
     ULONG Flags;
+    ULONG OpenHandleCount;
 
     ULONGLONG MFTIndex;
+    USHORT LinkCount;
 
     FILENAME_ATTRIBUTE Entry;
 
 } NTFS_FCB, *PNTFS_FCB;
 
+typedef struct _FIND_ATTR_CONTXT
+{
+    PDEVICE_EXTENSION Vcb;
+    BOOLEAN OnlyResident;
+    PNTFS_ATTR_RECORD FirstAttr;
+    PNTFS_ATTR_RECORD CurrAttr;
+    PNTFS_ATTR_RECORD LastAttr;
+    PNTFS_ATTR_RECORD NonResidentStart;
+    PNTFS_ATTR_RECORD NonResidentEnd;
+    ULONG Offset;
+} FIND_ATTR_CONTXT, *PFIND_ATTR_CONTXT;
+
+typedef struct
+{
+    USHORT USN;
+    USHORT Array[];
+} FIXUP_ARRAY, *PFIXUP_ARRAY;
+
 extern PNTFS_GLOBAL_DATA NtfsGlobalData;
 
-//int CdfsStrcmpi( wchar_t *str1, wchar_t *str2 );
-//void CdfsWstrcpy( wchar_t *str1, wchar_t *str2, int max );
+FORCEINLINE
+NTSTATUS
+NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
+{
+    PULONG Flags = &IrpContext->Flags;
+
+    *Flags &= ~IRPCONTEXT_COMPLETE;
+    *Flags |= IRPCONTEXT_QUEUE;
 
+    return STATUS_PENDING;
+}
 
 /* attrib.c */
 
 //VOID
 //NtfsDumpAttribute(PATTRIBUTE Attribute);
 
+NTSTATUS
+AddRun(PNTFS_VCB Vcb,
+       PNTFS_ATTR_CONTEXT AttrContext,
+       ULONG AttrOffset,
+       PFILE_RECORD_HEADER FileRecord,
+       ULONGLONG NextAssignedCluster,
+       ULONG RunLength);
+
+NTSTATUS
+ConvertDataRunsToLargeMCB(PUCHAR DataRun,
+                          PLARGE_MCB DataRunsMCB,
+                          PULONGLONG pNextVBN);
+
+NTSTATUS
+ConvertLargeMCBToDataRuns(PLARGE_MCB DataRunsMCB,
+                          PUCHAR RunBuffer,
+                          ULONG MaxBufferSize,
+                          PULONG UsedBufferSize);
+
 PUCHAR
 DecodeRun(PUCHAR DataRun,
           LONGLONG *DataRunOffset,
           ULONGLONG *DataRunLength);
 
 VOID
-NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord);
+NtfsDumpDataRuns(PVOID StartOfRun,
+                 ULONGLONG CurrentLCN);
+
+VOID
+NtfsDumpFileAttributes(PDEVICE_EXTENSION Vcb,
+                       PFILE_RECORD_HEADER FileRecord);
+
+PSTANDARD_INFORMATION
+GetStandardInformationFromRecord(PDEVICE_EXTENSION Vcb,
+                                 PFILE_RECORD_HEADER FileRecord);
 
 PFILENAME_ATTRIBUTE
-GetFileNameFromRecord(PFILE_RECORD_HEADER FileRecord, UCHAR NameType);
+GetFileNameFromRecord(PDEVICE_EXTENSION Vcb,
+                      PFILE_RECORD_HEADER FileRecord,
+                      UCHAR NameType);
+
+UCHAR
+GetPackedByteCount(LONGLONG NumberToPack,
+                   BOOLEAN IsSigned);
+
+NTSTATUS
+GetLastClusterInDataRun(PDEVICE_EXTENSION Vcb,
+                        PNTFS_ATTR_RECORD Attribute,
+                        PULONGLONG LastCluster);
 
 PFILENAME_ATTRIBUTE
-GetBestFileNameFromRecord(PFILE_RECORD_HEADER FileRecord);
+GetBestFileNameFromRecord(PDEVICE_EXTENSION Vcb,
+                          PFILE_RECORD_HEADER FileRecord);
+
+NTSTATUS
+FindFirstAttribute(PFIND_ATTR_CONTXT Context,
+                   PDEVICE_EXTENSION Vcb,
+                   PFILE_RECORD_HEADER FileRecord,
+                   BOOLEAN OnlyResident,
+                   PNTFS_ATTR_RECORD * Attribute);
+
+NTSTATUS
+FindNextAttribute(PFIND_ATTR_CONTXT Context,
+                  PNTFS_ATTR_RECORD * Attribute);
+
+VOID
+FindCloseAttribute(PFIND_ATTR_CONTXT Context);
+
+NTSTATUS
+FreeClusters(PNTFS_VCB Vcb,
+             PNTFS_ATTR_CONTEXT AttrContext,
+             ULONG AttrOffset,
+             PFILE_RECORD_HEADER FileRecord,
+             ULONG ClustersToFree);
 
 /* blockdev.c */
 
@@ -481,6 +601,13 @@ NtfsReadDisk(IN PDEVICE_OBJECT DeviceObject,
              IN OUT PUCHAR Buffer,
              IN BOOLEAN Override);
 
+NTSTATUS
+NtfsWriteDisk(IN PDEVICE_OBJECT DeviceObject,
+              IN LONGLONG StartingOffset,
+              IN ULONG Length,
+              IN ULONG SectorSize,
+              IN const PUCHAR Buffer);
+
 NTSTATUS
 NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
                 IN ULONG DiskSector,
@@ -499,32 +626,45 @@ NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
                     IN BOOLEAN Override);
 
 
+/* close.c */
+
+NTSTATUS
+NtfsCleanup(PNTFS_IRP_CONTEXT IrpContext);
+
+
 /* close.c */
 
 NTSTATUS
 NtfsCloseFile(PDEVICE_EXTENSION DeviceExt,
               PFILE_OBJECT FileObject);
 
-DRIVER_DISPATCH NtfsFsdClose;
-NTSTATUS NTAPI
-NtfsFsdClose(PDEVICE_OBJECT DeviceObject,
-             PIRP Irp);
+NTSTATUS
+NtfsClose(PNTFS_IRP_CONTEXT IrpContext);
 
 
 /* create.c */
 
-DRIVER_DISPATCH NtfsFsdCreate;
-NTSTATUS NTAPI
-NtfsFsdCreate(PDEVICE_OBJECT DeviceObject,
-              PIRP Irp);
+NTSTATUS
+NtfsCreate(PNTFS_IRP_CONTEXT IrpContext);
+
+
+/* devctl.c */
+
+NTSTATUS
+NtfsDeviceControl(PNTFS_IRP_CONTEXT IrpContext);
 
 
 /* dirctl.c */
 
-DRIVER_DISPATCH NtfsFsdDirectoryControl;
-NTSTATUS NTAPI
-NtfsFsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
-                        PIRP Irp);
+ULONGLONG
+NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt,
+                PFILE_RECORD_HEADER FileRecord,
+                PCWSTR Stream,
+                ULONG StreamLength,
+                PULONGLONG AllocatedSize);
+
+NTSTATUS
+NtfsDirectoryControl(PNTFS_IRP_CONTEXT IrpContext);
 
 
 /* dispatch.c */
@@ -551,11 +691,16 @@ NtfsAcqReadAhead(PVOID Context,
 VOID NTAPI
 NtfsRelReadAhead(PVOID Context);
 
+FAST_IO_CHECK_IF_POSSIBLE NtfsFastIoCheckIfPossible;
+FAST_IO_READ NtfsFastIoRead;
+FAST_IO_WRITE NtfsFastIoWrite;
+
 
 /* fcb.c */
 
 PNTFS_FCB
 NtfsCreateFCB(PCWSTR FileName,
+              PCWSTR Stream,
               PNTFS_VCB Vcb);
 
 VOID
@@ -564,6 +709,12 @@ NtfsDestroyFCB(PNTFS_FCB Fcb);
 BOOLEAN
 NtfsFCBIsDirectory(PNTFS_FCB Fcb);
 
+BOOLEAN
+NtfsFCBIsReparsePoint(PNTFS_FCB Fcb);
+
+BOOLEAN
+NtfsFCBIsCompressed(PNTFS_FCB Fcb);
+
 BOOLEAN
 NtfsFCBIsRoot(PNTFS_FCB Fcb);
 
@@ -604,24 +755,40 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
                   PNTFS_FCB *pFCB,
                   const PWSTR pFileName);
 
+NTSTATUS
+NtfsReadFCBAttribute(PNTFS_VCB Vcb,
+                     PNTFS_FCB pFCB,
+                     ULONG Type, 
+                     PCWSTR Name,
+                     ULONG NameLength,
+                     PVOID * Data);
+
+NTSTATUS
+NtfsMakeFCBFromDirEntry(PNTFS_VCB Vcb,
+                        PNTFS_FCB DirectoryFCB,
+                        PUNICODE_STRING Name,
+                        PCWSTR Stream,
+                        PFILE_RECORD_HEADER Record,
+                        ULONGLONG MFTIndex,
+                        PNTFS_FCB * fileFCB);
+
 
 /* finfo.c */
 
-DRIVER_DISPATCH NtfsFsdQueryInformation;
-NTSTATUS NTAPI
-NtfsFsdQueryInformation(PDEVICE_OBJECT DeviceObject,
-                        PIRP Irp);
+NTSTATUS
+NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext);
 
 
 /* fsctl.c */
 
-DRIVER_DISPATCH NtfsFsdFileSystemControl;
-NTSTATUS NTAPI
-NtfsFsdFileSystemControl(PDEVICE_OBJECT DeviceObject,
-                         PIRP Irp);
+NTSTATUS
+NtfsFileSystemControl(PNTFS_IRP_CONTEXT IrpContext);
 
 
 /* mft.c */
+PNTFS_ATTR_CONTEXT
+PrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord);
+
 VOID
 ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context);
 
@@ -632,24 +799,73 @@ ReadAttribute(PDEVICE_EXTENSION Vcb,
               PCHAR Buffer,
               ULONG Length);
 
+NTSTATUS
+WriteAttribute(PDEVICE_EXTENSION Vcb,
+               PNTFS_ATTR_CONTEXT Context,
+               ULONGLONG Offset,
+               const PUCHAR Buffer,
+               ULONG Length,
+               PULONG LengthWritten);
+
 ULONGLONG
 AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord);
 
-ULONG
+NTSTATUS
+SetAttributeDataLength(PFILE_OBJECT FileObject,
+                       PNTFS_FCB Fcb,
+                       PNTFS_ATTR_CONTEXT AttrContext,
+                       ULONG AttrOffset,
+                       PFILE_RECORD_HEADER FileRecord,
+                       PLARGE_INTEGER DataSize);
+
+ULONGLONG
 AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord);
 
+BOOLEAN
+CompareFileName(PUNICODE_STRING FileName,
+                PINDEX_ENTRY_ATTRIBUTE IndexEntry,
+                BOOLEAN DirSearch);
+
 NTSTATUS
 ReadFileRecord(PDEVICE_EXTENSION Vcb,
                ULONGLONG index,
                PFILE_RECORD_HEADER file);
 
+NTSTATUS
+UpdateIndexEntryFileNameSize(PDEVICE_EXTENSION Vcb,
+                             PFILE_RECORD_HEADER MftRecord,
+                             PCHAR IndexRecord,
+                             ULONG IndexBlockSize,
+                             PINDEX_ENTRY_ATTRIBUTE FirstEntry,
+                             PINDEX_ENTRY_ATTRIBUTE LastEntry,
+                             PUNICODE_STRING FileName,
+                             PULONG StartEntry,
+                             PULONG CurrentEntry,
+                             BOOLEAN DirSearch,
+                             ULONGLONG NewDataSize,
+                             ULONGLONG NewAllocatedSize);
+
+NTSTATUS
+UpdateFileNameRecord(PDEVICE_EXTENSION Vcb,
+                     ULONGLONG ParentMFTIndex,
+                     PUNICODE_STRING FileName,
+                     BOOLEAN DirSearch,
+                     ULONGLONG NewDataSize,
+                     ULONGLONG NewAllocationSize);
+
+NTSTATUS
+UpdateFileRecord(PDEVICE_EXTENSION Vcb,
+                 ULONGLONG index,
+                 PFILE_RECORD_HEADER file);
+
 NTSTATUS
 FindAttribute(PDEVICE_EXTENSION Vcb,
               PFILE_RECORD_HEADER MftRecord,
               ULONG Type,
               PCWSTR Name,
               ULONG NameLength,
-              PNTFS_ATTR_CONTEXT * AttrCtx);
+              PNTFS_ATTR_CONTEXT * AttrCtx,
+              PULONG Offset);
 
 VOID
 ReadVCN(PDEVICE_EXTENSION Vcb,
@@ -663,6 +879,10 @@ NTSTATUS
 FixupUpdateSequenceArray(PDEVICE_EXTENSION Vcb,
                          PNTFS_RECORD_HEADER Record);
 
+NTSTATUS
+AddFixupArray(PDEVICE_EXTENSION Vcb,
+              PNTFS_RECORD_HEADER Record);
+
 NTSTATUS
 ReadLCN(PDEVICE_EXTENSION Vcb,
         ULONGLONG lcn,
@@ -678,14 +898,12 @@ NTSTATUS
 NtfsLookupFile(PDEVICE_EXTENSION Vcb,
                PUNICODE_STRING PathName,
                PFILE_RECORD_HEADER *FileRecord,
-               PNTFS_ATTR_CONTEXT *DataContext,
                PULONGLONG MFTIndex);
 
 NTSTATUS
 NtfsLookupFileAt(PDEVICE_EXTENSION Vcb,
                  PUNICODE_STRING PathName,
                  PFILE_RECORD_HEADER *FileRecord,
-                 PNTFS_ATTR_CONTEXT *DataContext,
                  PULONGLONG MFTIndex,
                  ULONGLONG CurrentMFTIndex);
 
@@ -694,7 +912,6 @@ NtfsFindFileAt(PDEVICE_EXTENSION Vcb,
                PUNICODE_STRING SearchPattern,
                PULONG FirstEntry,
                PFILE_RECORD_HEADER *FileRecord,
-               PNTFS_ATTR_CONTEXT *DataContext,
                PULONGLONG MFTIndex,
                ULONGLONG CurrentMFTIndex);
 
@@ -707,6 +924,15 @@ PNTFS_IRP_CONTEXT
 NtfsAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
                        PIRP Irp);
 
+PVOID
+NtfsGetUserBuffer(PIRP Irp,
+                  BOOLEAN Paging);
+
+NTSTATUS
+NtfsLockUserBuffer(IN PIRP Irp,
+                   IN ULONG Length,
+                   IN LOCK_OPERATION Operation);
+
 #if 0
 BOOLEAN
 wstrcmpjoki(PWSTR s1, PWSTR s2);
@@ -724,19 +950,22 @@ NtfsFileFlagsToAttributes(ULONG NtfsAttributes,
 
 /* rw.c */
 
-DRIVER_DISPATCH NtfsFsdRead;
-NTSTATUS NTAPI
-NtfsFsdRead(PDEVICE_OBJECT DeviceObject,
-            PIRP Irp);
+NTSTATUS
+NtfsRead(PNTFS_IRP_CONTEXT IrpContext);
 
-DRIVER_DISPATCH NtfsFsdWrite;
-NTSTATUS NTAPI
-NtfsFsdWrite(PDEVICE_OBJECT DeviceObject,
-             PIRP Irp);
+NTSTATUS
+NtfsWrite(PNTFS_IRP_CONTEXT IrpContext);
 
 
 /* volinfo.c */
 
+NTSTATUS
+NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt,
+                     ULONG FirstDesiredCluster,
+                     ULONG DesiredClusters,
+                     PULONG FirstAssignedCluster,
+                     PULONG AssignedClusters);
+
 ULONGLONG
 NtfsGetFreeClusters(PDEVICE_EXTENSION DeviceExt);