xref: /reactos/drivers/filesystems/ntfs/ntfs.c (revision 845faec4)
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * COPYRIGHT:        See COPYING in the top level directory
20  * PROJECT:          ReactOS kernel
21  * FILE:             drivers/filesystem/ntfs/ntfs.c
22  * PURPOSE:          NTFS filesystem driver
23  * PROGRAMMER:       Eric Kohl
24  *                   Pierre Schweitzer
25  */
26 
27 /* INCLUDES *****************************************************************/
28 
29 #include "ntfs.h"
30 
31 #define NDEBUG
32 #include <debug.h>
33 
34 #if defined(ALLOC_PRAGMA)
35 #pragma alloc_text(INIT, DriverEntry)
36 #pragma alloc_text(INIT, NtfsInitializeFunctionPointers)
37 #endif
38 
39 /* GLOBALS *****************************************************************/
40 
41 PNTFS_GLOBAL_DATA NtfsGlobalData = NULL;
42 
43 /* FUNCTIONS ****************************************************************/
44 
45 /*
46  * FUNCTION: Called by the system to initialize the driver
47  * ARGUMENTS:
48  *           DriverObject = object describing this driver
49  *           RegistryPath = path to our configuration entries
50  * RETURNS: Success or failure
51  */
52 INIT_SECTION
53 NTSTATUS
54 NTAPI
55 DriverEntry(PDRIVER_OBJECT DriverObject,
56             PUNICODE_STRING RegistryPath)
57 {
58     UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
59     NTSTATUS Status;
60     PDEVICE_OBJECT DeviceObject;
61     OBJECT_ATTRIBUTES Attributes;
62     HANDLE DriverKey = NULL;
63 
64     TRACE_(NTFS, "DriverEntry(%p, '%wZ')\n", DriverObject, RegistryPath);
65 
66     Status = IoCreateDevice(DriverObject,
67                             sizeof(NTFS_GLOBAL_DATA),
68                             &DeviceName,
69                             FILE_DEVICE_DISK_FILE_SYSTEM,
70                             0,
71                             FALSE,
72                             &DeviceObject);
73     if (!NT_SUCCESS(Status))
74     {
75         WARN_(NTFS, "IoCreateDevice failed with status: %lx\n", Status);
76         return Status;
77     }
78 
79     /* Initialize global data */
80     NtfsGlobalData = DeviceObject->DeviceExtension;
81     RtlZeroMemory(NtfsGlobalData, sizeof(NTFS_GLOBAL_DATA));
82 
83     NtfsGlobalData->DeviceObject = DeviceObject;
84     NtfsGlobalData->Identifier.Type = NTFS_TYPE_GLOBAL_DATA;
85     NtfsGlobalData->Identifier.Size = sizeof(NTFS_GLOBAL_DATA);
86 
87     ExInitializeResourceLite(&NtfsGlobalData->Resource);
88 
89     NtfsGlobalData->EnableWriteSupport = FALSE;
90 
91     // Read registry to determine if write support should be enabled
92     InitializeObjectAttributes(&Attributes,
93                                RegistryPath,
94                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
95                                NULL,
96                                NULL);
97 
98     Status = ZwOpenKey(&DriverKey, KEY_READ, &Attributes);
99     if (NT_SUCCESS(Status))
100     {
101         UNICODE_STRING ValueName;
102         UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
103         PKEY_VALUE_PARTIAL_INFORMATION Value = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
104         ULONG ValueLength = sizeof(Buffer);
105         ULONG ResultLength;
106 
107         RtlInitUnicodeString(&ValueName, L"MyDataDoesNotMatterSoEnableExperimentalWriteSupportForEveryNTFSVolume");
108 
109         Status = ZwQueryValueKey(DriverKey,
110                                  &ValueName,
111                                  KeyValuePartialInformation,
112                                  Value,
113                                  ValueLength,
114                                  &ResultLength);
115 
116         if (NT_SUCCESS(Status) && Value->Data[0] == TRUE)
117         {
118             DPRINT1("\tEnabling write support on ALL NTFS volumes!\n");
119             NtfsGlobalData->EnableWriteSupport = TRUE;
120         }
121 
122         ZwClose(DriverKey);
123     }
124 
125     /* Keep trace of Driver Object */
126     NtfsGlobalData->DriverObject = DriverObject;
127 
128     /* Initialize IRP functions array */
129     NtfsInitializeFunctionPointers(DriverObject);
130 
131     /* Initialize CC functions array */
132     NtfsGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = NtfsAcqLazyWrite;
133     NtfsGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = NtfsRelLazyWrite;
134     NtfsGlobalData->CacheMgrCallbacks.AcquireForReadAhead = NtfsAcqReadAhead;
135     NtfsGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = NtfsRelReadAhead;
136 
137     NtfsGlobalData->FastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
138     NtfsGlobalData->FastIoDispatch.FastIoCheckIfPossible = NtfsFastIoCheckIfPossible;
139     NtfsGlobalData->FastIoDispatch.FastIoRead = NtfsFastIoRead;
140     NtfsGlobalData->FastIoDispatch.FastIoWrite = NtfsFastIoWrite;
141     DriverObject->FastIoDispatch = &NtfsGlobalData->FastIoDispatch;
142 
143     /* Initialize lookaside list for IRP contexts */
144     ExInitializeNPagedLookasideList(&NtfsGlobalData->IrpContextLookasideList,
145                                     NULL, NULL, 0, sizeof(NTFS_IRP_CONTEXT), TAG_IRP_CTXT, 0);
146     /* Initialize lookaside list for FCBs */
147     ExInitializeNPagedLookasideList(&NtfsGlobalData->FcbLookasideList,
148                                     NULL, NULL, 0, sizeof(NTFS_FCB), TAG_FCB, 0);
149     /* Initialize lookaside list for attributes contexts */
150     ExInitializeNPagedLookasideList(&NtfsGlobalData->AttrCtxtLookasideList,
151                                     NULL, NULL, 0, sizeof(NTFS_ATTR_CONTEXT), TAG_ATT_CTXT, 0);
152 
153     /* Driver can't be unloaded */
154     DriverObject->DriverUnload = NULL;
155 
156     NtfsGlobalData->DeviceObject->Flags |= DO_DIRECT_IO;
157 
158     /* Register file system */
159     IoRegisterFileSystem(NtfsGlobalData->DeviceObject);
160     ObReferenceObject(NtfsGlobalData->DeviceObject);
161 
162     return STATUS_SUCCESS;
163 }
164 
165 
166 /*
167  * FUNCTION: Called within the driver entry to initialize the IRP functions array
168  * ARGUMENTS:
169  *           DriverObject = object describing this driver
170  * RETURNS: Nothing
171  */
172 INIT_SECTION
173 VOID
174 NTAPI
175 NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject)
176 {
177     DriverObject->MajorFunction[IRP_MJ_CREATE]                   = NtfsFsdDispatch;
178     DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = NtfsFsdDispatch;
179     DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = NtfsFsdDispatch;
180     DriverObject->MajorFunction[IRP_MJ_READ]                     = NtfsFsdDispatch;
181     DriverObject->MajorFunction[IRP_MJ_WRITE]                    = NtfsFsdDispatch;
182     DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = NtfsFsdDispatch;
183     DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = NtfsFsdDispatch;
184     DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = NtfsFsdDispatch;
185     DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = NtfsFsdDispatch;
186     DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = NtfsFsdDispatch;
187     DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = NtfsFsdDispatch;
188     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = NtfsFsdDispatch;
189 
190     return;
191 }
192 
193 /* EOF */
194