Ejemplo n.º 1
0
NTSTATUS
AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    LARGE_INTEGER cacheSizeBytes;
    AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
    OBJECT_ATTRIBUTES   stObjectAttribs;
    IO_STATUS_BLOCK stIoStatus;
    UNICODE_STRING uniServiceName;

    __Enter
    {

        //
        // First this is to load the library
        //

        RtlInitUnicodeString( &uniServiceName,
                              AFS_REDIR_LIBRARY_SERVICE_ENTRY);

        ntStatus = AFSLoadLibrary( 0,
                                   &uniServiceName);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n",
                          ntStatus));

            try_return( ntStatus);
        }

        //
        // Save off the cache file information
        //

        pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize;

        pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount;

        pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength;

        cacheSizeBytes = RedirInitInfo->ExtentCount;
        cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize;

        AFSDumpFileLocation.Length = 0;

        AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR));

        AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                        AFSDumpFileLocation.MaximumLength,
                                                                        AFS_GENERIC_MEMORY_23_TAG);

        if( AFSDumpFileLocation.Buffer == NULL)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n"));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlCopyMemory( AFSDumpFileLocation.Buffer,
                       L"\\??\\",
                       4 * sizeof( WCHAR));

        AFSDumpFileLocation.Length = 4 * sizeof( WCHAR);

        RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)],
                       (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset),
                       RedirInitInfo->DumpFileLocationLength);

        AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength;

        //
        // Be sure the shutdown flag is not set
        //

        ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);

        //
        // Set up the Throttles.
        //
        // Max IO is 10% of the cache, or the value in the registry,
        // with a minimum of 5Mb (and a maximum of 50% cache size)
        //
        if( AFSMaxDirectIo)
        {
            //
            // collect what the user
            //
            pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo;
            pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024);

        }
        else
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
        }

        if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204))
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204;

        }

        //
        // For small cache configurations ...
        //

        if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2)
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart  = cacheSizeBytes.QuadPart / 2;
        }

        //
        // Maximum Dirty is 50% of the cache, or the value in the
        // registry.  No minimum, maximum of 90% of cache size.
        //
        if (AFSMaxDirtyFile)
        {

            pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile;
            pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024);

        }
        else
        {

            pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2;

        }

        cacheSizeBytes.QuadPart *= 9;
        cacheSizeBytes.QuadPart  = cacheSizeBytes.QuadPart / 10;

        if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart)
        {
            pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart;
        }

        //
        // Store off any flags for the file system
        //

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES))
        {

            //
            // Hide files which begin with .
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES);
        }

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES))
        {

            //
            // Hide files which begin with .
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES);
        }

        //
	// Global Reparse Point Policy
	//

	pDevExt->Specific.RDR.ReparsePointPolicy = RedirInitInfo->GlobalReparsePointPolicy;

	//
        // Are we performing direct to service IO?
        //

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO))
        {

            //
            // Send IO requests directly to service
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO);
        }
        else
        {

            if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
                RedirInitInfo->MemoryCacheLength.QuadPart != 0)
            {

                ntStatus = STATUS_INSUFFICIENT_RESOURCES;

#ifdef AMD64
                pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
                                                              (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
                                                              RedirInitInfo->MemoryCacheLength.QuadPart);
#else
                pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
                                                              (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
                                                              RedirInitInfo->MemoryCacheLength.LowPart);
#endif

                if( pDevExt->Specific.RDR.CacheMdl != NULL)
                {

                    __try
                    {

                        MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
                                             KernelMode,
                                             IoModifyAccess);

                        pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
                                                                                               NormalPagePriority);
                    }
                    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
                    {

                        AFSDumpTraceFilesFnc();

                        IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
                        pDevExt->Specific.RDR.CacheMdl = NULL;
                    }

                    if( pDevExt->Specific.RDR.CacheMdl != NULL)
                    {
                        pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
                        ntStatus = STATUS_SUCCESS;
                    }

                }
            }

            if( !NT_SUCCESS( ntStatus) &&
                RedirInitInfo->CacheFileNameLength == 0)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
                              ntStatus));

                try_return( ntStatus);
            }

            if( pDevExt->Specific.RDR.CacheMdl == NULL)
            {

                if( RedirInitInfo->CacheFileNameLength == 0)
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector CacheMdl == NULL\n"));

                    try_return( ntStatus = STATUS_INVALID_PARAMETER);
                }

                //
                // Go open the cache file
                //

                pDevExt->Specific.RDR.CacheFile.Length = 0;
                pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));

                pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                                            pDevExt->Specific.RDR.CacheFile.MaximumLength,
                                                                                            AFS_GENERIC_MEMORY_24_TAG);

                if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n"));

                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                }

                RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
                               L"\\??\\",
                               4 * sizeof( WCHAR));

                pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);

                RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
                               RedirInitInfo->CacheFileName,
                               RedirInitInfo->CacheFileNameLength);

                pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;

                InitializeObjectAttributes( &stObjectAttribs,
                                            &pDevExt->Specific.RDR.CacheFile,
                                            OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                            NULL,
                                            NULL);

                ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
                                       GENERIC_READ | GENERIC_WRITE,
                                       &stObjectAttribs,
                                       &stIoStatus,
                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                                       FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
                                  ntStatus));

                    try_return( ntStatus);
                }

                //
                // Map to the fileobject
                //

                ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
                                                      SYNCHRONIZE,
                                                      NULL,
                                                      KernelMode,
                                                      (void **)&pDevExt->Specific.RDR.CacheFileObject,
                                                      NULL);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgTrace(( AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
                                  ntStatus));

                    try_return( ntStatus);
                }
            }
        }
Ejemplo n.º 2
0
NTSTATUS
AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    LARGE_INTEGER cacheSizeBytes;
    AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
    AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    OBJECT_ATTRIBUTES   stObjectAttribs;
    IO_STATUS_BLOCK stIoStatus;
    UNICODE_STRING uniServiceName;

    __Enter
    {

        //
        // First this is to load the library
        //

        RtlInitUnicodeString( &uniServiceName,
                              AFS_REDIR_LIBRARY_SERVICE_ENTRY);

        ntStatus = AFSLoadLibrary( 0,
                                   &uniServiceName);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n",
                          ntStatus);

            try_return( ntStatus);
        }

        //
        // Save off the cache file information
        //

        pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize;

        pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount;

        pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength;

        cacheSizeBytes = RedirInitInfo->ExtentCount;
        cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize;

        AFSDumpFileLocation.Length = 0;

        AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR));

        AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                        AFSDumpFileLocation.MaximumLength,
                                                                        AFS_GENERIC_MEMORY_23_TAG);

        if( AFSDumpFileLocation.Buffer == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlCopyMemory( AFSDumpFileLocation.Buffer,
                       L"\\??\\",
                       4 * sizeof( WCHAR));

        AFSDumpFileLocation.Length = 4 * sizeof( WCHAR);

        RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)],
                       (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset),
                       RedirInitInfo->DumpFileLocationLength);

        AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength;

        //
        // Be sure the shutdown flag is not set
        //

        ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);

        //
        // Set up the Throttles.
        //
        // Max IO is 10% of the cache, or the value in the registry,
        // with a minimum of 5Mb (and a maximum of 50% cache size)
        //
        if( AFSMaxDirectIo)
        {
            //
            // collect what the user
            //
            pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo;
            pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024);

        }
        else
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2;
        }

        if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204))
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204;

        }

        //
        // For small cache configurations ...
        //

        if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2)
        {

            pDevExt->Specific.RDR.MaxIo.QuadPart  = cacheSizeBytes.QuadPart / 2;
        }

        //
        // Maximum Dirty is 50% of the cache, or the value in the
        // registry.  No minimum, maximum of 90% of cache size.
        //
        if (AFSMaxDirtyFile)
        {

            pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile;
            pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024);

        }
        else
        {

            pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2;

        }

        cacheSizeBytes.QuadPart *= 9;
        cacheSizeBytes.QuadPart  = cacheSizeBytes.QuadPart / 10;

        if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart)
        {
            pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart;
        }

        //
        // Store off any flags for the file system
        //

        if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES))
        {

            //
            // Hide files which begin with .
            //

            SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES);
        }

        if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
            RedirInitInfo->MemoryCacheLength.QuadPart != 0)
        {

            ntStatus = STATUS_INSUFFICIENT_RESOURCES;

#ifdef AMD64
            pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
                                                          (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
                                                          RedirInitInfo->MemoryCacheLength.QuadPart);
#else
            pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
                                                          (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
                                                          RedirInitInfo->MemoryCacheLength.LowPart);
#endif

            if( pDevExt->Specific.RDR.CacheMdl != NULL)
            {

                __try
                {

                    MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
                                         KernelMode,
                                         IoModifyAccess);

                    pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
                                                                                           NormalPagePriority);
                }
                __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
                {
                    IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
                    pDevExt->Specific.RDR.CacheMdl = NULL;
                }

                if( pDevExt->Specific.RDR.CacheMdl != NULL)
                {
                    pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
                    ntStatus = STATUS_SUCCESS;
                }

            }
        }
Ejemplo n.º 3
0
NTSTATUS
AFSProcessControlRequest( IN PIRP Irp)
{

    NTSTATUS            ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION  pIrpSp;
    ULONG               ulIoControlCode;
    BOOLEAN             bCompleteRequest = TRUE;
    AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    ULONG               ulBytesProcessed = 0;

    __try
    {

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);

        ulIoControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;

        switch( ulIoControlCode)
        {

            case IOCTL_AFS_INITIALIZE_CONTROL_DEVICE:
            {

                //
                // Go intialize the pool
                //

                ntStatus = AFSInitIrpPool();

                if( !NT_SUCCESS( ntStatus))
                {

                    //
                    // Don't initialize
                    //

                    break;
                }

                //
                // Tag this instance as the one to close the irp pool when it is closed
                //

                pIrpSp->FileObject->FsContext = (void *)((ULONG_PTR)pIrpSp->FileObject->FsContext | AFS_CONTROL_INSTANCE);

                break;
            }

            case IOCTL_AFS_INITIALIZE_REDIRECTOR_DEVICE:
            {

                AFSRedirectorInitInfo *pRedirInitInfo = (AFSRedirectorInitInfo *)Irp->AssociatedIrp.SystemBuffer;

                //
                // Extract off the passed in information which contains the
                // cache file parameters
                //

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSRedirectorInitInfo) ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSRedirectorInitInfo, CacheFileName) +
                                                                                                    pRedirInitInfo->CacheFileNameLength)
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                //
                // Initialize the Redirector device
                //

                ntStatus = AFSInitializeRedirector( pRedirInitInfo);

                if( !NT_SUCCESS( ntStatus))
                {

                    break;
                }

                //
                // Stash away context so we know the instance used to initialize the redirector
                //

                pIrpSp->FileObject->FsContext = (void *)((ULONG_PTR)pIrpSp->FileObject->FsContext | AFS_REDIRECTOR_INSTANCE);

                break;
            }

            case IOCTL_AFS_PROCESS_IRP_REQUEST:
            {

                ntStatus = AFSProcessIrpRequest( Irp);

                break;
            }

            case IOCTL_AFS_PROCESS_IRP_RESULT:
            {

                ntStatus = AFSProcessIrpResult( Irp);

                break;
            }

            case IOCTL_AFS_SYSNAME_NOTIFICATION:
            {

                AFSSysNameNotificationCB *pSysNameInfo = (AFSSysNameNotificationCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pSysNameInfo == NULL ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSSysNameNotificationCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSSetSysNameInformation( pSysNameInfo,
                                                     pIrpSp->Parameters.DeviceIoControl.InputBufferLength);

                break;
            }

            case IOCTL_AFS_CONFIGURE_DEBUG_TRACE:
            {

                AFSTraceConfigCB *pTraceInfo = (AFSTraceConfigCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pTraceInfo == NULL ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSTraceConfigCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSConfigureTrace( pTraceInfo);

                break;
            }

            case IOCTL_AFS_GET_TRACE_BUFFER:
            {

                if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSGetTraceBuffer( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
                                              Irp->AssociatedIrp.SystemBuffer,
                                              &Irp->IoStatus.Information);

                break;
            }

            case IOCTL_AFS_FORCE_CRASH:
            {

#if DBG

                if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_ENABLE_FORCE_CRASH))
                {

                    KeBugCheck( (ULONG)-1);
                }
#endif

                break;
            }

#ifdef NOT_IMPLEMENTED
            case IOCTL_AFS_LOAD_LIBRARY:
            {

                AFSLoadLibraryCB *pLoadLib = (AFSLoadLibraryCB *)Irp->AssociatedIrp.SystemBuffer;
                UNICODE_STRING uniServicePath;

                if( pLoadLib == NULL ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLoadLibraryCB) ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSLoadLibraryCB, LibraryServicePath) +
                                                                                                    pLoadLib->LibraryServicePathLength)
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                uniServicePath.Length = pLoadLib->LibraryServicePathLength;
                uniServicePath.MaximumLength = uniServicePath.Length;

                uniServicePath.Buffer = pLoadLib->LibraryServicePath;

                if( uniServicePath.Length == 0)
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSLoadLibrary( pLoadLib->Flags,
                                           &uniServicePath);

                if( NT_SUCCESS( ntStatus))
                {

                    //
                    // Intialize the library
                    //

                    ntStatus = AFSInitializeLibrary( NULL,
                                                     FALSE);
                }

                break;
            }

            case IOCTL_AFS_UNLOAD_LIBRARY:
            {

                //
                // Try to unload the library we currently have in place
                //

                ntStatus = AFSUnloadLibrary( FALSE);

                break;
            }
#endif

            case IOCTL_AFS_SHUTDOWN:
            {

                ntStatus = AFSShutdownRedirector();

                break;
            }

            case IOCTL_AFS_AUTHGROUP_CREATE_AND_SET:
            {


                AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pAuthGroupRequestCB == NULL ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSCreateSetProcessAuthGroup( pAuthGroupRequestCB);

                break;
            }

            case IOCTL_AFS_AUTHGROUP_QUERY:
            {

                ntStatus = AFSQueryProcessAuthGroupList( ( GUID *)Irp->AssociatedIrp.SystemBuffer,
                                                         pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
                                                         &Irp->IoStatus.Information);

                break;
            }

            case IOCTL_AFS_AUTHGROUP_SET:
            {

                AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pAuthGroupRequestCB == NULL ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSSetActiveProcessAuthGroup( pAuthGroupRequestCB);

                break;
            }

            case IOCTL_AFS_AUTHGROUP_RESET:
            {

                AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pAuthGroupRequestCB == NULL ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSResetActiveProcessAuthGroup( pAuthGroupRequestCB);

                break;
            }

            case IOCTL_AFS_AUTHGROUP_LOGON_CREATE:
            case IOCTL_AFS_AUTHGROUP_SID_CREATE:
            {

                AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pAuthGroupRequestCB != NULL &&
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSCreateAuthGroupForSIDorLogonSession( pAuthGroupRequestCB,
                                                                   ulIoControlCode == IOCTL_AFS_AUTHGROUP_LOGON_CREATE);

                break;
            }

            case IOCTL_AFS_AUTHGROUP_SID_QUERY:
            {

                AFSAuthGroupRequestCB *pAuthGroupRequestCB = NULL;

                if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( GUID))
                {
                    ntStatus = STATUS_INVALID_PARAMETER;
                    break;
                }

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( AFSAuthGroupRequestCB))
                {
                    pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer;
                }

                ntStatus = AFSQueryAuthGroup( pAuthGroupRequestCB,
                                              (GUID *)Irp->AssociatedIrp.SystemBuffer,
                                              &Irp->IoStatus.Information);

                break;
            }

            default:
            {

                //
                // Check the state of the library
                //

                ntStatus = AFSCheckLibraryState( Irp);

                if( !NT_SUCCESS( ntStatus) ||
                    ntStatus == STATUS_PENDING)
                {

                    if( ntStatus == STATUS_PENDING)
                    {
                        bCompleteRequest = FALSE;
                    }

                    break;
                }

                bCompleteRequest = FALSE;

                IoSkipCurrentIrpStackLocation( Irp);

                ntStatus = IoCallDriver( pDevExt->Specific.Control.LibraryDeviceObject,
                                         Irp);

                //
                // Indicate the library is done with the request
                //

                AFSClearLibraryRequest();

                break;
            }
        }

//try_exit:

    }
    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
    {

        ntStatus = STATUS_UNSUCCESSFUL;

        AFSDumpTraceFilesFnc();
    }

    if( bCompleteRequest)
    {

        Irp->IoStatus.Status = ntStatus;

        AFSCompleteRequest( Irp,
                              ntStatus);
    }

    return ntStatus;
}