1c2c66affSColin Finck /*
2c2c66affSColin Finck * ReactOS kernel
3c2c66affSColin Finck * Copyright (C) 2008 ReactOS Team
4c2c66affSColin Finck *
5c2c66affSColin Finck * This program is free software; you can redistribute it and/or modify
6c2c66affSColin Finck * it under the terms of the GNU General Public License as published by
7c2c66affSColin Finck * the Free Software Foundation; either version 2 of the License, or
8c2c66affSColin Finck * (at your option) any later version.
9c2c66affSColin Finck *
10c2c66affSColin Finck * This program is distributed in the hope that it will be useful,
11c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
12c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c2c66affSColin Finck * GNU General Public License for more details.
14c2c66affSColin Finck *
15c2c66affSColin Finck * You should have received a copy of the GNU General Public License
16c2c66affSColin Finck * along with this program; if not, write to the Free Software
17c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18c2c66affSColin Finck *
19c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
20c2c66affSColin Finck * PROJECT: ReactOS kernel
21c2c66affSColin Finck * FILE: drivers/filesystem/ntfs/dispatch.c
22c2c66affSColin Finck * PURPOSE: NTFS filesystem driver
23c2c66affSColin Finck * PROGRAMMER: Pierre Schweitzer
24c2c66affSColin Finck * UPDATE HISTORY:
25c2c66affSColin Finck */
26c2c66affSColin Finck
27c2c66affSColin Finck /* INCLUDES *****************************************************************/
28c2c66affSColin Finck
29c2c66affSColin Finck #include "ntfs.h"
30c2c66affSColin Finck
31c2c66affSColin Finck #define NDEBUG
32c2c66affSColin Finck #include <debug.h>
33c2c66affSColin Finck
34c2c66affSColin Finck static LONG QueueCount = 0;
35c2c66affSColin Finck
36c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
37c2c66affSColin Finck
38c2c66affSColin Finck static WORKER_THREAD_ROUTINE NtfsDoRequest;
39c2c66affSColin Finck
40c2c66affSColin Finck static
41c2c66affSColin Finck NTSTATUS
NtfsQueueRequest(PNTFS_IRP_CONTEXT IrpContext)42c2c66affSColin Finck NtfsQueueRequest(PNTFS_IRP_CONTEXT IrpContext)
43c2c66affSColin Finck {
44c2c66affSColin Finck InterlockedIncrement(&QueueCount);
45c2c66affSColin Finck DPRINT("NtfsQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount);
46c2c66affSColin Finck
47c2c66affSColin Finck ASSERT(!(IrpContext->Flags & IRPCONTEXT_QUEUE) &&
48c2c66affSColin Finck (IrpContext->Flags & IRPCONTEXT_COMPLETE));
49c2c66affSColin Finck IrpContext->Flags |= IRPCONTEXT_CANWAIT;
50c2c66affSColin Finck IoMarkIrpPending(IrpContext->Irp);
51c2c66affSColin Finck ExInitializeWorkItem(&IrpContext->WorkQueueItem, NtfsDoRequest, IrpContext);
52c2c66affSColin Finck ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
53c2c66affSColin Finck
54c2c66affSColin Finck return STATUS_PENDING;
55c2c66affSColin Finck }
56c2c66affSColin Finck
57c2c66affSColin Finck static
58c2c66affSColin Finck NTSTATUS
NtfsDispatch(PNTFS_IRP_CONTEXT IrpContext)59c2c66affSColin Finck NtfsDispatch(PNTFS_IRP_CONTEXT IrpContext)
60c2c66affSColin Finck {
61c2c66affSColin Finck PIRP Irp = IrpContext->Irp;
62c2c66affSColin Finck NTSTATUS Status = STATUS_UNSUCCESSFUL;
63c2c66affSColin Finck
64c2c66affSColin Finck TRACE_(NTFS, "NtfsDispatch()\n");
65c2c66affSColin Finck
66c2c66affSColin Finck FsRtlEnterFileSystem();
67c2c66affSColin Finck
68c2c66affSColin Finck NtfsIsIrpTopLevel(Irp);
69c2c66affSColin Finck
70c2c66affSColin Finck switch (IrpContext->MajorFunction)
71c2c66affSColin Finck {
72c2c66affSColin Finck case IRP_MJ_QUERY_VOLUME_INFORMATION:
73c2c66affSColin Finck Status = NtfsQueryVolumeInformation(IrpContext);
74c2c66affSColin Finck break;
75c2c66affSColin Finck
76c2c66affSColin Finck case IRP_MJ_SET_VOLUME_INFORMATION:
77c2c66affSColin Finck Status = NtfsSetVolumeInformation(IrpContext);
78c2c66affSColin Finck break;
79c2c66affSColin Finck
80c2c66affSColin Finck case IRP_MJ_QUERY_INFORMATION:
81c2c66affSColin Finck Status = NtfsQueryInformation(IrpContext);
82c2c66affSColin Finck break;
83c2c66affSColin Finck
847f762aacSTrevor Thompson case IRP_MJ_SET_INFORMATION:
85*037d8820STrevor Thompson if (!NtfsGlobalData->EnableWriteSupport)
86*037d8820STrevor Thompson {
87*037d8820STrevor Thompson DPRINT1("NTFS write-support is EXPERIMENTAL and is disabled by default!\n");
88*037d8820STrevor Thompson Status = STATUS_ACCESS_DENIED;
89*037d8820STrevor Thompson }
90*037d8820STrevor Thompson else
91*037d8820STrevor Thompson {
927f762aacSTrevor Thompson Status = NtfsSetInformation(IrpContext);
93*037d8820STrevor Thompson }
947f762aacSTrevor Thompson break;
957f762aacSTrevor Thompson
96c2c66affSColin Finck case IRP_MJ_DIRECTORY_CONTROL:
97c2c66affSColin Finck Status = NtfsDirectoryControl(IrpContext);
98c2c66affSColin Finck break;
99c2c66affSColin Finck
100c2c66affSColin Finck case IRP_MJ_READ:
101c2c66affSColin Finck Status = NtfsRead(IrpContext);
102c2c66affSColin Finck break;
103c2c66affSColin Finck
104c2c66affSColin Finck case IRP_MJ_DEVICE_CONTROL:
105c2c66affSColin Finck Status = NtfsDeviceControl(IrpContext);
106c2c66affSColin Finck break;
107c2c66affSColin Finck
108c2c66affSColin Finck case IRP_MJ_WRITE:
109*037d8820STrevor Thompson if (!NtfsGlobalData->EnableWriteSupport)
110*037d8820STrevor Thompson {
111*037d8820STrevor Thompson DPRINT1("NTFS write-support is EXPERIMENTAL and is disabled by default!\n");
112*037d8820STrevor Thompson Status = STATUS_ACCESS_DENIED;
113*037d8820STrevor Thompson }
114*037d8820STrevor Thompson else
115*037d8820STrevor Thompson {
116c2c66affSColin Finck Status = NtfsWrite(IrpContext);
117*037d8820STrevor Thompson }
118c2c66affSColin Finck break;
119c2c66affSColin Finck
120c2c66affSColin Finck case IRP_MJ_CLOSE:
121c2c66affSColin Finck Status = NtfsClose(IrpContext);
122c2c66affSColin Finck break;
123c2c66affSColin Finck
124c2c66affSColin Finck case IRP_MJ_CLEANUP:
125c2c66affSColin Finck Status = NtfsCleanup(IrpContext);
126c2c66affSColin Finck break;
127c2c66affSColin Finck
128c2c66affSColin Finck case IRP_MJ_CREATE:
129c2c66affSColin Finck Status = NtfsCreate(IrpContext);
130c2c66affSColin Finck break;
131c2c66affSColin Finck
132c2c66affSColin Finck case IRP_MJ_FILE_SYSTEM_CONTROL:
133c2c66affSColin Finck Status = NtfsFileSystemControl(IrpContext);
134c2c66affSColin Finck break;
135c2c66affSColin Finck }
136c2c66affSColin Finck
137c2c66affSColin Finck ASSERT((!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
138c2c66affSColin Finck ((IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
139c2c66affSColin Finck (!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && (IrpContext->Flags & IRPCONTEXT_QUEUE)));
140c2c66affSColin Finck
141c2c66affSColin Finck if (IrpContext->Flags & IRPCONTEXT_COMPLETE)
142c2c66affSColin Finck {
143c2c66affSColin Finck Irp->IoStatus.Status = Status;
144c2c66affSColin Finck IoCompleteRequest(Irp, IrpContext->PriorityBoost);
145c2c66affSColin Finck }
146c2c66affSColin Finck
147c2c66affSColin Finck if (IrpContext->Flags & IRPCONTEXT_QUEUE)
148c2c66affSColin Finck {
149c2c66affSColin Finck /* Reset our status flags before queueing the IRP */
150c2c66affSColin Finck IrpContext->Flags |= IRPCONTEXT_COMPLETE;
151c2c66affSColin Finck IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
152c2c66affSColin Finck Status = NtfsQueueRequest(IrpContext);
153c2c66affSColin Finck }
154c2c66affSColin Finck else
155c2c66affSColin Finck {
156c2c66affSColin Finck ExFreeToNPagedLookasideList(&NtfsGlobalData->IrpContextLookasideList, IrpContext);
157c2c66affSColin Finck }
158c2c66affSColin Finck
159c2c66affSColin Finck IoSetTopLevelIrp(NULL);
160c2c66affSColin Finck FsRtlExitFileSystem();
161c2c66affSColin Finck
162c2c66affSColin Finck return Status;
163c2c66affSColin Finck }
164c2c66affSColin Finck
165c2c66affSColin Finck static
166c2c66affSColin Finck VOID
167c2c66affSColin Finck NTAPI
NtfsDoRequest(PVOID IrpContext)168c2c66affSColin Finck NtfsDoRequest(PVOID IrpContext)
169c2c66affSColin Finck {
170c2c66affSColin Finck InterlockedDecrement(&QueueCount);
171c2c66affSColin Finck DPRINT("NtfsDoRequest(IrpContext %p), MajorFunction %x, %d\n",
172c2c66affSColin Finck IrpContext, ((PNTFS_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
173c2c66affSColin Finck NtfsDispatch((PNTFS_IRP_CONTEXT)IrpContext);
174c2c66affSColin Finck }
175c2c66affSColin Finck
176c2c66affSColin Finck /*
177c2c66affSColin Finck * FUNCTION: This function manages IRP for various major functions
178c2c66affSColin Finck * ARGUMENTS:
179c2c66affSColin Finck * DriverObject = object describing this driver
180c2c66affSColin Finck * Irp = IRP to be passed to internal functions
181c2c66affSColin Finck * RETURNS: Status of I/O Request
182c2c66affSColin Finck */
183c2c66affSColin Finck NTSTATUS
184c2c66affSColin Finck NTAPI
NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject,PIRP Irp)185c2c66affSColin Finck NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject,
186c2c66affSColin Finck PIRP Irp)
187c2c66affSColin Finck {
188c2c66affSColin Finck PNTFS_IRP_CONTEXT IrpContext = NULL;
189c2c66affSColin Finck NTSTATUS Status;
190c2c66affSColin Finck
191c2c66affSColin Finck TRACE_(NTFS, "NtfsFsdDispatch()\n");
192c2c66affSColin Finck
193c2c66affSColin Finck IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
194c2c66affSColin Finck if (IrpContext == NULL)
195c2c66affSColin Finck {
196c2c66affSColin Finck Status = STATUS_INSUFFICIENT_RESOURCES;
197c2c66affSColin Finck Irp->IoStatus.Status = Status;
198c2c66affSColin Finck IoCompleteRequest(Irp, IO_NO_INCREMENT);
199c2c66affSColin Finck }
200c2c66affSColin Finck else
201c2c66affSColin Finck {
202c2c66affSColin Finck Status = NtfsDispatch(IrpContext);
203c2c66affSColin Finck }
204c2c66affSColin Finck
205c2c66affSColin Finck return Status;
206c2c66affSColin Finck }
207