Author: tthompson
Date: Fri Jun 23 17:30:13 2017
New Revision: 75170
URL: 
http://svn.reactos.org/svn/reactos?rev=75170&view=rev
Log:
[NTFS] - Fix IncreaseMftSize(); check IrpContext to see if waiting for exclusive access to
the MFT is allowed. As pointed out by Pierre.
Modified:
    branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/create.c
    branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c
    branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/create.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/create.c   [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/create.c   [iso-8859-1] Fri Jun 23
17:30:13 2017
@@ -323,7 +323,7 @@
 static
 NTSTATUS
 NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
-               PIRP Irp)
+               PNTFS_IRP_CONTEXT IrpContext)
 {
     PDEVICE_EXTENSION DeviceExt;
     PIO_STACK_LOCATION Stack;
@@ -334,8 +334,9 @@
 //    PWSTR FileName;
     NTSTATUS Status;
     UNICODE_STRING FullPath;
-
-    DPRINT1("NtfsCreateFile(%p, %p) called\n", DeviceObject, Irp);
+    PIRP Irp = IrpContext->Irp;
+
+    DPRINT1("NtfsCreateFile(%p, %p) called\n", DeviceObject, IrpContext);
     DeviceExt = DeviceObject->DeviceExtension;
     ASSERT(DeviceExt);
@@ -561,7 +562,7 @@
             }
             // Create the file record on disk
-            Status = NtfsCreateFileRecord(DeviceExt, FileObject);
+            Status = NtfsCreateFileRecord(DeviceExt, FileObject,
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT));
             if (!NT_SUCCESS(Status))
             {
                 DPRINT1("ERROR: Couldn't create file record!\n");
@@ -569,7 +570,7 @@
             }
             // Now we should be able to open the file
-            return NtfsCreateFile(DeviceObject, Irp);
+            return NtfsCreateFile(DeviceObject, IrpContext);
         }
     }
@@ -615,7 +616,7 @@
     ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
                                    TRUE);
     Status = NtfsCreateFile(DeviceObject,
-                            IrpContext->Irp);
+                            IrpContext);
     ExReleaseResourceLite(&DeviceExt->DirResource);
     return Status;
@@ -634,13 +635,20 @@
 * @param FileObject
 * Pointer to a FILE_OBJECT describing the file to be created
 *
+* @param CanWait
+* Boolean 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.
+*
 * @return
 * 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)
+                     PFILE_OBJECT FileObject,
+                     BOOLEAN CanWait)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     PFILE_RECORD_HEADER FileRecord;
@@ -649,7 +657,7 @@
     ULONGLONG ParentMftIndex;
     ULONGLONG FileMftIndex;
-    DPRINT1("NtfsCreateFileRecord(%p, %p)\n", DeviceExt, FileObject);
+    DPRINT1("NtfsCreateFileRecord(%p, %p, %s)\n", DeviceExt, FileObject,
CanWait ? "TRUE" : "FALSE");
     // allocate memory for file record
     FileRecord = ExAllocatePoolWithTag(NonPagedPool,
@@ -708,7 +716,7 @@
     NtfsDumpFileRecord(DeviceExt, FileRecord);
     // Now that we've built the file record in memory, we need to store it in the
MFT.
-    Status = AddNewMftEntry(FileRecord, DeviceExt, &FileMftIndex);
+    Status = AddNewMftEntry(FileRecord, DeviceExt, &FileMftIndex, CanWait);
     if (NT_SUCCESS(Status))
     {
         // The highest 2 bytes should be the sequence number, unless the parent happens
to be root
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c      [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/mft.c      [iso-8859-1] Fri Jun 23
17:30:13 2017
@@ -195,10 +195,16 @@
 * @param Vcb
 * Pointer to the VCB (DEVICE_EXTENSION) of the target volume.
 *
+*
+* @param CanWait
+* Boolean 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.
+*
 * @return
 * STATUS_SUCCESS on success.
 * STATUS_INSUFFICIENT_RESOURCES if an allocation fails.
 * STATUS_INVALID_PARAMETER if there was an error reading the Mft's bitmap.
+* STATUS_CANT_WAIT if CanWait was FALSE and the function could not get immediate,
exclusive access to the MFT.
 *
 * @remarks
 * Increases the size of the Master File Table by 8 records. Bitmap entries for the new
records are cleared,
@@ -206,7 +212,7 @@
 * This function will wait for exlusive access to the volume fcb.
 */
 NTSTATUS
-IncreaseMftSize(PDEVICE_EXTENSION Vcb)
+IncreaseMftSize(PDEVICE_EXTENSION Vcb, BOOLEAN CanWait)
 {
     PNTFS_ATTR_CONTEXT BitmapContext;
     LARGE_INTEGER BitmapSize;
@@ -221,10 +227,10 @@
     ULONG LengthWritten;
     NTSTATUS Status;
-    DPRINT1("IncreaseMftSize(%p)\n", Vcb);
+    DPRINT1("IncreaseMftSize(%p, %s)\n", Vcb, CanWait ? "TRUE" :
"FALSE");
     // We need exclusive access to the mft while we change its size
-    if (!ExAcquireResourceExclusiveLite(&(Vcb->DirResource), TRUE))
+    if (!ExAcquireResourceExclusiveLite(&(Vcb->DirResource), CanWait))
     {
         return STATUS_CANT_WAIT;
     }
@@ -1638,17 +1644,22 @@
 * @param DestinationIndex
 * Pointer to a ULONGLONG which will receive the MFT index where the file record was
stored.
 *
+* @param CanWait
+* Boolean 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.
+*
 * @return
 * STATUS_SUCCESS on success.
 * STATUS_OBJECT_NAME_NOT_FOUND if we can't find the MFT's $Bitmap or if we
weren't able
 * to read the attribute.
 * STATUS_INSUFFICIENT_RESOURCES if we can't allocate enough memory for a copy of
$Bitmap.
-*
+* STATUS_CANT_WAIT if CanWait was FALSE and the function could not get immediate,
exclusive access to the MFT.
 */
 NTSTATUS
 AddNewMftEntry(PFILE_RECORD_HEADER FileRecord,
                PDEVICE_EXTENSION DeviceExt,
-               PULONGLONG DestinationIndex)
+               PULONGLONG DestinationIndex,
+               BOOLEAN CanWait)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     ULONGLONG MftIndex;
@@ -1661,7 +1672,7 @@
     LARGE_INTEGER BitmapBits;
     UCHAR SystemReservedBits;
-    DPRINT1("AddNewMftEntry(%p, %p, %p)\n", FileRecord, DeviceExt,
DestinationIndex);
+    DPRINT1("AddNewMftEntry(%p, %p, %p, %s)\n", FileRecord, DeviceExt,
DestinationIndex, CanWait ? "TRUE" : "FALSE");
     // First, we have to read the mft's $Bitmap attribute
     Status = FindAttribute(DeviceExt, DeviceExt->MasterFileTable, AttributeBitmap,
L"", 0, &BitmapContext, NULL);
@@ -1717,14 +1728,14 @@
         ReleaseAttributeContext(BitmapContext);
         // Couldn't find a free record in the MFT, add some blank records and try
again
-        Status = IncreaseMftSize(DeviceExt);
+        Status = IncreaseMftSize(DeviceExt, CanWait);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("ERROR: Couldn't find space in MFT for file or increase MFT
size!\n");
             return Status;
         }
-        return AddNewMftEntry(FileRecord, DeviceExt, DestinationIndex);
+        return AddNewMftEntry(FileRecord, DeviceExt, DestinationIndex, CanWait);
     }
     DPRINT1("Creating file record at MFT index: %I64u\n", MftIndex);
Modified: branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/NTFS/drivers/filesyst…
==============================================================================
--- branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h     [iso-8859-1] (original)
+++ branches/GSoC_2016/NTFS/drivers/filesystems/ntfs/ntfs.h     [iso-8859-1] Fri Jun 23
17:30:13 2017
@@ -667,7 +667,8 @@
 NTSTATUS
 NtfsCreateFileRecord(PDEVICE_EXTENSION DeviceExt,
-                     PFILE_OBJECT FileObject);
+                     PFILE_OBJECT FileObject,
+                     BOOLEAN CanWait);
 /* devctl.c */
@@ -825,7 +826,8 @@
 NTSTATUS
 AddNewMftEntry(PFILE_RECORD_HEADER FileRecord,
                PDEVICE_EXTENSION DeviceExt,
-               PULONGLONG DestinationIndex);
+               PULONGLONG DestinationIndex,
+               BOOLEAN CanWait);
 PNTFS_ATTR_CONTEXT
 PrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord);