[NTFS] - In the NtfsAddFilenameToDirectory() function, rename DirectoryContext parame...
[reactos.git] / drivers / filesystems / ntfs / ntfs.c
index dff0505..c9bbc49 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+#if defined(ALLOC_PRAGMA)
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(INIT, NtfsInitializeFunctionPointers)
+#endif
+
 /* GLOBALS *****************************************************************/
 
 PNTFS_GLOBAL_DATA NtfsGlobalData = NULL;
@@ -44,6 +49,7 @@ PNTFS_GLOBAL_DATA NtfsGlobalData = NULL;
  *           RegistryPath = path to our configuration entries
  * RETURNS: Success or failure
  */
+INIT_SECTION
 NTSTATUS
 NTAPI
 DriverEntry(PDRIVER_OBJECT DriverObject,
@@ -51,23 +57,71 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
 {
     UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
     NTSTATUS Status;
+    PDEVICE_OBJECT DeviceObject;
+    OBJECT_ATTRIBUTES Attributes;
+    HANDLE DriverKey = NULL;
 
     TRACE_(NTFS, "DriverEntry(%p, '%wZ')\n", DriverObject, RegistryPath);
 
-    /* Initialize global data */
-    NtfsGlobalData = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_GLOBAL_DATA), 'GRDN');
-    if (!NtfsGlobalData)
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(NTFS_GLOBAL_DATA),
+                            &DeviceName,
+                            FILE_DEVICE_DISK_FILE_SYSTEM,
+                            0,
+                            FALSE,
+                            &DeviceObject);
+    if (!NT_SUCCESS(Status))
     {
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-        goto ErrorEnd;
+        WARN_(NTFS, "IoCreateDevice failed with status: %lx\n", Status);
+        return Status;
     }
 
+    /* Initialize global data */
+    NtfsGlobalData = DeviceObject->DeviceExtension;
     RtlZeroMemory(NtfsGlobalData, sizeof(NTFS_GLOBAL_DATA));
+
+    NtfsGlobalData->DeviceObject = DeviceObject;
     NtfsGlobalData->Identifier.Type = NTFS_TYPE_GLOBAL_DATA;
     NtfsGlobalData->Identifier.Size = sizeof(NTFS_GLOBAL_DATA);
 
     ExInitializeResourceLite(&NtfsGlobalData->Resource);
 
+    NtfsGlobalData->EnableWriteSupport = FALSE;
+
+    // Read registry to determine if write support should be enabled
+    InitializeObjectAttributes(&Attributes,
+                               RegistryPath,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+
+    Status = ZwOpenKey(&DriverKey, KEY_READ, &Attributes);
+    if (NT_SUCCESS(Status))
+    {
+        UNICODE_STRING ValueName;
+        UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
+        PKEY_VALUE_PARTIAL_INFORMATION Value = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
+        ULONG ValueLength = sizeof(Buffer);
+        ULONG ResultLength;
+
+        RtlInitUnicodeString(&ValueName, L"MyDataDoesNotMatterSoEnableExperimentalWriteSupportForEveryNTFSVolume");
+
+        Status = ZwQueryValueKey(DriverKey,
+                                 &ValueName,
+                                 KeyValuePartialInformation,
+                                 Value,
+                                 ValueLength,
+                                 &ResultLength);
+
+        if (NT_SUCCESS(Status) && Value->Data[0] == TRUE)
+        {
+            DPRINT1("\tEnabling write support on ALL NTFS volumes!\n");
+            NtfsGlobalData->EnableWriteSupport = TRUE;
+        }
+
+        ZwClose(DriverKey);
+    }
+
     /* Keep trace of Driver Object */
     NtfsGlobalData->DriverObject = DriverObject;
 
@@ -80,39 +134,29 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
     NtfsGlobalData->CacheMgrCallbacks.AcquireForReadAhead = NtfsAcqReadAhead; 
     NtfsGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = NtfsRelReadAhead; 
 
+    NtfsGlobalData->FastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
+    NtfsGlobalData->FastIoDispatch.FastIoCheckIfPossible = NtfsFastIoCheckIfPossible;
+    NtfsGlobalData->FastIoDispatch.FastIoRead = NtfsFastIoRead;
+    NtfsGlobalData->FastIoDispatch.FastIoWrite = NtfsFastIoWrite;
+    DriverObject->FastIoDispatch = &NtfsGlobalData->FastIoDispatch;
+
+    /* Initialize lookaside list for IRP contexts */
+    ExInitializeNPagedLookasideList(&NtfsGlobalData->IrpContextLookasideList,
+                                    NULL, NULL, 0, sizeof(NTFS_IRP_CONTEXT), 'PRIN', 0);
+    /* Initialize lookaside list for FCBs */
+    ExInitializeNPagedLookasideList(&NtfsGlobalData->FcbLookasideList,
+                                    NULL, NULL, 0, sizeof(NTFS_FCB), TAG_FCB, 0);
+
     /* Driver can't be unloaded */
     DriverObject->DriverUnload = NULL;
 
-    Status = IoCreateDevice(DriverObject,
-                            sizeof(NTFS_GLOBAL_DATA),
-                            &DeviceName,
-                            FILE_DEVICE_DISK_FILE_SYSTEM,
-                            0,
-                            FALSE,
-                            &NtfsGlobalData->DeviceObject);
-    if (!NT_SUCCESS(Status))
-    {
-        WARN_(NTFS, "IoCreateDevice failed with status: %lx\n", Status);
-        goto ErrorEnd;
-    }
-
     NtfsGlobalData->DeviceObject->Flags |= DO_DIRECT_IO;
 
     /* Register file system */
     IoRegisterFileSystem(NtfsGlobalData->DeviceObject);
     ObReferenceObject(NtfsGlobalData->DeviceObject);
 
-ErrorEnd:
-    if (!NT_SUCCESS(Status))
-    {
-        if (NtfsGlobalData)
-        {
-            ExDeleteResourceLite(&NtfsGlobalData->Resource);
-            ExFreePoolWithTag(NtfsGlobalData, 'GRDN');
-        }
-    }
-
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 
@@ -122,19 +166,23 @@ ErrorEnd:
  *           DriverObject = object describing this driver
  * RETURNS: Nothing
  */
+INIT_SECTION
 VOID
 NTAPI
 NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject)
 {
-    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = NtfsFsdCreate;
-    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = NtfsFsdClose;
-    DriverObject->MajorFunction[IRP_MJ_READ]                     = NtfsFsdRead;
-    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = NtfsFsdWrite;
-    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = NtfsFsdQueryInformation;
+    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_READ]                     = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = NtfsFsdDispatch;
     DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = NtfsFsdDispatch;
     DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = NtfsFsdDispatch;
-    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = NtfsFsdDirectoryControl;
-    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = NtfsFsdFileSystemControl;
+    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = NtfsFsdDispatch;
+    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = NtfsFsdDispatch;
 
     return;
 }