Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

fspdisp.c File Reference

#include "UdfProcs.h"

Go to the source code of this file.

Defines

#define BugCheckFileId   (UDFS_BUG_CHECK_FSPDISP)
#define Dbg   (UDFS_DEBUG_LEVEL_FSPDISP)

Functions

VOID UdfFspDispatch (IN PIRP_CONTEXT IrpContext)


Define Documentation

#define BugCheckFileId   (UDFS_BUG_CHECK_FSPDISP)
 

Definition at line 28 of file fspdisp.c.

#define Dbg   (UDFS_DEBUG_LEVEL_FSPDISP)
 

Definition at line 34 of file fspdisp.c.


Function Documentation

VOID UdfFspDispatch IN PIRP_CONTEXT  IrpContext  ) 
 

Definition at line 38 of file fspdisp.c.

References ASSERT, _IO_STACK_LOCATION::DeviceObject, FALSE, _IO_STACK_LOCATION::FileObject, FsRtlEnterFileSystem, FsRtlExitFileSystem, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FSP_FLAGS, IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_CREATE, IRP_MJ_DEVICE_CONTROL, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MJ_LOCK_CONTROL, IRP_MJ_PNP, IRP_MJ_QUERY_INFORMATION, IRP_MJ_QUERY_VOLUME_INFORMATION, IRP_MJ_READ, IRP_MJ_SET_INFORMATION, KeAcquireSpinLock, KeReleaseSpinLock(), NTSTATUS(), NULL, _VOLUME_DEVICE_OBJECT::OverflowQueue, _VOLUME_DEVICE_OBJECT::OverflowQueueCount, _VOLUME_DEVICE_OBJECT::OverflowQueueSpinLock, _VOLUME_DEVICE_OBJECT::PostedRequestCount, SetFlag, Status, ThreadContext, TRUE, UdfCleanupIrpContext(), UdfCommonCleanup(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteRequest(), UdfExceptionFilter(), UdfProcessException(), and UdfSetThreadContext().

Referenced by UdfAddToWorkque().

00044 : 00045 00046 This is the main FSP thread routine that is executed to receive 00047 and dispatch IRP requests. Each FSP thread begins its execution here. 00048 There is one thread created at system initialization time and subsequent 00049 threads created as needed. 00050 00051 Arguments: 00052 00053 IrpContext - IrpContext for a request to process. 00054 00055 Return Value: 00056 00057 None 00058 00059 --*/ 00060 00061 { 00062 THREAD_CONTEXT ThreadContext; 00063 NTSTATUS Status; 00064 00065 PIRP Irp = IrpContext->Irp; 00066 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00067 00068 PVOLUME_DEVICE_OBJECT VolDo = NULL; 00069 00070 // 00071 // If this request has an associated volume device object, remember it. 00072 // 00073 00074 if (IrpSp->FileObject != NULL) { 00075 00076 VolDo = CONTAINING_RECORD( IrpSp->DeviceObject, 00077 VOLUME_DEVICE_OBJECT, 00078 DeviceObject ); 00079 } 00080 00081 // 00082 // Now case on the function code. For each major function code, 00083 // either call the appropriate worker routine. This routine that 00084 // we call is responsible for completing the IRP, and not us. 00085 // That way the routine can complete the IRP and then continue 00086 // post processing as required. For example, a read can be 00087 // satisfied right away and then read can be done. 00088 // 00089 // We'll do all of the work within an exception handler that 00090 // will be invoked if ever some underlying operation gets into 00091 // trouble. 00092 // 00093 00094 while (TRUE) { 00095 00096 // 00097 // Set all the flags indicating we are in the Fsp. 00098 // 00099 00100 SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); 00101 00102 FsRtlEnterFileSystem(); 00103 00104 UdfSetThreadContext( IrpContext, &ThreadContext ); 00105 00106 while (TRUE) { 00107 00108 try { 00109 00110 // 00111 // Reinitialize for the next try at completing this 00112 // request. 00113 // 00114 00115 Status = 00116 IrpContext->ExceptionStatus = STATUS_SUCCESS; 00117 00118 // 00119 // Initialize the Io status field in the Irp. 00120 // 00121 00122 Irp->IoStatus.Status = STATUS_SUCCESS; 00123 Irp->IoStatus.Information = 0; 00124 00125 // 00126 // Case on the major irp code. 00127 // 00128 00129 switch (IrpContext->MajorFunction) { 00130 00131 case IRP_MJ_CLEANUP : 00132 00133 Status = UdfCommonCleanup( IrpContext, Irp ); 00134 break; 00135 00136 case IRP_MJ_CLOSE : 00137 00138 // 00139 // Closes should never be posted. 00140 // 00141 00142 ASSERT( FALSE ); 00143 break; 00144 00145 case IRP_MJ_CREATE : 00146 00147 Status = UdfCommonCreate( IrpContext, Irp ); 00148 break; 00149 00150 case IRP_MJ_DEVICE_CONTROL : 00151 00152 Status = UdfCommonDevControl( IrpContext, Irp ); 00153 break; 00154 00155 case IRP_MJ_DIRECTORY_CONTROL : 00156 00157 Status = UdfCommonDirControl( IrpContext, Irp ); 00158 break; 00159 00160 case IRP_MJ_FILE_SYSTEM_CONTROL : 00161 00162 Status = UdfCommonFsControl( IrpContext, Irp ); 00163 break; 00164 00165 case IRP_MJ_LOCK_CONTROL : 00166 00167 Status = UdfCommonLockControl( IrpContext, Irp ); 00168 break; 00169 00170 case IRP_MJ_PNP : 00171 00172 ASSERT( FALSE ); 00173 Status = UdfCommonPnp( IrpContext, Irp ); 00174 break; 00175 00176 case IRP_MJ_QUERY_INFORMATION : 00177 00178 Status = UdfCommonQueryInfo( IrpContext, Irp ); 00179 break; 00180 00181 case IRP_MJ_QUERY_VOLUME_INFORMATION : 00182 00183 Status = UdfCommonQueryVolInfo( IrpContext, Irp ); 00184 break; 00185 00186 case IRP_MJ_READ : 00187 00188 Status = UdfCommonRead( IrpContext, Irp ); 00189 break; 00190 00191 case IRP_MJ_SET_INFORMATION : 00192 00193 Status = UdfCommonSetInfo( IrpContext, Irp ); 00194 break; 00195 00196 default : 00197 00198 Status = STATUS_INVALID_DEVICE_REQUEST; 00199 UdfCompleteRequest( IrpContext, Irp, Status ); 00200 } 00201 00202 } except( UdfExceptionFilter( IrpContext, GetExceptionInformation() )) { 00203 00204 Status = UdfProcessException( IrpContext, Irp, GetExceptionCode() ); 00205 } 00206 00207 // 00208 // Break out of the loop if we didn't get CANT_WAIT. 00209 // 00210 00211 if (Status != STATUS_CANT_WAIT) { break; } 00212 00213 // 00214 // We are retrying this request. Cleanup the IrpContext for the retry. 00215 // 00216 00217 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00218 UdfCleanupIrpContext( IrpContext, FALSE ); 00219 } 00220 00221 FsRtlExitFileSystem(); 00222 00223 // 00224 // If there are any entries on this volume's overflow queue, service 00225 // them. 00226 // 00227 00228 if (VolDo != NULL) { 00229 00230 KIRQL SavedIrql; 00231 PVOID Entry = NULL; 00232 00233 // 00234 // We have a volume device object so see if there is any work 00235 // left to do in its overflow queue. 00236 // 00237 00238 KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql ); 00239 00240 if (VolDo->OverflowQueueCount > 0) { 00241 00242 // 00243 // There is overflow work to do in this volume so we'll 00244 // decrement the Overflow count, dequeue the IRP, and release 00245 // the Event 00246 // 00247 00248 VolDo->OverflowQueueCount -= 1; 00249 00250 Entry = RemoveHeadList( &VolDo->OverflowQueue ); 00251 } 00252 00253 KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql ); 00254 00255 // 00256 // There wasn't an entry, break out of the loop and return to 00257 // the Ex Worker thread. 00258 // 00259 00260 if (Entry == NULL) { break; } 00261 00262 // 00263 // Extract the IrpContext , Irp, set wait to TRUE, and loop. 00264 // 00265 00266 IrpContext = CONTAINING_RECORD( Entry, 00267 IRP_CONTEXT, 00268 WorkQueueItem.List ); 00269 00270 Irp = IrpContext->Irp; 00271 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00272 00273 continue; 00274 } 00275 00276 break; 00277 } 00278 00279 // 00280 // Decrement the PostedRequestCount if there was a volume device object. 00281 // 00282 00283 if (VolDo) { 00284 00285 InterlockedDecrement( &VolDo->PostedRequestCount ); 00286 } 00287 00288 return; 00289 }


Generated on Sat May 15 19:43:46 2004 for test by doxygen 1.3.7