xref: /reactos/drivers/filesystems/ntfs/dispatch.c (revision 037d8820)
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