Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmisc.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: drivers/fs/vfat/misc.c 00005 * PURPOSE: VFAT Filesystem 00006 * PROGRAMMER: 00007 * 00008 */ 00009 00010 /* INCLUDES *****************************************************************/ 00011 00012 #define NDEBUG 00013 #include "vfat.h" 00014 00015 /* GLOBALS ******************************************************************/ 00016 00017 const char* MajorFunctionNames[] = 00018 { 00019 "IRP_MJ_CREATE", 00020 "IRP_MJ_CREATE_NAMED_PIPE", 00021 "IRP_MJ_CLOSE", 00022 "IRP_MJ_READ", 00023 "IRP_MJ_WRITE", 00024 "IRP_MJ_QUERY_INFORMATION", 00025 "IRP_MJ_SET_INFORMATION", 00026 "IRP_MJ_QUERY_EA", 00027 "IRP_MJ_SET_EA", 00028 "IRP_MJ_FLUSH_BUFFERS", 00029 "IRP_MJ_QUERY_VOLUME_INFORMATION", 00030 "IRP_MJ_SET_VOLUME_INFORMATION", 00031 "IRP_MJ_DIRECTORY_CONTROL", 00032 "IRP_MJ_FILE_SYSTEM_CONTROL", 00033 "IRP_MJ_DEVICE_CONTROL", 00034 "IRP_MJ_INTERNAL_DEVICE_CONTROL", 00035 "IRP_MJ_SHUTDOWN", 00036 "IRP_MJ_LOCK_CONTROL", 00037 "IRP_MJ_CLEANUP", 00038 "IRP_MJ_CREATE_MAILSLOT", 00039 "IRP_MJ_QUERY_SECURITY", 00040 "IRP_MJ_SET_SECURITY", 00041 "IRP_MJ_POWER", 00042 "IRP_MJ_SYSTEM_CONTROL", 00043 "IRP_MJ_DEVICE_CHANGE", 00044 "IRP_MJ_QUERY_QUOTA", 00045 "IRP_MJ_SET_QUOTA", 00046 "IRP_MJ_PNP", 00047 "IRP_MJ_MAXIMUM_FUNCTION" 00048 }; 00049 00050 /* FUNCTIONS ****************************************************************/ 00051 00052 static LONG QueueCount = 0; 00053 00054 static NTSTATUS VfatLockControl( 00055 IN PVFAT_IRP_CONTEXT IrpContext 00056 ) 00057 { 00058 PVFATFCB Fcb; 00059 NTSTATUS Status; 00060 00061 DPRINT("VfatLockControl(IrpContext %p)\n", IrpContext); 00062 00063 ASSERT(IrpContext); 00064 00065 Fcb = (PVFATFCB)IrpContext->FileObject->FsContext; 00066 00067 if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject) 00068 { 00069 Status = STATUS_INVALID_DEVICE_REQUEST; 00070 goto Fail; 00071 } 00072 00073 if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) 00074 { 00075 Status = STATUS_INVALID_PARAMETER; 00076 goto Fail; 00077 } 00078 00079 Status = FsRtlProcessFileLock(&Fcb->FileLock, 00080 IrpContext->Irp, 00081 NULL 00082 ); 00083 00084 VfatFreeIrpContext(IrpContext); 00085 return Status; 00086 00087 Fail:; 00088 IrpContext->Irp->IoStatus.Status = Status; 00089 IoCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)); 00090 VfatFreeIrpContext(IrpContext); 00091 return Status; 00092 } 00093 00094 static NTSTATUS 00095 VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext) 00096 { 00097 DPRINT ("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext, 00098 IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]); 00099 00100 ASSERT(IrpContext); 00101 00102 switch (IrpContext->MajorFunction) 00103 { 00104 case IRP_MJ_CLOSE: 00105 return VfatClose (IrpContext); 00106 case IRP_MJ_CREATE: 00107 return VfatCreate (IrpContext); 00108 case IRP_MJ_READ: 00109 return VfatRead (IrpContext); 00110 case IRP_MJ_WRITE: 00111 return VfatWrite (IrpContext); 00112 case IRP_MJ_FILE_SYSTEM_CONTROL: 00113 return VfatFileSystemControl(IrpContext); 00114 case IRP_MJ_QUERY_INFORMATION: 00115 return VfatQueryInformation (IrpContext); 00116 case IRP_MJ_SET_INFORMATION: 00117 return VfatSetInformation (IrpContext); 00118 case IRP_MJ_DIRECTORY_CONTROL: 00119 return VfatDirectoryControl(IrpContext); 00120 case IRP_MJ_QUERY_VOLUME_INFORMATION: 00121 return VfatQueryVolumeInformation(IrpContext); 00122 case IRP_MJ_SET_VOLUME_INFORMATION: 00123 return VfatSetVolumeInformation(IrpContext); 00124 case IRP_MJ_LOCK_CONTROL: 00125 return VfatLockControl(IrpContext); 00126 case IRP_MJ_CLEANUP: 00127 return VfatCleanup(IrpContext); 00128 case IRP_MJ_FLUSH_BUFFERS: 00129 return VfatFlush(IrpContext); 00130 case IRP_MJ_PNP: 00131 return VfatPnp(IrpContext); 00132 default: 00133 DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction); 00134 IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR; 00135 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT); 00136 VfatFreeIrpContext(IrpContext); 00137 return STATUS_DRIVER_INTERNAL_ERROR; 00138 } 00139 } 00140 00141 NTSTATUS NTAPI VfatBuildRequest ( 00142 IN PDEVICE_OBJECT DeviceObject, 00143 IN PIRP Irp) 00144 { 00145 NTSTATUS Status; 00146 PVFAT_IRP_CONTEXT IrpContext; 00147 00148 DPRINT ("VfatBuildRequest (DeviceObject %p, Irp %p)\n", DeviceObject, Irp); 00149 00150 ASSERT(DeviceObject); 00151 ASSERT(Irp); 00152 IrpContext = VfatAllocateIrpContext(DeviceObject, Irp); 00153 if (IrpContext == NULL) 00154 { 00155 Status = STATUS_INSUFFICIENT_RESOURCES; 00156 Irp->IoStatus.Status = Status; 00157 IoCompleteRequest (Irp, IO_NO_INCREMENT); 00158 } 00159 else 00160 { 00161 FsRtlEnterFileSystem(); 00162 Status = VfatDispatchRequest (IrpContext); 00163 FsRtlExitFileSystem(); 00164 } 00165 return Status; 00166 } 00167 00168 VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext) 00169 { 00170 ASSERT(IrpContext); 00171 ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext); 00172 } 00173 00174 PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp) 00175 { 00176 PVFAT_IRP_CONTEXT IrpContext; 00177 /*PIO_STACK_LOCATION Stack;*/ 00178 UCHAR MajorFunction; 00179 DPRINT ("VfatAllocateIrpContext(DeviceObject %p, Irp %p)\n", DeviceObject, Irp); 00180 00181 ASSERT(DeviceObject); 00182 ASSERT(Irp); 00183 00184 IrpContext = ExAllocateFromNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList); 00185 if (IrpContext) 00186 { 00187 RtlZeroMemory(IrpContext, sizeof(VFAT_IRP_CONTEXT)); 00188 IrpContext->Irp = Irp; 00189 IrpContext->DeviceObject = DeviceObject; 00190 IrpContext->DeviceExt = DeviceObject->DeviceExtension; 00191 IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp); 00192 ASSERT(IrpContext->Stack); 00193 MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction; 00194 IrpContext->MinorFunction = IrpContext->Stack->MinorFunction; 00195 IrpContext->FileObject = IrpContext->Stack->FileObject; 00196 IrpContext->Flags = 0; 00197 if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL || 00198 MajorFunction == IRP_MJ_DEVICE_CONTROL || 00199 MajorFunction == IRP_MJ_SHUTDOWN) 00200 { 00201 IrpContext->Flags |= IRPCONTEXT_CANWAIT; 00202 } 00203 else if (MajorFunction != IRP_MJ_CLEANUP && 00204 MajorFunction != IRP_MJ_CLOSE && 00205 IoIsOperationSynchronous(Irp)) 00206 { 00207 IrpContext->Flags |= IRPCONTEXT_CANWAIT; 00208 } 00209 KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE); 00210 IrpContext->RefCount = 0; 00211 } 00212 return IrpContext; 00213 } 00214 00215 static VOID NTAPI VfatDoRequest (PVOID IrpContext) 00216 { 00217 InterlockedDecrement(&QueueCount); 00218 DPRINT ("VfatDoRequest (IrpContext %p), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount); 00219 FsRtlEnterFileSystem(); 00220 VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext); 00221 FsRtlExitFileSystem(); 00222 00223 } 00224 00225 NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext) 00226 { 00227 InterlockedIncrement(&QueueCount); 00228 DPRINT ("VfatQueueRequest (IrpContext %p), %d\n", IrpContext, QueueCount); 00229 00230 ASSERT(IrpContext != NULL); 00231 ASSERT(IrpContext->Irp != NULL); 00232 00233 IrpContext->Flags |= IRPCONTEXT_CANWAIT; 00234 IoMarkIrpPending (IrpContext->Irp); 00235 ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext); 00236 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue); 00237 return STATUS_PENDING; 00238 } 00239 00240 PVOID VfatGetUserBuffer(IN PIRP Irp) 00241 { 00242 ASSERT(Irp); 00243 00244 if (Irp->MdlAddress) 00245 { 00246 /* This call may be in the paging path, so use maximum priority */ 00247 /* FIXME: call with normal priority in the non-paging path */ 00248 return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority); 00249 } 00250 else 00251 { 00252 return Irp->UserBuffer; 00253 } 00254 } 00255 00256 NTSTATUS VfatLockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation) 00257 { 00258 ASSERT(Irp); 00259 00260 if (Irp->MdlAddress) 00261 { 00262 return STATUS_SUCCESS; 00263 } 00264 00265 IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp); 00266 00267 if (!Irp->MdlAddress) 00268 { 00269 return STATUS_INSUFFICIENT_RESOURCES; 00270 } 00271 00272 MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, Operation); 00273 00274 return STATUS_SUCCESS; 00275 } 00276 00277 Generated on Sun May 27 2012 04:16:47 for ReactOS by
1.7.6.1
|