[ros-diffs] [arty] 44161: Untested implementation of large mcb (merging back).

arty at svn.reactos.org arty at svn.reactos.org
Sat Nov 14 19:00:32 CET 2009


Author: arty
Date: Sat Nov 14 19:00:32 2009
New Revision: 44161

URL: http://svn.reactos.org/svn/reactos?rev=44161&view=rev
Log:
Untested implementation of large mcb (merging back).

Modified:
    branches/pierre-fsd/include/ddk/ntifs.h
    branches/pierre-fsd/ntoskrnl/fsrtl/largemcb.c

Modified: branches/pierre-fsd/include/ddk/ntifs.h
URL: http://svn.reactos.org/svn/reactos/branches/pierre-fsd/include/ddk/ntifs.h?rev=44161&r1=44160&r2=44161&view=diff
==============================================================================
--- branches/pierre-fsd/include/ddk/ntifs.h [iso-8859-1] (original)
+++ branches/pierre-fsd/include/ddk/ntifs.h [iso-8859-1] Sat Nov 14 19:00:32 2009
@@ -25,7 +25,6 @@
 #define _GNU_NTIFS_
 
 #ifdef _NTOSKRNL_
-/* HACKHACKHACK!!! We shouldn't include this header from ntoskrnl! */
 #define NTKERNELAPI
 #else
 #define NTKERNELAPI DECLSPEC_IMPORT
@@ -44,13 +43,26 @@
 #define VER_PRODUCTBUILD 10000
 #endif
 
-#ifndef NTSYSAPI
-#define NTSYSAPI
-#endif
-
 #define EX_PUSH_LOCK ULONG_PTR
 #define PEX_PUSH_LOCK PULONG_PTR
 
+    
+#ifndef FlagOn
+#define FlagOn(_F,_SF)        ((_F) & (_SF))
+#endif
+    
+#ifndef BooleanFlagOn
+#define BooleanFlagOn(F,SF)   ((BOOLEAN)(((F) & (SF)) != 0))
+#endif
+    
+#ifndef SetFlag
+#define SetFlag(_F,_SF)       ((_F) |= (_SF))
+#endif
+    
+#ifndef ClearFlag
+#define ClearFlag(_F,_SF)     ((_F) &= ~(_SF))
+#endif
+    
 #include "csq.h"
 
 #ifdef _NTOSKRNL_
@@ -197,7 +209,10 @@
 #define FILE_SUPPORTS_OBJECT_IDS        0x00010000
 #define FILE_SUPPORTS_ENCRYPTION        0x00020000
 #define FILE_NAMED_STREAMS              0x00040000
-
+#define FILE_READ_ONLY_VOLUME           0x00080000
+#define FILE_SEQUENTIAL_WRITE_ONCE      0x00100000
+#define FILE_SUPPORTS_TRANSACTIONS      0x00200000
+    
 #define FILE_PIPE_BYTE_STREAM_TYPE      0x00000000
 #define FILE_PIPE_MESSAGE_TYPE          0x00000001
 
@@ -261,6 +276,7 @@
 #define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX (0x08)
 #define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH (0x10)
 #define FSRTL_FLAG_USER_MAPPED_FILE     (0x20)
+#define FSRTL_FLAG_ADVANCED_HEADER      (0x40)
 #define FSRTL_FLAG_EOF_ADVANCE_ACTIVE   (0x80)
 
 #define FSRTL_FLAG2_DO_MODIFIED_WRITE        (0x01)
@@ -317,8 +333,6 @@
 
 #define MAILSLOT_SIZE_AUTO              0
 
-#define MAP_PROCESS                     1L
-#define MAP_SYSTEM                      2L
 #define MEM_DOS_LIM                     0x40000000
 
 #define MCB_FLAG_RAISE_ON_ALLOCATION_FAILURE 1
@@ -933,10 +947,10 @@
     UCHAR Revision;
     UCHAR Sbz1;
     SECURITY_DESCRIPTOR_CONTROL Control;
-    DWORD_PTR Owner;
-    DWORD_PTR Group;
-    DWORD_PTR Sacl;
-    DWORD_PTR Dacl;
+    ULONG Owner;
+    ULONG Group;
+    ULONG Sacl;
+    ULONG Dacl;
 } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
 typedef enum _TOKEN_INFORMATION_CLASS {
 	TokenUser=1,TokenGroups,TokenPrivileges,TokenOwner,
@@ -1025,24 +1039,6 @@
     WCHAR           FileName[1];
 } FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
 
-typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
-    ULONG           NextEntryOffset;
-    ULONG           FileIndex;
-    LARGE_INTEGER   CreationTime;
-    LARGE_INTEGER   LastAccessTime;
-    LARGE_INTEGER   LastWriteTime;
-    LARGE_INTEGER   ChangeTime;
-    LARGE_INTEGER   EndOfFile;
-    LARGE_INTEGER   AllocationSize;
-    ULONG           FileAttributes;
-    ULONG           FileNameLength;
-    ULONG           EaSize;
-    CCHAR           ShortNameLength;
-    WCHAR           ShortName[12];
-    LARGE_INTEGER   FileId;
-    WCHAR           FileName[1];
-} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
-
 typedef struct _FILE_COMPLETION_INFORMATION {
     HANDLE  Port;
     PVOID   Key;
@@ -1090,8 +1086,42 @@
     ULONG           FileAttributes;
     ULONG           FileNameLength;
     ULONG           EaSize;
-    WCHAR           FileName[0];
+    WCHAR           FileName[ANYSIZE_ARRAY];
 } FILE_FULL_DIRECTORY_INFORMATION, *PFILE_FULL_DIRECTORY_INFORMATION;
+    
+typedef struct _FILE_ID_FULL_DIR_INFORMATION {
+    ULONG NextEntryOffset;
+    ULONG FileIndex;
+    LARGE_INTEGER CreationTime;
+    LARGE_INTEGER LastAccessTime;
+    LARGE_INTEGER LastWriteTime;
+    LARGE_INTEGER ChangeTime;
+    LARGE_INTEGER EndOfFile;
+    LARGE_INTEGER AllocationSize;
+    ULONG FileAttributes;
+    ULONG FileNameLength;
+    ULONG EaSize;
+    LARGE_INTEGER FileId;
+    WCHAR FileName[1];
+} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
+
+typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
+    ULONG NextEntryOffset;
+    ULONG FileIndex;
+    LARGE_INTEGER CreationTime;
+    LARGE_INTEGER LastAccessTime;
+    LARGE_INTEGER LastWriteTime;
+    LARGE_INTEGER ChangeTime;
+    LARGE_INTEGER EndOfFile;
+    LARGE_INTEGER AllocationSize;
+    ULONG FileAttributes;
+    ULONG FileNameLength;
+    ULONG EaSize;
+    CCHAR ShortNameLength;
+    WCHAR ShortName[12];
+    LARGE_INTEGER FileId;
+    WCHAR FileName[1];
+} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;
 
 typedef struct _FILE_EA_INFORMATION {
     ULONG EaSize;
@@ -1177,22 +1207,6 @@
     ULONG           EaSize;
     WCHAR           FileName[1];
 } FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;
-
-typedef struct _FILE_ID_FULL_DIR_INFORMATION {
-    ULONG           NextEntryOffset;
-    ULONG           FileIndex;
-    LARGE_INTEGER   CreationTime;
-    LARGE_INTEGER   LastAccessTime;
-    LARGE_INTEGER   LastWriteTime;
-    LARGE_INTEGER   ChangeTime;
-    LARGE_INTEGER   EndOfFile;
-    LARGE_INTEGER   AllocationSize;
-    ULONG           FileAttributes;
-    ULONG           FileNameLength;
-    ULONG           EaSize;
-    LARGE_INTEGER   FileId;
-    WCHAR           FileName[1];
-} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;
 
 typedef struct _FILE_GET_EA_INFORMATION {
     ULONG   NextEntryOffset;
@@ -1503,6 +1517,10 @@
 } FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
 #endif /* (VER_PRODUCTBUILD >= 2195) */
 
+#define FSRTL_FCB_HEADER_V0             (0x00)
+#define FSRTL_FCB_HEADER_V1             (0x01)
+
+
 typedef struct _FSRTL_COMMON_FCB_HEADER {
     CSHORT          NodeTypeCode;
     CSHORT          NodeByteSize;
@@ -1519,6 +1537,13 @@
     LARGE_INTEGER   ValidDataLength;
 } FSRTL_COMMON_FCB_HEADER, *PFSRTL_COMMON_FCB_HEADER;
 
+typedef enum _FSRTL_COMPARISON_RESULT
+{
+    LessThan = -1,
+    EqualTo = 0,
+    GreaterThan = 1
+} FSRTL_COMPARISON_RESULT;
+    
 #if (VER_PRODUCTBUILD >= 2600)
 
 typedef struct _FSRTL_ADVANCED_FCB_HEADER {
@@ -1897,6 +1922,63 @@
     PRTL_AVL_FREE_ROUTINE FreeRoutine,
     PVOID TableContext
 );
+
+NTSYSAPI
+PVOID
+NTAPI
+RtlInsertElementGenericTableAvl (
+    PRTL_AVL_TABLE Table,
+    PVOID Buffer,
+    CLONG BufferSize,
+    PBOOLEAN NewElement OPTIONAL
+    );
+    
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlDeleteElementGenericTableAvl (
+    PRTL_AVL_TABLE Table,
+    PVOID Buffer
+    );
+    
+NTSYSAPI
+PVOID
+NTAPI
+RtlLookupElementGenericTableAvl (
+    PRTL_AVL_TABLE Table,
+    PVOID Buffer
+    );
+    
+NTSYSAPI
+PVOID
+NTAPI
+RtlEnumerateGenericTableWithoutSplayingAvl (
+    PRTL_AVL_TABLE Table,
+    PVOID *RestartKey
+    );
+
+NTSYSAPI
+PVOID
+NTAPI
+RtlEnumerateGenericTableAvl (
+    PRTL_AVL_TABLE Table,
+	BOOLEAN Reset
+    );
+
+NTSYSAPI
+ULONG
+NTAPI
+RtlNumberGenericTableElementsAvl (
+	PRTL_AVL_TABLE Table
+	);
+	
+NTSYSAPI
+PVOID
+NTAPI
+RtlGetElementGenericTableAvl (
+	PRTL_AVL_TABLE Table,
+	ULONG i
+	);
 
 #if defined(USE_LPC6432)
 #define LPC_CLIENT_ID CLIENT_ID64
@@ -2321,7 +2403,7 @@
     OUT PIO_STATUS_BLOCK        IoStatus OPTIONAL
 );
 
-typedef VOID (*PDIRTY_PAGE_ROUTINE) (
+typedef VOID (NTAPI *PDIRTY_PAGE_ROUTINE) (
     IN PFILE_OBJECT     FileObject,
     IN PLARGE_INTEGER   FileOffset,
     IN ULONG            Length,
@@ -2758,7 +2840,20 @@
 #endif
 #endif /* (VER_PRODUCTBUILD >= 2600) */
 
-#define FlagOn(x, f) ((x) & (f))
+
+#define FsRtlSetupAdvancedHeader( _advhdr, _fmutx )                         \
+{                                                                           \
+    SetFlag( (_advhdr)->Flags, FSRTL_FLAG_ADVANCED_HEADER );                \
+    SetFlag( (_advhdr)->Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS );     \
+    (_advhdr)->Version = FSRTL_FCB_HEADER_V1;                               \
+    InitializeListHead( &(_advhdr)->FilterContexts );                       \
+    if ((_fmutx) != NULL) {                                                 \
+        (_advhdr)->FastMutex = (_fmutx);                                    \
+    }                                                                       \
+    *((PULONG_PTR)(&(_advhdr)->PushLock)) = 0;                              \
+    /*ExInitializePushLock( &(_advhdr)->PushLock ); API Not avaliable downlevel*/\
+    (_advhdr)->FileContextSupportPointer = NULL;                            \
+}
 
 NTKERNELAPI
 BOOLEAN
@@ -3038,6 +3133,17 @@
     IN PUNICODE_STRING Name
 );
 
+NTKERNELAPI
+BOOLEAN
+NTAPI
+FsRtlIsFatDbcsLegal (
+    IN ANSI_STRING DbcsName,
+    IN BOOLEAN WildCardsPermissible,
+    IN BOOLEAN PathNamePermissible,
+    IN BOOLEAN LeadingBackslashPermissible
+    );
+
+
 #define FsRtlCompleteRequest(IRP,STATUS) {         \
     (IRP)->IoStatus.Status = (STATUS);             \
     IoCompleteRequest( (IRP), IO_DISK_INCREMENT ); \
@@ -3520,7 +3626,7 @@
     IN PVOID        FsContext
 );
 
-typedef BOOLEAN (*PCHECK_FOR_TRAVERSE_ACCESS) (
+typedef BOOLEAN (NTAPI *PCHECK_FOR_TRAVERSE_ACCESS) (
     IN PVOID                        NotifyContext,
     IN PVOID                        TargetContext,
     IN PSECURITY_SUBJECT_CONTEXT    SubjectContext
@@ -3593,17 +3699,6 @@
 NTAPI
 FsRtlNotifyInitializeSync (
     IN PNOTIFY_SYNC *NotifySync
-);
-
-NTKERNELAPI
-VOID
-NTAPI
-FsRtlNotifyReportChange (
-    IN PNOTIFY_SYNC NotifySync,
-    IN PLIST_ENTRY  NotifyList,
-    IN PSTRING      FullTargetName,
-    IN PUSHORT      FileNamePartLength,
-    IN ULONG        FilterMatch
 );
 
 NTKERNELAPI
@@ -3755,19 +3850,19 @@
 NTKERNELAPI
 BOOLEAN
 NTAPI
-FsRtlRemoveBaseMcbEntry (
-    IN PBASE_MCB  Mcb,
-    IN LONGLONG   Vbn,
-    IN LONGLONG   SectorCount
-);
-
-NTKERNELAPI
-VOID
-NTAPI
-FsRtlRemoveLargeMcbEntry (
-    IN PLARGE_MCB  Mcb,
-    IN LONGLONG    Vbn,
-    IN LONGLONG    SectorCount
+FsRtlRemoveBaseMcbEntry(
+	IN PBASE_MCB Mcb,
+	IN LONGLONG Vbn,
+	IN LONGLONG SectorCount
+);
+
+NTKERNELAPI
+VOID
+NTAPI
+FsRtlRemoveLargeMcbEntry(
+	IN PLARGE_MCB Mcb,
+	IN LONGLONG Vbn,
+	IN LONGLONG SectorCount
 );
 
 NTKERNELAPI
@@ -3884,13 +3979,6 @@
 NTAPI
 FsRtlUninitializeOplock (
     IN OUT POPLOCK Oplock
-);
-
-NTHALAPI
-VOID
-NTAPI
-HalDisplayString (
-    IN PCHAR String
 );
 
 NTKERNELAPI
@@ -4003,6 +4091,32 @@
 IoGetBaseFileSystemDeviceObject (
     IN PFILE_OBJECT FileObject
 );
+
+#if (VER_PRODUCTBUILD >= 2600)
+
+NTKERNELAPI
+PDEVICE_OBJECT
+NTAPI
+IoGetDeviceAttachmentBaseRef (
+    IN PDEVICE_OBJECT DeviceObject
+);
+
+NTKERNELAPI
+NTSTATUS
+NTAPI
+IoGetDiskDeviceObject (
+    IN PDEVICE_OBJECT   FileSystemDeviceObject,
+    OUT PDEVICE_OBJECT  *DiskDeviceObject
+);
+
+NTKERNELAPI
+PDEVICE_OBJECT
+NTAPI
+IoGetLowerDeviceObject (
+    IN PDEVICE_OBJECT DeviceObject
+);
+
+#endif /* (VER_PRODUCTBUILD >= 2600) */
 
 NTKERNELAPI
 PEPROCESS
@@ -4988,6 +5102,24 @@
 NTSYSAPI
 NTSTATUS
 NTAPI
+RtlOemStringToCountedUnicodeString(
+    IN OUT PUNICODE_STRING DestinationString,
+    IN PCOEM_STRING SourceString,
+    IN BOOLEAN AllocateDestinationString
+);
+    
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUnicodeStringToCountedOemString(
+    IN OUT POEM_STRING DestinationString,
+    IN PCUNICODE_STRING SourceString,
+    IN BOOLEAN AllocateDestinationString
+);
+    
+NTSYSAPI
+NTSTATUS
+NTAPI
 RtlReserveChunk (
     IN USHORT       CompressionFormat,
     IN OUT PUCHAR   *CompressedBuffer,
@@ -5065,6 +5197,17 @@
     OUT PULONG BytesInMultiByteString OPTIONAL,
     IN PWCH UnicodeString,
     IN ULONG BytesInUnicodeString
+);
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlOemToUnicodeN(
+    OUT PWSTR UnicodeString,
+    IN ULONG MaxBytesInUnicodeString,
+    OUT PULONG BytesInUnicodeString OPTIONAL,
+    IN PCH OemString,
+    IN ULONG BytesInOemString
 );
 
 /* RTL Splay Tree Functions */
@@ -5404,7 +5547,7 @@
     ((PSECURITY_SUBJECT_CONTEXT) SubjectContext)->ClientToken :     \
     ((PSECURITY_SUBJECT_CONTEXT) SubjectContext)->PrimaryToken )
 
-typedef NTSTATUS (*PSE_LOGON_SESSION_TERMINATED_ROUTINE) (
+typedef NTSTATUS (NTAPI *PSE_LOGON_SESSION_TERMINATED_ROUTINE) (
     IN PLUID LogonId
 );
 

Modified: branches/pierre-fsd/ntoskrnl/fsrtl/largemcb.c
URL: http://svn.reactos.org/svn/reactos/branches/pierre-fsd/ntoskrnl/fsrtl/largemcb.c?rev=44161&r1=44160&r2=44161&view=diff
==============================================================================
--- branches/pierre-fsd/ntoskrnl/fsrtl/largemcb.c [iso-8859-1] (original)
+++ branches/pierre-fsd/ntoskrnl/fsrtl/largemcb.c [iso-8859-1] Sat Nov 14 19:00:32 2009
@@ -5,6 +5,7 @@
  * PURPOSE:         Large Mapped Control Block (MCB) support for File System Drivers
  * PROGRAMMERS:     Alex Ionescu (alex.ionescu at reactos.org)
  *                  Pierre Schweitzer (heis_spiter at hotmail.com) 
+ *                  Art Yerkes (art.yerkes at gmail.com)
  */
 
 /* INCLUDES ******************************************************************/
@@ -15,13 +16,50 @@
 
 /* GLOBALS *******************************************************************/
 
+#define GET_LIST_HEAD(x) ((PLIST_ENTRY)(&((PRTL_GENERIC_TABLE)x)[1]))
+
 PAGED_LOOKASIDE_LIST FsRtlFirstMappingLookasideList;
 NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList;
 
+typedef struct _LARGE_MCB_MAPPING_ENTRY
+{
+	LARGE_INTEGER RunStartVbn;
+	LARGE_INTEGER SectorCount;
+	LARGE_INTEGER StartingLbn;
+	LIST_ENTRY Sequence;
+} LARGE_MCB_MAPPING_ENTRY, *PLARGE_MCB_MAPPING_ENTRY;
+
+static PVOID NTAPI McbMappingAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes)
+{
+	PVOID Result;
+	PBASE_MCB Mcb = (PBASE_MCB)Table->TableContext;
+	Result = ExAllocatePoolWithTag(Mcb->PoolType, Bytes, 'LMCB');
+	DPRINT("McbMappingAllocate(%d) => %p\n", Bytes, Result);
+	return Result;
+}
+
+static VOID NTAPI McbMappingFree(PRTL_GENERIC_TABLE Table, PVOID Buffer)
+{
+	DPRINT("McbMappingFree(%p)\n", Buffer);
+	ExFreePoolWithTag(Buffer, 'LMCB');
+}
+
+static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingCompare
+(RTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB)
+{
+	PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB;
+	return 
+		(A->RunStartVbn.QuadPart + A->SectorCount.QuadPart <
+		 B->RunStartVbn.QuadPart) ? GenericLessThan :
+		(A->RunStartVbn.QuadPart > 
+		 B->RunStartVbn.QuadPart + B->SectorCount.QuadPart) ? 
+		GenericGreaterThan : GenericEqual;
+}
+
 /* PUBLIC FUNCTIONS **********************************************************/
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOLEAN
 NTAPI
@@ -30,8 +68,59 @@
                      IN LONGLONG Lbn,
                      IN LONGLONG SectorCount)
 {
-    KeBugCheck(FILE_SYSTEM);
-    return FALSE;
+	LARGE_MCB_MAPPING_ENTRY Node;
+	PLARGE_MCB_MAPPING_ENTRY Existing = NULL;
+	BOOLEAN NewElement = FALSE;
+
+	Node.RunStartVbn.QuadPart = Vbn;
+	Node.StartingLbn.QuadPart = Lbn;
+	Node.SectorCount.QuadPart = SectorCount;
+
+	while (!NewElement)
+	{
+		Existing = RtlInsertElementGenericTable
+			(Mcb->Mapping, &Node, sizeof(Node), &NewElement);
+		if (!Existing) break;
+
+		if (!NewElement)
+		{
+			// We merge the existing runs
+			LARGE_INTEGER StartVbn, FinalVbn;
+			if (Existing->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart)
+			{
+				StartVbn = Existing->RunStartVbn;
+				Node.StartingLbn = Existing->StartingLbn;
+			}
+			else
+			{
+				StartVbn = Node.RunStartVbn;
+			}
+			if (Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart >
+				Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart)
+			{
+				FinalVbn.QuadPart = 
+					Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart;
+			}
+			else
+			{
+				FinalVbn.QuadPart =
+					Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart;
+			}
+			Node.RunStartVbn.QuadPart = StartVbn.QuadPart;
+			Node.SectorCount.QuadPart = FinalVbn.QuadPart - StartVbn.QuadPart;
+			RemoveHeadList(&Existing->Sequence);
+			RtlDeleteElementGenericTable(Mcb->Mapping, Existing);
+			Mcb->PairCount--;
+		}
+		else
+		{
+			Mcb->MaximumPairCount++;
+			Mcb->PairCount++;
+			InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Existing->Sequence);
+		}
+	}
+
+	return !!Existing;
 }
 
 /*
@@ -45,6 +134,8 @@
                       IN LONGLONG SectorCount)
 {
     BOOLEAN Result;
+
+	DPRINT1("Mcb %x Vbn %x Lbn %x SectorCount %x\n", Mcb, Vbn, Lbn, SectorCount);
 
     KeAcquireGuardedMutex(Mcb->GuardedMutex);
     Result = FsRtlAddBaseMcbEntry(&(Mcb->BaseMcb),
@@ -67,11 +158,26 @@
                          OUT PLONGLONG Lbn,
                          OUT PLONGLONG SectorCount)
 {
-    KeBugCheck(FILE_SYSTEM);
-    *Vbn = 0;
-    *Lbn = 0;
-    *SectorCount= 0;
-    return FALSE;
+	ULONG i = 0;
+	BOOLEAN Result = FALSE;
+	PLARGE_MCB_MAPPING_ENTRY Entry;
+	for (Entry = (PLARGE_MCB_MAPPING_ENTRY)
+			 RtlEnumerateGenericTable(Mcb->Mapping, TRUE);
+		 Entry && i < RunIndex;
+		 Entry = (PLARGE_MCB_MAPPING_ENTRY)
+			 RtlEnumerateGenericTable(Mcb->Mapping, FALSE), i++);
+	if (Entry)
+	{
+		Result = TRUE;
+		if (Vbn)
+			*Vbn = Entry->RunStartVbn.QuadPart;
+		if (Lbn)
+			*Lbn = Entry->StartingLbn.QuadPart;
+		if (SectorCount)
+			*SectorCount = Entry->SectorCount.QuadPart;
+	}
+
+	return Result;
 }
 
 /*
@@ -115,12 +221,19 @@
     else
     {
         Mcb->Mapping = ExAllocatePoolWithTag(PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE,
-                                             sizeof(INT_MAPPING) * MAXIMUM_PAIR_COUNT,
-                                             TAG('F', 'S', 'B', 'C'));
+											 sizeof(RTL_GENERIC_TABLE) + sizeof(LIST_ENTRY),
+                                             'FSBC');
     }
 
     Mcb->PoolType = PoolType;
     Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT;
+	RtlInitializeGenericTable
+		(Mcb->Mapping,
+		 (PRTL_GENERIC_COMPARE_ROUTINE)McbMappingCompare,
+		 McbMappingAllocate,
+		 McbMappingFree,
+		 Mcb);
+	InitializeListHead(GET_LIST_HEAD(Mcb->Mapping));
 }
 
 /*
@@ -160,7 +273,7 @@
                                    NULL,
                                    NULL,
                                    POOL_RAISE_IF_ALLOCATION_FAILURE,
-                                   sizeof(INT_MAPPING) * MAXIMUM_PAIR_COUNT,
+								   sizeof(RTL_GENERIC_TABLE) + sizeof(LIST_ENTRY),
                                    IFS_POOL_TAG,
                                    0); /* FIXME: Should be 4 */
 
@@ -187,10 +300,42 @@
                         OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL,
                         OUT PULONG Index OPTIONAL)
 {
-    KeBugCheck(FILE_SYSTEM);
-    *Lbn = 0;
-    *SectorCountFromLbn = 0;
-    return FALSE;
+	BOOLEAN Result = FALSE;
+	LARGE_MCB_MAPPING_ENTRY ToLookup;
+	PLARGE_MCB_MAPPING_ENTRY Entry;
+
+	ToLookup.RunStartVbn.QuadPart = Vbn;
+	ToLookup.SectorCount.QuadPart = 1;
+
+	Entry = RtlLookupElementGenericTable(Mcb->Mapping, &ToLookup);
+	if (!Entry)
+	{
+		// Find out if we have a following entry.  The spec says we should return
+		// found with Lbn == -1 when we're beneath the largest map.
+		ToLookup.SectorCount.QuadPart = (1ull<<62) - ToLookup.RunStartVbn.QuadPart;
+		Entry = RtlLookupElementGenericTable(Mcb->Mapping, &ToLookup);
+		if (Entry)
+		{
+			Result = TRUE;
+			if (Lbn) *Lbn = ~0ull;
+		}
+		else
+		{
+			Result = FALSE;
+		}
+	}
+	else
+	{
+		LARGE_INTEGER Offset;
+		Offset.QuadPart = Vbn - Entry->RunStartVbn.QuadPart;
+		Result = TRUE;
+		if (Lbn) *Lbn = Entry->StartingLbn.QuadPart + Offset.QuadPart;
+		if (SectorCountFromLbn) *SectorCountFromLbn = Entry->SectorCount.QuadPart - Offset.QuadPart;
+		if (StartingLbn) *StartingLbn = Entry->StartingLbn.QuadPart;
+		if (SectorCountFromStartingLbn) *SectorCountFromStartingLbn = Entry->SectorCount.QuadPart;
+	}
+	
+    return Result;
 }
 
 /*
@@ -231,11 +376,28 @@
                                     IN OUT PLONGLONG LargeLbn,
                                     IN OUT PULONG Index)
 {
-    KeBugCheck(FILE_SYSTEM);
-    *LargeVbn = 0;
-    *LargeLbn = 0;
-    *Index = 0;
-    return FALSE;
+	ULONG i = 0;
+	BOOLEAN Result = FALSE;
+	PLIST_ENTRY ListEntry;
+	PLARGE_MCB_MAPPING_ENTRY Entry;
+	PLARGE_MCB_MAPPING_ENTRY CountEntry;
+
+	ListEntry = GET_LIST_HEAD(OpaqueMcb->Mapping);
+	if (!IsListEmpty(ListEntry))
+	{
+		Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence);
+		Result = TRUE;
+		*LargeVbn = Entry->RunStartVbn.QuadPart;
+		*LargeLbn = Entry->StartingLbn.QuadPart;
+
+		for (i = 0, CountEntry = RtlEnumerateGenericTable(OpaqueMcb->Mapping, TRUE);
+			 CountEntry != Entry;
+			 CountEntry = RtlEnumerateGenericTable(OpaqueMcb->Mapping, FALSE));
+
+		*Index = i;
+	}
+
+	return Result;
 }
 
 /*
@@ -269,8 +431,20 @@
                             OUT PLONGLONG Vbn,
                             OUT PLONGLONG Lbn)
 {
-    KeBugCheck(FILE_SYSTEM);
-    return FALSE;
+	BOOLEAN Result = FALSE;
+	PLIST_ENTRY ListEntry;
+	PLARGE_MCB_MAPPING_ENTRY Entry;
+
+	ListEntry = GET_LIST_HEAD(Mcb->Mapping);
+	if (!IsListEmpty(ListEntry))
+	{
+		Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence);
+		Result = TRUE;
+		*Vbn = Entry->RunStartVbn.QuadPart;
+		*Lbn = Entry->StartingLbn.QuadPart;
+	}
+	
+	return Result;
 }
 
 /*
@@ -331,8 +505,90 @@
                         IN LONGLONG Vbn,
                         IN LONGLONG SectorCount)
 {
-    KeBugCheck(FILE_SYSTEM);
-    return FALSE;
+	LARGE_MCB_MAPPING_ENTRY Node;
+	PLARGE_MCB_MAPPING_ENTRY Element;
+
+	Node.RunStartVbn.QuadPart = Vbn;
+	Node.SectorCount.QuadPart = SectorCount;
+
+	while ((Element = RtlLookupElementGenericTable(Mcb->Mapping, &Node)))
+	{
+		// Must split
+		if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart &&
+			Element->SectorCount.QuadPart > Node.SectorCount.QuadPart)
+		{
+			LARGE_MCB_MAPPING_ENTRY Upper, Reinsert;
+			PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted;
+			LARGE_INTEGER StartHole = Node.RunStartVbn;
+			LARGE_INTEGER EndHole;
+			EndHole.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart;
+			Upper.RunStartVbn.QuadPart = EndHole.QuadPart;
+			Upper.StartingLbn.QuadPart = 
+				Element->StartingLbn.QuadPart + 
+				EndHole.QuadPart - 
+				Element->RunStartVbn.QuadPart;
+			Upper.SectorCount.QuadPart = 
+				Element->SectorCount.QuadPart -
+				(EndHole.QuadPart - Element->RunStartVbn.QuadPart);
+			Reinsert = *Element;
+			Reinsert.SectorCount.QuadPart = 
+				Element->RunStartVbn.QuadPart - StartHole.QuadPart;
+			RemoveEntryList(&Element->Sequence);
+			RtlDeleteElementGenericTable(Mcb->Mapping, Element);
+			Mcb->PairCount--;
+
+			Reinserted = RtlInsertElementGenericTable
+				(Mcb->Mapping, &Reinsert, sizeof(Reinsert), NULL);
+			InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence);
+			Mcb->PairCount++;
+			
+			Inserted = RtlInsertElementGenericTable
+				(Mcb->Mapping, &Upper, sizeof(Upper), NULL);
+			InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Inserted->Sequence);
+			Mcb->PairCount++;
+		}
+		else if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart)
+		{
+			LARGE_MCB_MAPPING_ENTRY NewElement;
+			PLARGE_MCB_MAPPING_ENTRY Reinserted;
+			LARGE_INTEGER StartHole = Node.RunStartVbn;
+			NewElement.RunStartVbn = Element->RunStartVbn;
+			NewElement.StartingLbn = Element->StartingLbn;
+			NewElement.SectorCount.QuadPart = StartHole.QuadPart - Element->StartingLbn.QuadPart;
+
+			RemoveEntryList(&Element->Sequence);
+			RtlDeleteElementGenericTable(Mcb->Mapping, Element);
+			Mcb->PairCount--;
+			
+			Reinserted = RtlInsertElementGenericTable
+				(Mcb->Mapping, &NewElement, sizeof(NewElement), NULL);
+			InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence);
+			Mcb->PairCount++;			
+		}
+		else
+		{
+			LARGE_MCB_MAPPING_ENTRY NewElement;
+			PLARGE_MCB_MAPPING_ENTRY Reinserted;
+			LARGE_INTEGER EndHole = Element->RunStartVbn;
+			LARGE_INTEGER EndRun;
+			EndRun.QuadPart = Element->RunStartVbn.QuadPart + Element->SectorCount.QuadPart;
+			NewElement.RunStartVbn = EndHole;
+			NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + 
+				(EndHole.QuadPart - Element->RunStartVbn.QuadPart);
+			NewElement.SectorCount.QuadPart = EndRun.QuadPart - EndHole.QuadPart;
+
+			RemoveEntryList(&Element->Sequence);
+			RtlDeleteElementGenericTable(Mcb->Mapping, Element);
+			Mcb->PairCount--;
+			
+			Reinserted = RtlInsertElementGenericTable
+				(Mcb->Mapping, &NewElement, sizeof(NewElement), NULL);
+			InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence);
+			Mcb->PairCount++;			
+		}
+	}
+
+	return TRUE;
 }
 
 /*
@@ -358,7 +614,16 @@
 NTAPI
 FsRtlResetBaseMcb(IN PBASE_MCB Mcb)
 {
-    Mcb->PairCount = 0;
+	PLARGE_MCB_MAPPING_ENTRY Element;
+
+	while (RtlNumberGenericTableElements(Mcb->Mapping) &&
+		   (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(Mcb->Mapping, 0)))
+	{
+		RtlDeleteElementGenericTable(Mcb->Mapping, Element);
+	}
+
+	Mcb->PairCount = 0;
+	Mcb->MaximumPairCount = 0;
 }
 
 /*
@@ -372,13 +637,44 @@
     if (!SelfSynchronized)
     {
         KeAcquireGuardedMutex(Mcb->GuardedMutex);
-        Mcb->BaseMcb.PairCount = 0;
-        KeReleaseGuardedMutex(Mcb->GuardedMutex);
+	}
+
+	FsRtlResetBaseMcb(&Mcb->BaseMcb);
+
+
+    if (!SelfSynchronized)
+    {
+		KeReleaseGuardedMutex(Mcb->GuardedMutex);
     }
-    else
-    {
-        Mcb->BaseMcb.PairCount = 0;
-    }
+}
+
+#define MCB_BUMP_NO_MORE 0
+#define MCB_BUMP_AGAIN   1
+
+static ULONG NTAPI McbBump(PBASE_MCB Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart)
+{
+	LARGE_MCB_MAPPING_ENTRY Reimagined;
+	PLARGE_MCB_MAPPING_ENTRY Found = NULL;
+
+	Reimagined = *FixedPart;
+	while ((Found = RtlLookupElementGenericTable(Mcb->Mapping, &Reimagined)))
+	{
+		Reimagined = *Found;
+		Reimagined.RunStartVbn.QuadPart = 
+			FixedPart->RunStartVbn.QuadPart + FixedPart->SectorCount.QuadPart;
+	}
+
+	if (!Found) return MCB_BUMP_NO_MORE;
+	DPRINT1
+		("Moving %x-%x to %x because %x-%x overlaps\n",
+		 Found->RunStartVbn.LowPart, 
+		 Found->RunStartVbn.LowPart + Found->SectorCount.QuadPart,
+		 Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart,
+		 Reimagined.RunStartVbn.LowPart,
+		 Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart);
+	Found->RunStartVbn.QuadPart = Reimagined.RunStartVbn.QuadPart + Reimagined.SectorCount.QuadPart;
+	Found->StartingLbn.QuadPart = Reimagined.StartingLbn.QuadPart + Reimagined.SectorCount.QuadPart;
+	return MCB_BUMP_AGAIN;
 }
 
 /*
@@ -390,8 +686,66 @@
                   IN LONGLONG Vbn,
                   IN LONGLONG Amount)
 {
-    KeBugCheck(FILE_SYSTEM);
-    return FALSE;
+	ULONG Result;
+	LARGE_MCB_MAPPING_ENTRY Node;
+	PLARGE_MCB_MAPPING_ENTRY Existing = NULL;
+
+	Node.RunStartVbn.QuadPart = Vbn;
+	Node.SectorCount.QuadPart = 0;
+	
+	Existing = RtlLookupElementGenericTable(Mcb->Mapping, &Node);
+
+	if (Existing)
+	{
+		// We're in the middle of a run
+		LARGE_MCB_MAPPING_ENTRY UpperPart;
+		LARGE_MCB_MAPPING_ENTRY LowerPart;
+		PLARGE_MCB_MAPPING_ENTRY InsertedUpper;
+
+		UpperPart.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart + Amount;
+		UpperPart.SectorCount.QuadPart = Existing->RunStartVbn.QuadPart + 
+			(Existing->SectorCount.QuadPart - Node.RunStartVbn.QuadPart);
+		UpperPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart + 
+			(Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart);
+		LowerPart.RunStartVbn.QuadPart = Existing->RunStartVbn.QuadPart;
+		LowerPart.SectorCount.QuadPart = Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart;
+		LowerPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart;
+		
+		Node = UpperPart;
+
+		while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN);
+
+		if (Result == MCB_BUMP_NO_MORE)
+		{
+			Node = *Existing;
+			RemoveHeadList(&Existing->Sequence);
+			RtlDeleteElementGenericTable(Mcb->Mapping, Existing);
+			Mcb->PairCount--;
+			
+			// Adjust the element we found.
+			Existing->SectorCount = LowerPart.SectorCount;
+
+			InsertedUpper = RtlInsertElementGenericTable
+				(Mcb->Mapping, &UpperPart, sizeof(UpperPart), NULL);
+			if (!InsertedUpper)
+			{
+				// Just make it like it was
+				Existing->SectorCount = Node.SectorCount;
+				return FALSE;
+			}
+			InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &InsertedUpper->Sequence);
+			Mcb->PairCount++;
+		}
+		else
+		{
+			Node.RunStartVbn.QuadPart = Vbn;
+			Node.SectorCount.QuadPart = Amount;
+			while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN);
+			return Result == MCB_BUMP_NO_MORE;
+		}
+	}
+	
+	return TRUE;
 }
 
 /*
@@ -422,7 +776,23 @@
 FsRtlTruncateBaseMcb(IN PBASE_MCB Mcb,
                      IN LONGLONG Vbn)
 {
-    KeBugCheck(FILE_SYSTEM);
+	if (!Vbn)
+	{
+		FsRtlResetBaseMcb(Mcb);
+	}
+	else
+	{
+		LARGE_MCB_MAPPING_ENTRY Truncate;
+		PLARGE_MCB_MAPPING_ENTRY Found;
+		Truncate.RunStartVbn.QuadPart = Vbn;
+		Truncate.SectorCount.QuadPart = (1ull<<62) - Truncate.RunStartVbn.QuadPart;
+		while ((Found = RtlLookupElementGenericTable(Mcb->Mapping, &Truncate)))
+		{
+			RemoveEntryList(&Found->Sequence);
+			RtlDeleteElementGenericTable(Mcb->Mapping, Found);
+			Mcb->PairCount--;
+		}
+	}
 }
 
 /*
@@ -446,6 +816,8 @@
 NTAPI
 FsRtlUninitializeBaseMcb(IN PBASE_MCB Mcb)
 {
+	FsRtlResetBaseMcb(Mcb);
+
     if ((Mcb->PoolType == PagedPool) && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT))
     {
         ExFreeToPagedLookasideList(&FsRtlFirstMappingLookasideList,
@@ -453,7 +825,7 @@
     }
     else
     {
-        ExFreePoolWithTag(Mcb->Mapping, TAG('F', 'S', 'B', 'C'));
+        ExFreePoolWithTag(Mcb->Mapping, 'FSBC');
     }
 }
 




More information about the Ros-diffs mailing list