1 /* 2 * ReactOS kernel 3 * Copyright (C) 2008 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/dispatch.c 22 * PURPOSE: NTFS filesystem driver 23 * PROGRAMMER: Pierre Schweitzer 24 * UPDATE HISTORY: 25 */ 26 27 /* INCLUDES *****************************************************************/ 28 29 #include "ntfs.h" 30 31 #define NDEBUG 32 #include <debug.h> 33 34 static LONG QueueCount = 0; 35 36 /* FUNCTIONS ****************************************************************/ 37 38 static WORKER_THREAD_ROUTINE NtfsDoRequest; 39 40 static 41 NTSTATUS 42 NtfsQueueRequest(PNTFS_IRP_CONTEXT IrpContext) 43 { 44 InterlockedIncrement(&QueueCount); 45 DPRINT("NtfsQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount); 46 47 ASSERT(!(IrpContext->Flags & IRPCONTEXT_QUEUE) && 48 (IrpContext->Flags & IRPCONTEXT_COMPLETE)); 49 IrpContext->Flags |= IRPCONTEXT_CANWAIT; 50 IoMarkIrpPending(IrpContext->Irp); 51 ExInitializeWorkItem(&IrpContext->WorkQueueItem, NtfsDoRequest, IrpContext); 52 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); 53 54 return STATUS_PENDING; 55 } 56 57 static 58 NTSTATUS 59 NtfsDispatch(PNTFS_IRP_CONTEXT IrpContext) 60 { 61 PIRP Irp = IrpContext->Irp; 62 NTSTATUS Status = STATUS_UNSUCCESSFUL; 63 64 TRACE_(NTFS, "NtfsDispatch()\n"); 65 66 FsRtlEnterFileSystem(); 67 68 NtfsIsIrpTopLevel(Irp); 69 70 switch (IrpContext->MajorFunction) 71 { 72 case IRP_MJ_QUERY_VOLUME_INFORMATION: 73 Status = NtfsQueryVolumeInformation(IrpContext); 74 break; 75 76 case IRP_MJ_SET_VOLUME_INFORMATION: 77 Status = NtfsSetVolumeInformation(IrpContext); 78 break; 79 80 case IRP_MJ_QUERY_INFORMATION: 81 Status = NtfsQueryInformation(IrpContext); 82 break; 83 84 case IRP_MJ_DIRECTORY_CONTROL: 85 Status = NtfsDirectoryControl(IrpContext); 86 break; 87 88 case IRP_MJ_READ: 89 Status = NtfsRead(IrpContext); 90 break; 91 92 case IRP_MJ_DEVICE_CONTROL: 93 Status = NtfsDeviceControl(IrpContext); 94 break; 95 96 case IRP_MJ_WRITE: 97 Status = NtfsWrite(IrpContext); 98 break; 99 100 case IRP_MJ_CLOSE: 101 Status = NtfsClose(IrpContext); 102 break; 103 104 case IRP_MJ_CLEANUP: 105 Status = NtfsCleanup(IrpContext); 106 break; 107 108 case IRP_MJ_CREATE: 109 Status = NtfsCreate(IrpContext); 110 break; 111 112 case IRP_MJ_FILE_SYSTEM_CONTROL: 113 Status = NtfsFileSystemControl(IrpContext); 114 break; 115 } 116 117 ASSERT((!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) || 118 ((IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) || 119 (!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && (IrpContext->Flags & IRPCONTEXT_QUEUE))); 120 121 if (IrpContext->Flags & IRPCONTEXT_COMPLETE) 122 { 123 Irp->IoStatus.Status = Status; 124 IoCompleteRequest(Irp, IrpContext->PriorityBoost); 125 } 126 127 if (IrpContext->Flags & IRPCONTEXT_QUEUE) 128 { 129 /* Reset our status flags before queueing the IRP */ 130 IrpContext->Flags |= IRPCONTEXT_COMPLETE; 131 IrpContext->Flags &= ~IRPCONTEXT_QUEUE; 132 Status = NtfsQueueRequest(IrpContext); 133 } 134 else 135 { 136 ExFreeToNPagedLookasideList(&NtfsGlobalData->IrpContextLookasideList, IrpContext); 137 } 138 139 IoSetTopLevelIrp(NULL); 140 FsRtlExitFileSystem(); 141 142 return Status; 143 } 144 145 static 146 VOID 147 NTAPI 148 NtfsDoRequest(PVOID IrpContext) 149 { 150 InterlockedDecrement(&QueueCount); 151 DPRINT("NtfsDoRequest(IrpContext %p), MajorFunction %x, %d\n", 152 IrpContext, ((PNTFS_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount); 153 NtfsDispatch((PNTFS_IRP_CONTEXT)IrpContext); 154 } 155 156 /* 157 * FUNCTION: This function manages IRP for various major functions 158 * ARGUMENTS: 159 * DriverObject = object describing this driver 160 * Irp = IRP to be passed to internal functions 161 * RETURNS: Status of I/O Request 162 */ 163 NTSTATUS 164 NTAPI 165 NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject, 166 PIRP Irp) 167 { 168 PNTFS_IRP_CONTEXT IrpContext = NULL; 169 NTSTATUS Status; 170 171 TRACE_(NTFS, "NtfsFsdDispatch()\n"); 172 173 IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp); 174 if (IrpContext == NULL) 175 { 176 Status = STATUS_INSUFFICIENT_RESOURCES; 177 Irp->IoStatus.Status = Status; 178 IoCompleteRequest(Irp, IO_NO_INCREMENT); 179 } 180 else 181 { 182 Status = NtfsDispatch(IrpContext); 183 } 184 185 return Status; 186 } 187