test: fspdisp.c Source File

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

# fspdisp.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1989  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     FspDisp.c
    00008
    00009 Abstract:
    00010
    00011     This module implements the main dispatch procedure/thread for the Udfs
    00012     Fsp
    00013
    00014 Author:
    00015
    00016     Dan Lovinger    [DanLo]     23-Sep-1996
    00017
    00018 Revision History:
    00019
    00020 --*/
    00021
    00022 #include "UdfProcs.h"
    00023
    00024 //
    00025 //  The Bug check file id for this module
    00026 //
    00027
    00028 #define BugCheckFileId                   (UDFS_BUG_CHECK_FSPDISP)
    00029
    00030 //
    00031 //  The local debug trace level
    00032 //
    00033
    00034 #define Dbg                              (UDFS_DEBUG_LEVEL_FSPDISP)
    00035
    00036
    00037 VOID
    00038 UdfFspDispatch (
    00039     IN PIRP_CONTEXT IrpContext
    00040     )
    00041
    00042 /*++
    00043
    00044 Routine Description:
    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 }
    00290
    00291
    00292