Example #1
0
NTSTATUS
AFSFlushBuffers( IN PDEVICE_OBJECT DeviceObject,
                 IN PIRP Irp)
{

    NTSTATUS      ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;

    __Enter
    {

        if( DeviceObject == AFSDeviceObject)
        {

            ntStatus = STATUS_INVALID_DEVICE_REQUEST;

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

        NOTHING;
    }

    return ntStatus;
}
Example #2
0
NTSTATUS
AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
                  IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    IO_STACK_LOCATION *pIrpSp;

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __try
    {

        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                      AFS_TRACE_LEVEL_WARNING,
                      "AFSSetVolumeInfo Entry for FO %08lX\n", pIrpSp->FileObject);

        AFSCompleteRequest( Irp,
                            ntStatus);

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

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSSetVolumeInfo\n");

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #3
0
NTSTATUS
AFSSetEA( IN PDEVICE_OBJECT LibDeviceObject,
          IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_EAS_NOT_SUPPORTED;
    IO_STACK_LOCATION *pIrpSp;

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __try
    {

        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                      AFS_TRACE_LEVEL_ERROR,
                      "AFSSetEa Entry for FO %08lX\n", pIrpSp->FileObject);

        AFSCompleteRequest( Irp,
                            ntStatus);

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

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSSetEA\n");
    }

    return ntStatus;
}
Example #4
0
NTSTATUS
AFSFSControl( IN PDEVICE_OBJECT LibDeviceObject,
              IN PIRP Irp)
{

    UNREFERENCED_PARAMETER(LibDeviceObject);
    NTSTATUS ntStatus = STATUS_SUCCESS;
    IO_STACK_LOCATION *pIrpSp;

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __try
    {

        switch( pIrpSp->MinorFunction)
        {

            case IRP_MN_USER_FS_REQUEST:

                ntStatus = AFSProcessUserFsRequest( Irp);

                break;

            case IRP_MN_MOUNT_VOLUME:

                break;

            case IRP_MN_VERIFY_VOLUME:

                break;

            default:

                break;
        }

        AFSCompleteRequest( Irp,
                              ntStatus);

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

        AFSDbgTrace(( 0,
                      0,
                      "EXCEPTION - AFSFSControl\n"));

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #5
0
NTSTATUS
AFSControlDeviceCreate( IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;

    __Enter
    {

        //
        // For now, jsut let the open happen
        //

        Irp->IoStatus.Information = FILE_OPENED;

        AFSCompleteRequest( Irp, ntStatus);
    }

    return ntStatus;
}
Example #6
0
NTSTATUS
AFSClose( IN PDEVICE_OBJECT DeviceObject,
          IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;

    __try
    {

        if( DeviceObject == AFSDeviceObject)
        {

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

        ntStatus = AFSCommonClose( DeviceObject,
                                   Irp);

try_exit:

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

        AFSDbgTrace(( 0,
                      0,
                      "EXCEPTION - AFSClose\n"));

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #7
0
NTSTATUS
AFSWrite( IN PDEVICE_OBJECT DeviceObject,
          IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;

    __try
    {

        if( DeviceObject == AFSDeviceObject)
        {

            ntStatus = STATUS_INVALID_DEVICE_REQUEST;

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {

                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        //
        // Increment the outstanding IO count again - this time for the
        // completion routine.
        //

        ntStatus = AFSCheckLibraryState( Irp);

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

            AFSClearLibraryRequest();

            if( ntStatus != STATUS_PENDING)
            {

                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        //
        // And send it down, but arrange to capture the comletion
        // so we can free our lock against unloading.
        //

        IoCopyCurrentIrpStackLocationToNext( Irp);

        AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "Setting AFSWriteComplete as IoCompletion Routine Irp %p\n",
                      Irp));

        IoSetCompletionRoutine( Irp, AFSWriteComplete, NULL, TRUE, TRUE, TRUE);

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

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

        AFSClearLibraryRequest();

try_exit:

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

        ntStatus = STATUS_INSUFFICIENT_RESOURCES;

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #8
0
NTSTATUS
AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                 IN PIRP Irp)
{

    NTSTATUS            ntStatus = STATUS_SUCCESS;
    FILE_OBJECT        *pFileObject = NULL;
    IO_STACK_LOCATION  *pIrpSp;
    AFSDeviceExt       *pDeviceExt = NULL;
    AFSDeviceExt       *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    GUID               *pAuthGroup = NULL;
    UNICODE_STRING uniGUIDString;

    __Enter
    {

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);
        pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
        pFileObject = pIrpSp->FileObject;

        uniGUIDString.Buffer = NULL;
        uniGUIDString.Length = 0;
        uniGUIDString.MaximumLength = 0;

        //
        // Validate the process entry
        //

        pAuthGroup = AFSValidateProcessEntry();

        if( pAuthGroup != NULL)
        {

            RtlStringFromGUID( *pAuthGroup,
                               &uniGUIDString);

            AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s (%08lX) Located AuthGroup %wZ after validation\n",
                          __FUNCTION__,
                          Irp,
                          &uniGUIDString);

        }
        else
        {
            AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s (%08lX) Failed to locate AuthGroup\n",
                          __FUNCTION__,
                          Irp);
        }

        //
        // Root open?
        //

        if( pFileObject == NULL ||
            pFileObject->FileName.Buffer == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSCommonCreate (%08lX) Processing volume open request\n",
                          Irp);

            ntStatus = AFSOpenRedirector( Irp);

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }


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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

        if ( pFileObject) {
            AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s (%08lX) File \"%wZ\" AuthGroup '%wZ' ntStatus %08lX\n",
                          __FUNCTION__,
                          Irp,
                          &pFileObject->FileName,
                          &uniGUIDString,
                          ntStatus);
        }

        if( uniGUIDString.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUIDString);
        }
    }

    return ntStatus;
}
Example #9
0
NTSTATUS
AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject,
                 IN PIRP Irp)
{

    UNREFERENCED_PARAMETER(LibDeviceObject);
    AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
    NTSTATUS           ntStatus = STATUS_SUCCESS;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    PFILE_OBJECT       pFileObject = pIrpSp->FileObject;
    AFSFcb            *pFcb = (AFSFcb *)pFileObject->FsContext;
    AFSCcb            *pCcb = (AFSCcb *)pFileObject->FsContext2;
    IO_STATUS_BLOCK    iosb = {0};
    BOOLEAN            bReleaseSectionObject = FALSE;

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __Enter
    {

        if( pFcb == NULL)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSFlushBuffers Attempted access (%p) when pFcb == NULL\n",
                          Irp));

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

        if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
            pFcb->Header.NodeTypeCode == AFS_ROOT_ALL )
        {

            //
            // Once we support ADS's on directories we need to perform a flush ehre
            //

            try_return( ntStatus = STATUS_SUCCESS);

        }
        else if (pFcb->Header.NodeTypeCode != AFS_FILE_FCB)
        {
            //
            // Nothing to flush Everything but files are write through
            //
            try_return( ntStatus = STATUS_INVALID_PARAMETER);
        }

	AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSFlushBuffers Acquiring Fcb SectionObject lock %p SHARED %08lX\n",
                      &pFcb->NPFcb->SectionObjectResource,
                      PsGetCurrentThread()));

        AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
                          TRUE);

        bReleaseSectionObject = TRUE;

        //
        // The flush consists of two parts.  We firstly flush our
        // cache (if we have one), then we tell the service to write
        // to the remote server
        //
        __try
        {

            CcFlushCache( &pFcb->NPFcb->SectionObjectPointers, NULL, 0, &iosb);

            if (!NT_SUCCESS( iosb.Status ))
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "AFSFlushBuffers CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                              pFcb->ObjectInformation->FileId.Cell,
                              pFcb->ObjectInformation->FileId.Volume,
                              pFcb->ObjectInformation->FileId.Vnode,
                              pFcb->ObjectInformation->FileId.Unique,
                              iosb.Status,
                              iosb.Information));

                try_return( ntStatus = iosb.Status );
            }
        }
	__except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
        {

            try_return( ntStatus = GetExceptionCode());
        }

	if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
	{

	    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
			  AFS_TRACE_LEVEL_VERBOSE,
			  "AFSFlushBuffers Releasing Fcb SectionObject lock %p SHARED %08lX\n",
			  &pFcb->NPFcb->SectionObjectResource,
			  PsGetCurrentThread()));

	    AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);

	    bReleaseSectionObject = FALSE;

	    //
	    // Now, flush to the server - if there is stuff to do
	    //

	    ntStatus = AFSFlushExtents( pFcb,
					&pCcb->AuthGroup);

	    if( !NT_SUCCESS( ntStatus))
	    {

		AFSReleaseExtentsWithFlush( pFcb,
					    &pCcb->AuthGroup,
					    TRUE);

		ntStatus = STATUS_SUCCESS;
	    }
	}

try_exit:

        if ( bReleaseSectionObject)
        {

	    AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSFlushBuffers Releasing Fcb SectionObject lock %p SHARED %08lX\n",
                          &pFcb->NPFcb->SectionObjectResource,
                          PsGetCurrentThread()));

            AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
        }

        AFSCompleteRequest( Irp, ntStatus);
    }

    return ntStatus;
}
Example #10
0
NTSTATUS
AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
{

    NTSTATUS           ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    PFILE_OBJECT       pFileObject = pIrpSp->FileObject;
    BOOLEAN            bCompleteIrp = TRUE;

    __Enter
    {

        switch( pIrpSp->Parameters.DeviceIoControl.IoControlCode)
        {

            case IOCTL_REDIR_QUERY_PATH:
            {

                QUERY_PATH_REQUEST *pPathRequest = (QUERY_PATH_REQUEST *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
                QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer;
                UNICODE_STRING uniPathName;

                ntStatus = STATUS_BAD_NETWORK_PATH;

                uniPathName.Length = (USHORT)pPathRequest->PathNameLength;
                uniPathName.MaximumLength = uniPathName.Length;

                uniPathName.Buffer = pPathRequest->FilePathName;

                if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR))
                {

                    USHORT usLength = uniPathName.Length;

                    uniPathName.Length = AFSServerName.Length;

                    //
                    // Skip over the first slash in the name
                    //

                    uniPathName.Buffer = &uniPathName.Buffer[ 1];


                    //
                    // Check to see if the first (or only) component
                    // of the path matches the server name
                    //

                    if( RtlCompareUnicodeString( &AFSServerName,
                                                 &uniPathName,
                                                 TRUE) == 0 &&
                        ( usLength == AFSServerName.Length + sizeof( WCHAR) ||
                          uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\'))
                    {

                        ntStatus = STATUS_SUCCESS;

                        pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR);
                    }
                }

                break;
            }

            case IOCTL_REDIR_QUERY_PATH_EX:
            {

                QUERY_PATH_REQUEST_EX *pPathRequest = (QUERY_PATH_REQUEST_EX *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
                QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer;
                UNICODE_STRING uniPathName;

                ntStatus = STATUS_BAD_NETWORK_PATH;

                uniPathName.Length = pPathRequest->PathName.Length;
                uniPathName.MaximumLength = uniPathName.Length;

                uniPathName.Buffer = pPathRequest->PathName.Buffer;

                if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR))
                {

                    USHORT usLength = uniPathName.Length;

                    uniPathName.Length = AFSServerName.Length;

                    //
                    // Skip over the first slash in the name
                    //

                    uniPathName.Buffer = &uniPathName.Buffer[ 1];


                    //
                    // Check to see if the first (or only) component
                    // of the path matches the server name
                    //

                    if( RtlCompareUnicodeString( &AFSServerName,
                                                 &uniPathName,
                                                 TRUE) == 0 &&
                        ( usLength == AFSServerName.Length + sizeof( WCHAR) ||
                          uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\'))
                    {

                        ntStatus = STATUS_SUCCESS;

                        pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR);
                    }
                }

                break;
            }

            default:

                ntStatus = STATUS_INVALID_DEVICE_REQUEST;

                break;
        }

        if (bCompleteIrp)
        {
            //
            // Complete the request
            //

            AFSCompleteRequest( Irp,
                                ntStatus);
        }
    }

    return ntStatus;
}
Example #11
0
NTSTATUS
AFSCleanup( IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __try
    {

        //
        // Set some initial variables to make processing easier
        //

        if( DeviceObject == AFSDeviceObject)
        {

            if( FlagOn( (ULONG_PTR)pIrpSp->FileObject->FsContext, AFS_CONTROL_INSTANCE))
            {

                //
                // This is the process which was registered for the callback pool so cleanup the pool
                //

                AFSCleanupIrpPool();
            }

            if( FlagOn( (ULONG_PTR)pIrpSp->FileObject->FsContext, AFS_REDIRECTOR_INSTANCE))
            {

                //
                // Close the redirector
                //

                AFSCloseRedirector();
            }

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

        ntStatus = AFSCommonCleanup( DeviceObject,
                                     Irp);

try_exit:

        NOTHING;
    }
    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
    {

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSCleanup\n");
    }

    return ntStatus;
}
Example #12
0
NTSTATUS
AFSDevControl( IN PDEVICE_OBJECT LibDeviceObject,
               IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    IO_STACK_LOCATION *pIrpSp;
    ULONG               ulIoControlCode;

    __try
    {

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);

        ulIoControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;

        switch( ulIoControlCode)
        {

            case IOCTL_AFS_INITIALIZE_LIBRARY_DEVICE:
            {

                AFSLibraryInitCB *pLibInitCB = (AFSLibraryInitCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLibraryInitCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSInitializeLibrary( pLibInitCB);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSDevControl AFSInitializeLibrary failure %08lX\n",
                                  ntStatus);

                    break;
                }

                //
                // Initialize our global entries
                //

                ntStatus = AFSInitializeGlobalDirectoryEntries();

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSDevControl AFSInitializeGlobalDirectoryEntries failure %08lX\n",
                                  ntStatus);

                    break;
                }

                ntStatus = AFSInitializeSpecialShareNameList();

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                                  AFS_TRACE_LEVEL_ERROR,
                                  "AFSDevControl AFSInitializeSpecialShareNameList failure %08lX\n",
                                  ntStatus);

                    break;
                }

                break;
            }

            case IOCTL_AFS_ADD_CONNECTION:
            {

                AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSNetworkProviderConnectionCB, RemoteName) +
                                                                                                            pConnectCB->RemoteNameLength ||
                    pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( ULONG))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSAddConnection( pConnectCB,
                                             (PULONG)Irp->AssociatedIrp.SystemBuffer,
                                             &Irp->IoStatus.Information);

                break;
            }

            case IOCTL_AFS_CANCEL_CONNECTION:
            {

                AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSCancelConnection( pConnectCB,
                                                (AFSCancelConnectionResultCB *)Irp->AssociatedIrp.SystemBuffer,
                                                &Irp->IoStatus.Information);

                break;
            }

            case IOCTL_AFS_GET_CONNECTION:
            {

                AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
                    pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

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

                break;
            }

            case IOCTL_AFS_LIST_CONNECTIONS:
            {

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

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

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

                break;
            }

            case IOCTL_AFS_GET_CONNECTION_INFORMATION:
            {

                AFSNetworkProviderConnectionCB *pConnectCB = (AFSNetworkProviderConnectionCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkProviderConnectionCB) ||
                    pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0)
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSGetConnectionInfo( pConnectCB,
                                                 pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
                                                 &Irp->IoStatus.Information);

                break;
            }

            case IOCTL_AFS_SET_FILE_EXTENTS:
            {

                AFSSetFileExtentsCB *pExtents = (AFSSetFileExtentsCB*) Irp->AssociatedIrp.SystemBuffer;

                //
                // Check lengths twice so that if the buffer makes the
                // count invalid we will not Accvio
                //

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
                    ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG)) ||
                    pIrpSp->Parameters.DeviceIoControl.InputBufferLength <
                    ( FIELD_OFFSET( AFSSetFileExtentsCB, ExtentCount) + sizeof(ULONG) +
                      sizeof (AFSFileExtentCB) * pExtents->ExtentCount))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSProcessSetFileExtents( pExtents );

                Irp->IoStatus.Information = 0;
                Irp->IoStatus.Status = ntStatus;

                break;
            }

            case IOCTL_AFS_RELEASE_FILE_EXTENTS:
            {
                ntStatus = AFSProcessReleaseFileExtents( Irp);
                break;
            }

            case IOCTL_AFS_SET_FILE_EXTENT_FAILURE:
            {

                ntStatus = AFSProcessExtentFailure( Irp);

                break;
            }

            case IOCTL_AFS_INVALIDATE_CACHE:
            {

                AFSInvalidateCacheCB *pInvalidate = (AFSInvalidateCacheCB*)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSInvalidateCacheCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSInvalidateCache( pInvalidate);

                Irp->IoStatus.Information = 0;
                Irp->IoStatus.Status = ntStatus;

                break;
            }

            case IOCTL_AFS_NETWORK_STATUS:
            {

                AFSNetworkStatusCB *pNetworkStatus = (AFSNetworkStatusCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSNetworkStatusCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                //
                // Set the network status
                //

                ntStatus = AFSSetNetworkState( pNetworkStatus);

                Irp->IoStatus.Information = 0;
                Irp->IoStatus.Status = ntStatus;

                break;
            }

            case IOCTL_AFS_VOLUME_STATUS:
            {

                AFSVolumeStatusCB *pVolumeStatus = (AFSVolumeStatusCB *)Irp->AssociatedIrp.SystemBuffer;

                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSVolumeStatusCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSSetVolumeState( pVolumeStatus);

                Irp->IoStatus.Information = 0;
                Irp->IoStatus.Status = ntStatus;

                break;
            }

            case IOCTL_AFS_STATUS_REQUEST:
            {

                if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSDriverStatusRespCB))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSGetDriverStatus( (AFSDriverStatusRespCB *)Irp->AssociatedIrp.SystemBuffer);

                Irp->IoStatus.Information = sizeof( AFSDriverStatusRespCB);

                break;
            }

            case IOCTL_AFS_GET_OBJECT_INFORMATION:
            {


                if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSGetStatusInfoCB) ||
                    pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( AFSStatusInfoCB))

                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                ntStatus = AFSGetObjectStatus( (AFSGetStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
                                               pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
                                               (AFSStatusInfoCB *)Irp->AssociatedIrp.SystemBuffer,
                                               (ULONG *)&Irp->IoStatus.Information);

                break;
            }

            case 0x140390:      // IOCTL_LMR_DISABLE_LOCAL_BUFFERING
            {
                //
                // See http://msdn.microsoft.com/en-us/library/ee210753%28v=vs.85%29.aspx
                //
                // The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code is defined internally by
                // the system as 0x140390 and not in a public header file. It is used by
                // special-purpose applications to disable local client-side in-memory
                // caching of data when reading data from or writing data to a remote file.
                // After local buffering is disabled, the setting remains in effect until all
                // open handles to the file are closed and the redirector cleans up its internal
                // data structures.
                //
                // General-purpose applications should not use IOCTL_LMR_DISABLE_LOCAL_BUFFERING,
                // because it can result in excessive network traffic and associated loss of
                // performance. The IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code should be used
                // only in specialized applications moving large amounts of data over the network
                // while attempting to maximize use of network bandwidth. For example, the CopyFile
                // and CopyFileEx functions use IOCTL_LMR_DISABLE_LOCAL_BUFFERING to improve large
                // file copy performance.
                //
                // IOCTL_LMR_DISABLE_LOCAL_BUFFERING is not implemented by local file systems and
                // will fail with the error ERROR_INVALID_FUNCTION. Issuing the
                // IOCTL_LMR_DISABLE_LOCAL_BUFFERING control code on remote directory handles will
                // fail with the error ERROR_NOT_SUPPORTED.
                //

                ntStatus = STATUS_NOT_SUPPORTED;

                break;
            }

         default:
            {

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }
        }

//try_exit:

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

        ntStatus = STATUS_UNSUCCESSFUL;

        AFSDumpTraceFilesFnc();
    }

    Irp->IoStatus.Status = ntStatus;

    AFSCompleteRequest( Irp,
                        ntStatus);

    return ntStatus;
}
Example #13
0
NTSTATUS
AFSCommonClose( IN PDEVICE_OBJECT DeviceObject,
                IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    AFSDeviceExt *pDeviceExt = NULL;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    AFSFcb* pFcb = NULL;

    __Enter
    {

        pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);

        pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext;

        if( pFcb == NULL ||
            pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB)
        {

            AFSCompleteRequest( Irp, ntStatus);

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

        NOTHING;
    }

    return ntStatus;
}
Example #14
0
NTSTATUS
AFSCommonCleanup( IN PDEVICE_OBJECT DeviceObject,
                  IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    PFILE_OBJECT pFileObject = NULL;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    BOOLEAN bCompleteRequest = TRUE;

    __Enter
    {

        //
        // Set some initial variables to make processing easier
        //

        pFileObject = pIrpSp->FileObject;

        if( pIrpSp->FileObject->FsContext == NULL)
        {

            //
            // Root open
            //

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

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

            try_return( ntStatus);
        }

        bCompleteRequest = FALSE;

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

        if( bCompleteRequest)
        {

            if( pFileObject != NULL)
            {

                //
                // Setup the fileobject flags to indicate cleanup is complete.
                //

                SetFlag( pFileObject->Flags, FO_CLEANUP_COMPLETE);
            }

            //
            // Complete the request
            //

            AFSCompleteRequest( Irp, ntStatus);
        }
    }

    return ntStatus;
}
Example #15
0
NTSTATUS
AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject,
                 IN PIRP Irp)
{

    NTSTATUS           ntStatus = STATUS_SUCCESS;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    PFILE_OBJECT       pFileObject = pIrpSp->FileObject;
    AFSFcb            *pFcb = (AFSFcb *)pFileObject->FsContext;
    AFSCcb            *pCcb = (AFSCcb *)pFileObject->FsContext2;
    IO_STATUS_BLOCK    iosb = {0};

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __Enter
    {

        if( pFcb == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSFlushBuffers Attempted access (%08lX) when pFcb == NULL\n",
                          Irp);

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

        if( pFcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
            pFcb->Header.NodeTypeCode == AFS_ROOT_ALL )
        {

            //
            // Once we support ADS's on directories we need to perform a flush ehre
            //

            try_return( ntStatus = STATUS_SUCCESS);

        }
        else if (pFcb->Header.NodeTypeCode != AFS_FILE_FCB)
        {
            //
            // Nothing to flush Everything but files are write through
            //
            try_return( ntStatus = STATUS_INVALID_PARAMETER);
        }
        //
        // The flush consists of two parts.  We firstly flush our
        // cache (if we have one), then we tell the service to write
        // to the remote server
        //
        __try
        {

            CcFlushCache( &pFcb->NPFcb->SectionObjectPointers, NULL, 0, &iosb);

            if (!NT_SUCCESS( iosb.Status ))
            {

                AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "AFSFlushBuffers CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                              pFcb->ObjectInformation->FileId.Cell,
                              pFcb->ObjectInformation->FileId.Volume,
                              pFcb->ObjectInformation->FileId.Vnode,
                              pFcb->ObjectInformation->FileId.Unique,
                              iosb.Status,
                              iosb.Information);

                try_return( ntStatus = iosb.Status );
            }
        }
        __except( EXCEPTION_EXECUTE_HANDLER)
        {

            try_return( ntStatus = GetExceptionCode());
        }
        //
        // Now, flush to the server - if there is stuff to do
        //

        ntStatus = AFSFlushExtents( pFcb,
                                    &pCcb->AuthGroup);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSReleaseExtentsWithFlush( pFcb,
                                        &pCcb->AuthGroup);

            ntStatus = STATUS_SUCCESS;
        }

try_exit:

        AFSCompleteRequest( Irp, ntStatus);
    }

    return ntStatus;
}
Example #16
0
NTSTATUS
AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject,
            IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pDeviceExt = NULL;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    AFSFcb *pFcb = NULL;
    AFSCcb *pCcb = NULL;
    PFILE_OBJECT pFileObject = NULL;
    AFSFcb *pRootFcb = NULL;
    AFSDeviceExt *pControlDeviceExt = NULL;
    IO_STATUS_BLOCK stIoSB;
    AFSObjectInfoCB *pObjectInfo = NULL;
    AFSFileCleanupCB stFileCleanup;
    ULONG   ulNotificationFlags = 0;

    __try
    {

        if( AFSRDRDeviceObject == NULL)
        {

            //
            // Let this through, it's a cleanup on the library control device
            //

            try_return( ntStatus);
        }

        pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
        pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;

        //
        // Set some initial variables to make processing easier
        //

        pFileObject = pIrpSp->FileObject;

        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;

        pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;

        if( pFcb == NULL)
        {
            try_return( ntStatus);
        }

        pObjectInfo = pFcb->ObjectInformation;

        pRootFcb = pObjectInfo->VolumeCB->RootFcb;

        RtlZeroMemory( &stFileCleanup,
                       sizeof( AFSFileCleanupCB));

        stFileCleanup.ProcessId = (ULONGLONG)PsGetCurrentProcessId();

        stFileCleanup.Identifier = (ULONGLONG)pFileObject;

        //
        // Perform the cleanup functionality depending on the type of node it is
        //

        switch( pFcb->Header.NodeTypeCode)
        {

            case AFS_ROOT_ALL:
            {

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup Acquiring GlobalRoot lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                  TRUE);

                ASSERT( pFcb->OpenHandleCount != 0);

                InterlockedDecrement( &pFcb->OpenHandleCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (RootAll) Decrement handle count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenHandleCount);

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync,
                                    &pControlDeviceExt->Specific.Control.DirNotifyList,
                                    pCcb);

                break;
            }

            case AFS_IOCTL_FCB:
            {

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup Acquiring PIOCtl lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                  TRUE);

                ASSERT( pFcb->OpenHandleCount != 0);

                InterlockedDecrement( &pFcb->OpenHandleCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (IOCtl) Decrement handle count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenHandleCount);

                //
                // Decrement the open child handle count
                //

                if( pObjectInfo->ParentObjectInformation != NULL &&
                    pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
                {

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup (IOCtl) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
                }

                //
                // And finally, release the Fcb if we acquired it.
                //

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                break;
            }

            //
            // This Fcb represents a file
            //

            case AFS_FILE_FCB:
            {

                //
                // We may be performing some cleanup on the Fcb so grab it exclusive to ensure no collisions
                //

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup Acquiring Fcb lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                TRUE);

                //
                // If the handle has write permission ...
                //

                if( (pCcb->GrantedAccess & FILE_WRITE_DATA) &&
                    CcIsFileCached( pIrpSp->FileObject))
                {

                    __try
                    {

                        CcFlushCache( &pFcb->NPFcb->SectionObjectPointers,
                                      NULL,
                                      0,
                                      &stIoSB);

                        if( !NT_SUCCESS( stIoSB.Status))
                        {

                            AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
                                          AFS_TRACE_LEVEL_ERROR,
                                          "AFSCleanup CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
                                          &pCcb->FullFileName,
                                          pObjectInfo->FileId.Cell,
                                          pObjectInfo->FileId.Volume,
                                          pObjectInfo->FileId.Vnode,
                                          pObjectInfo->FileId.Unique,
                                          stIoSB.Status,
                                          stIoSB.Information);

                            ntStatus = stIoSB.Status;
                        }
                    }
                    __except( EXCEPTION_EXECUTE_HANDLER)
                    {

                        ntStatus = GetExceptionCode();
                    }
                }

                //
                // Uninitialize the cache map. This call is unconditional.
                //

                AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup Tearing down cache map for Fcb %08lX FileObject %08lX\n",
                              pFcb,
                              pFileObject);

                CcUninitializeCacheMap( pFileObject,
                                        NULL,
                                        NULL);

                //
                // Unlock all outstanding locks on the file, again, unconditionally
                //

                (VOID) FsRtlFastUnlockAll( &pFcb->Specific.File.FileLock,
                                           pFileObject,
                                           IoGetRequestorProcess( Irp),
                                           NULL);

                //
                // Tell the service to unlock all on the file
                //

                ulNotificationFlags |= AFS_REQUEST_FLAG_BYTE_RANGE_UNLOCK_ALL;

                //
                // Perform some final common processing
                //

                ASSERT( pFcb->OpenHandleCount != 0);

                InterlockedDecrement( &pFcb->OpenHandleCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (File) Decrement handle count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenHandleCount);

                if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
                {

                    stFileCleanup.ParentId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
                }

                stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;

                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                {

                    stFileCleanup.AllocationSize = pObjectInfo->EndOfFile;

                    stFileCleanup.FileAttributes = pObjectInfo->FileAttributes;

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME))
                    {

                        stFileCleanup.CreateTime = pObjectInfo->CreationTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME))
                    {

                        stFileCleanup.ChangeTime = pObjectInfo->ChangeTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME))
                    {

                        stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME))
                    {

                        stFileCleanup.LastWriteTime = pObjectInfo->LastWriteTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME | AFS_FCB_FLAG_UPDATE_WRITE_TIME);
                    }
                }

                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_WRITE_TIME))
                {

                    stFileCleanup.LastWriteTime = pObjectInfo->LastWriteTime;
                }

                //
                // If the count has dropped to zero and there is a pending delete
                // then delete the node
                //

                if( pFcb->OpenHandleCount == 0 &&
                    BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                {

                    //
                    // Stop anything possibly in process
                    //

                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup Acquiring Fcb extents lock %08lX EXCL %08lX\n",
                                  &pFcb->NPFcb->Specific.File.ExtentsResource,
                                  PsGetCurrentThread());

                    AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
                                    TRUE);

                    pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;

                    KeSetEvent( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
                                0,
                                FALSE);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup Releasing Fcb extents lock %08lX EXCL %08lX\n",
                                  &pFcb->NPFcb->Specific.File.ExtentsResource,
                                  PsGetCurrentThread());

                    AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);

                    //
                    // Before telling the server about the deleted file, tear down all extents for
                    // the file
                    //

                    AFSTearDownFcbExtents( pFcb,
                                           &pCcb->AuthGroup);

                    ntStatus = STATUS_SUCCESS;

                    ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED;

                    //
                    // Indicate the file access mode that is being released
                    //

                    stFileCleanup.FileAccess = pCcb->FileAccess;

                    //
                    // Push the request to the service
                    //

                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
                                                  ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
                                                  &pCcb->AuthGroup,
                                                  &pCcb->DirectoryCB->NameInformation.FileName,
                                                  &pObjectInfo->FileId,
                                                  &stFileCleanup,
                                                  sizeof( AFSFileCleanupCB),
                                                  NULL,
                                                  NULL);

                    if( !NT_SUCCESS( ntStatus) &&
                        ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
                    {

                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_ERROR,
                                      "AFSCleanup Failed to notify service of deleted file %wZ Status %08lX\n",
                                      &pCcb->FullFileName,
                                      ntStatus);

                        ntStatus = STATUS_SUCCESS;

                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
                    }
                    else
                    {

                        ntStatus = STATUS_SUCCESS;

                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_VERBOSE,
                                      "AFSCleanup Setting DELETE flag in file %wZ Dir Entry %p\n",
                                      &pCcb->FullFileName,
                                      pCcb->DirectoryCB);

                        SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);

                        ASSERT( pObjectInfo->ParentObjectInformation != NULL);

                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
                                                        pCcb,
                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
                                                        (ULONG)FILE_ACTION_REMOVED);

                        //
                        // Now that the service has the entry has deleted we need to remove it from the parent
                        // tree so another lookup on the node will fail
                        //

                        if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
                        {

                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                            TRUE);

                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                          AFS_TRACE_LEVEL_VERBOSE,
                                          "AFSCleanup DE %p for %wZ removing entry\n",
                                          pCcb->DirectoryCB,
                                          &pCcb->DirectoryCB->NameInformation.FileName);

                            AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
                                                pCcb->DirectoryCB);

                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                        }
                        else
                        {

                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                          AFS_TRACE_LEVEL_VERBOSE,
                                          "AFSCleanup DE %p for %wZ NOT removing entry due to flag set\n",
                                          pCcb->DirectoryCB,
                                          &pCcb->DirectoryCB->NameInformation.FileName);
                        }
                    }
                }
                else
                {

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                    {

                        ULONG ulNotifyFilter = 0;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);

                        ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES);

                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
                                                        pCcb,
                                                        (ULONG)ulNotifyFilter,
                                                        (ULONG)FILE_ACTION_MODIFIED);
                    }

                    //
                    // Attempt to flush any dirty extents to the server. This may be a little
                    // aggressive, to flush whenever the handle is closed, but it ensures
                    // coherency.
                    //

                    if( (pCcb->GrantedAccess & FILE_WRITE_DATA) &&
                        pFcb->Specific.File.ExtentsDirtyCount != 0)
                    {

                        AFSFlushExtents( pFcb,
                                         &pCcb->AuthGroup);
                    }

                    if( pFcb->OpenHandleCount == 0)
                    {

                        //
                        // Wait for any outstanding queued flushes to complete
                        //

                        AFSWaitOnQueuedFlushes( pFcb);

                        ulNotificationFlags |= AFS_REQUEST_FLAG_FLUSH_FILE;
                    }

                    //
                    // Indicate the file access mode that is being released
                    //

                    stFileCleanup.FileAccess = pCcb->FileAccess;

                    //
                    // Push the request to the service
                    //

                    AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
                                       ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
                                       &pCcb->AuthGroup,
                                       &pCcb->DirectoryCB->NameInformation.FileName,
                                       &pObjectInfo->FileId,
                                       &stFileCleanup,
                                       sizeof( AFSFileCleanupCB),
                                       NULL,
                                       NULL);
                }

                //
                // Remove the share access at this time since we may not get the close for sometime on this FO.
                //

                IoRemoveShareAccess( pFileObject,
                                     &pFcb->ShareAccess);

                //
                // We don't need the name array after the user closes the handle on the file
                //

                if( pCcb->NameArray != NULL)
                {

                    AFSFreeNameArray( pCcb->NameArray);

                    pCcb->NameArray = NULL;
                }

                //
                // Decrement the open child handle count
                //

                if( pObjectInfo->ParentObjectInformation != NULL)
                {

                    ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup (File) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
                }

                //
                // And finally, release the Fcb if we acquired it.
                //

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                break;
            }

            //
            // Root or directory node
            //

            case AFS_ROOT_FCB:
            {

                //
                // Set the root Fcb to this node
                //

                pRootFcb = pFcb;

                //
                // Fall through to below
                //
            }

            case AFS_DIRECTORY_FCB:
            {

                //
                // We may be performing some cleanup on the Fcb so grab it exclusive to ensure no collisions
                //

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup Acquiring Dcb lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                  TRUE);

                //
                // Perform some final common processing
                //

                ASSERT( pFcb->OpenHandleCount != 0);

                InterlockedDecrement( &pFcb->OpenHandleCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (Dir) Decrement handle count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenHandleCount);

                if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
                {

                    stFileCleanup.ParentId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
                }

                stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;

                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                {

                    stFileCleanup.FileAttributes = pObjectInfo->FileAttributes;

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME))
                    {

                        stFileCleanup.CreateTime = pObjectInfo->CreationTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME))
                    {

                        stFileCleanup.ChangeTime = pObjectInfo->ChangeTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME))
                    {

                        stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
                    }
                }

                //
                // If the count has dropped to zero and there is a pending delete
                // then delete the node
                //

                if( pFcb->OpenHandleCount == 0 &&
                    BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                {

                    //
                    // Try to notify the service about the delete
                    //

                    ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED;

                    //
                    // Indicate the file access mode that is being released
                    //

                    stFileCleanup.FileAccess = pCcb->FileAccess;

                    //
                    // Push the request to the service
                    //

                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
                                                  ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
                                                  &pCcb->AuthGroup,
                                                  &pCcb->DirectoryCB->NameInformation.FileName,
                                                  &pObjectInfo->FileId,
                                                  &stFileCleanup,
                                                  sizeof( AFSFileCleanupCB),
                                                  NULL,
                                                  NULL);

                    if( !NT_SUCCESS( ntStatus) &&
                        ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
                    {

                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_ERROR,
                                      "AFSCleanup Failed to notify service of deleted directory %wZ Status %08lX\n",
                                      &pCcb->FullFileName,
                                      ntStatus);

                        ntStatus = STATUS_SUCCESS;

                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
                    }
                    else
                    {

                        ntStatus = STATUS_SUCCESS;

                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_VERBOSE,
                                      "AFSCleanup Setting DELETE flag in directory %wZ Dir Entry %p\n",
                                      &pCcb->FullFileName,
                                      pCcb->DirectoryCB);

                        SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);

                        ASSERT( pObjectInfo->ParentObjectInformation != NULL);

                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
                                                        pCcb,
                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
                                                        (ULONG)FILE_ACTION_REMOVED);

                        //
                        // Now that the service has the entry has deleted we need to remove it from the parent
                        // tree so another lookup on the node will fail
                        //

                        if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
                        {

                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                            TRUE);

                            AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
                                                pCcb->DirectoryCB);

                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                        }
                        else
                        {

                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                          AFS_TRACE_LEVEL_VERBOSE,
                                          "AFSCleanup DE %p for %wZ NOT removing entry due to flag set\n",
                                          pCcb->DirectoryCB,
                                          &pCcb->DirectoryCB->NameInformation.FileName);
                        }
                    }
                }

                //
                // If there have been any updates to the node then push it to
                // the service
                //

                else
                {

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                    {

                        ULONG ulNotifyFilter = 0;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);

                        if(  pObjectInfo->ParentObjectInformation != NULL)
                        {

                            ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES);

                            AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
                                                            pCcb,
                                                            (ULONG)ulNotifyFilter,
                                                            (ULONG)FILE_ACTION_MODIFIED);
                        }
                    }

                    //
                    // Indicate the file access mode that is being released
                    //

                    stFileCleanup.FileAccess = pCcb->FileAccess;

                    AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
                                       ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
                                       &pCcb->AuthGroup,
                                       &pCcb->DirectoryCB->NameInformation.FileName,
                                       &pObjectInfo->FileId,
                                       &stFileCleanup,
                                       sizeof( AFSFileCleanupCB),
                                       NULL,
                                       NULL);
                }

                //
                // Release the notification for this directory if there is one
                //

                FsRtlNotifyCleanup( pControlDeviceExt->Specific.Control.NotifySync,
                                    &pControlDeviceExt->Specific.Control.DirNotifyList,
                                    pCcb);

                //
                // Remove the share access at this time since we may not get the close for sometime on this FO.
                //

                IoRemoveShareAccess( pFileObject,
                                     &pFcb->ShareAccess);

                //
                // We don't need the name array after the user closes the handle on the file
                //

                if( pCcb->NameArray != NULL)
                {

                    AFSFreeNameArray( pCcb->NameArray);

                    pCcb->NameArray = NULL;
                }

                //
                // Decrement the open child handle count
                //

                if( pObjectInfo->ParentObjectInformation != NULL)
                {

                    ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup (Dir) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
                }

                //
                // And finally, release the Fcb if we acquired it.
                //

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                break;
            }

            case AFS_SYMBOLIC_LINK_FCB:
            case AFS_MOUNT_POINT_FCB:
            case AFS_DFS_LINK_FCB:
            case AFS_INVALID_FCB:
            {

                //
                // We may be performing some cleanup on the Fcb so grab it exclusive to ensure no collisions
                //

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (MP/SL) Acquiring Dcb lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                  TRUE);

                //
                // Perform some final common processing
                //

                ASSERT( pFcb->OpenHandleCount != 0);

                InterlockedDecrement( &pFcb->OpenHandleCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (MP/SL) Decrement handle count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenHandleCount);

                if( pFcb->ObjectInformation->ParentObjectInformation != NULL)
                {

                    stFileCleanup.ParentId = pFcb->ObjectInformation->ParentObjectInformation->FileId;
                }

                stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;

                if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                {

                    stFileCleanup.FileAttributes = pObjectInfo->FileAttributes;

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME))
                    {

                        stFileCleanup.CreateTime = pObjectInfo->CreationTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CREATE_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME))
                    {

                        stFileCleanup.ChangeTime = pObjectInfo->ChangeTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_CHANGE_TIME);
                    }

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME))
                    {

                        stFileCleanup.LastAccessTime = pObjectInfo->LastAccessTime;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_UPDATE_ACCESS_TIME);
                    }
                }

                //
                // If the count has dropped to zero and there is a pending delete
                // then delete the node
                //

                if( pFcb->OpenHandleCount == 0 &&
                    BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
                {

                    //
                    // Try to notify the service about the delete
                    //

                    ulNotificationFlags |= AFS_REQUEST_FLAG_FILE_DELETED;

                    //
                    // Indicate the file access mode that is being released
                    //

                    stFileCleanup.FileAccess = pCcb->FileAccess;

                    //
                    // Push the request to the service
                    //

                    ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
                                                  ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
                                                  &pCcb->AuthGroup,
                                                  &pCcb->DirectoryCB->NameInformation.FileName,
                                                  &pObjectInfo->FileId,
                                                  &stFileCleanup,
                                                  sizeof( AFSFileCleanupCB),
                                                  NULL,
                                                  NULL);

                    if( !NT_SUCCESS( ntStatus) &&
                        ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
                    {

                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_ERROR,
                                      "AFSCleanup Failed to notify service of deleted MP/SL %wZ Status %08lX\n",
                                      &pCcb->FullFileName,
                                      ntStatus);

                        ntStatus = STATUS_SUCCESS;

                        ClearFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
                    }
                    else
                    {

                        ntStatus = STATUS_SUCCESS;

                        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_VERBOSE,
                                      "AFSCleanup Setting DELETE flag in MP/SL %wZ Dir Entry %p\n",
                                      &pCcb->FullFileName,
                                      pCcb->DirectoryCB);

                        SetFlag( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_DELETED);

                        ASSERT( pObjectInfo->ParentObjectInformation != NULL);

                        AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
                                                        pCcb,
                                                        (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
                                                        (ULONG)FILE_ACTION_REMOVED);

                        //
                        // Now that the service has the entry has deleted we need to remove it from the parent
                        // tree so another lookup on the node will fail
                        //

                        if( !BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
                        {

                            AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                            TRUE);

                            AFSRemoveNameEntry( pObjectInfo->ParentObjectInformation,
                                                pCcb->DirectoryCB);

                            AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
                        }
                        else
                        {

                            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                          AFS_TRACE_LEVEL_VERBOSE,
                                          "AFSCleanup DE %p for %wZ NOT removing entry due to flag set\n",
                                          pCcb->DirectoryCB,
                                          &pCcb->DirectoryCB->NameInformation.FileName);
                        }
                    }
                }

                //
                // If there have been any updates to the node then push it to
                // the service
                //

                else
                {

                    if( BooleanFlagOn( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED))
                    {

                        ULONG ulNotifyFilter = 0;

                        ClearFlag( pFcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);

                        if(  pObjectInfo->ParentObjectInformation != NULL)
                        {

                            ulNotifyFilter |= (FILE_NOTIFY_CHANGE_ATTRIBUTES);

                            AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
                                                            pCcb,
                                                            (ULONG)ulNotifyFilter,
                                                            (ULONG)FILE_ACTION_MODIFIED);
                        }
                    }

                    //
                    // Indicate the file access mode that is being released
                    //

                    stFileCleanup.FileAccess = pCcb->FileAccess;

                    AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING,
                                       ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS,
                                       &pCcb->AuthGroup,
                                       &pCcb->DirectoryCB->NameInformation.FileName,
                                       &pObjectInfo->FileId,
                                       &stFileCleanup,
                                       sizeof( AFSFileCleanupCB),
                                       NULL,
                                       NULL);
                }

                //
                // Remove the share access at this time since we may not get the close for sometime on this FO.
                //

                IoRemoveShareAccess( pFileObject,
                                     &pFcb->ShareAccess);

                //
                // We don't need the name array after the user closes the handle on the file
                //

                if( pCcb->NameArray != NULL)
                {

                    AFSFreeNameArray( pCcb->NameArray);

                    pCcb->NameArray = NULL;
                }

                //
                // Decrement the open child handle count
                //

                if( pObjectInfo->ParentObjectInformation != NULL)
                {

                    ASSERT( pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0);

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup (MP/SL) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
                }

                //
                // And finally, release the Fcb if we acquired it.
                //

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                break;
            }

            case AFS_SPECIAL_SHARE_FCB:
            {

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup Acquiring SPECIAL SHARE lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                TRUE);

                ASSERT( pFcb->OpenHandleCount != 0);

                InterlockedDecrement( &pFcb->OpenHandleCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSCleanup (Share) Decrement handle count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenHandleCount);

                //
                // Decrement the open child handle count
                //

                if( pObjectInfo->ParentObjectInformation != NULL &&
                    pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount > 0)
                {

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSCleanup (Share) Decrement child open handle count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
                }

                //
                // And finally, release the Fcb if we acquired it.
                //

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                break;
            }

            default:

                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_WARNING,
                              "AFSCleanup Processing unknown node type %d\n",
                              pFcb->Header.NodeTypeCode);

                break;
        }


try_exit:

        if( pFileObject != NULL)
        {

            //
            // Setup the fileobject flags to indicate cleanup is complete.
            //

            SetFlag( pFileObject->Flags, FO_CLEANUP_COMPLETE);
        }

        //
        // Complete the request
        //

        AFSCompleteRequest( Irp, ntStatus);
    }
Example #17
0
NTSTATUS
AFSRead( IN PDEVICE_OBJECT DeviceObject,
         IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;

    __try
    {

        if( DeviceObject == AFSDeviceObject)
        {

            ntStatus = STATUS_INVALID_DEVICE_REQUEST;

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

        NOTHING;
    }
    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
    {

        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    return ntStatus;
}
Example #18
0
NTSTATUS
AFSSetSecurity( IN PDEVICE_OBJECT DeviceObject,
                IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_NOT_SUPPORTED;
    IO_STACK_LOCATION *pIrpSp;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    AFSFcb* pFcb = NULL;

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __try
    {

        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSSetSecurity Entry for FO %p\n",
                      pIrpSp->FileObject));

        if( DeviceObject == AFSDeviceObject)
        {

            ntStatus = STATUS_INVALID_DEVICE_REQUEST;

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

        pFcb = (AFSFcb*) pIrpSp->FileObject->FsContext;

        if( pFcb == NULL ||
            pFcb->Header.NodeTypeCode == AFS_REDIRECTOR_FCB)
        {

            //
            // Root open
            //

            ntStatus = STATUS_INVALID_DEVICE_REQUEST;

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

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

        AFSDbgTrace(( 0,
                      0,
                      "EXCEPTION - AFSSetSecurity\n"));

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #19
0
NTSTATUS
AFSClose( IN PDEVICE_OBJECT LibDeviceObject,
          IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    ULONG ulRequestType = 0;
    IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
    AFSFcb *pFcb = NULL;
    AFSDeviceExt *pDeviceExt = NULL;
    AFSCcb *pCcb = NULL;
    AFSObjectInfoCB *pObjectInfo = NULL;
    AFSDirectoryCB *pDirCB = NULL;

    __try
    {

        if( AFSRDRDeviceObject == NULL)
        {

            //
            // Let this through, it's an close on the library control device
            //

            try_return( ntStatus);
        }

        pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);

        pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;

        if( pFcb == NULL)
        {
            try_return( ntStatus);
        }

        pObjectInfo = pFcb->ObjectInformation;

        //
        // Perform the close functionality depending on the type of node it is
        //

        switch( pFcb->Header.NodeTypeCode)
        {

            case AFS_IOCTL_FCB:
            {

                AFSPIOCtlOpenCloseRequestCB stPIOCtlClose;
                AFSFileID stParentFileId;

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose Acquiring GlobalRoot lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                  TRUE);

                pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;

                //
                // Send the close to the CM
                //

                RtlZeroMemory( &stPIOCtlClose,
                               sizeof( AFSPIOCtlOpenCloseRequestCB));

                stPIOCtlClose.RequestId = pCcb->RequestID;

                stPIOCtlClose.RootId = pObjectInfo->VolumeCB->ObjectInformation.FileId;

                RtlZeroMemory( &stParentFileId,
                               sizeof( AFSFileID));

                stParentFileId = pObjectInfo->ParentObjectInformation->FileId;

                //
                // Issue the close request to the service
                //

                AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_CLOSE,
                                   AFS_REQUEST_FLAG_SYNCHRONOUS,
                                   &pCcb->AuthGroup,
                                   NULL,
                                   &stParentFileId,
                                   (void *)&stPIOCtlClose,
                                   sizeof( AFSPIOCtlOpenCloseRequestCB),
                                   NULL,
                                   NULL);

                pDirCB = pCcb->DirectoryCB;

                //
                // Remove the Ccb and de-allocate it
                //

                ntStatus = AFSRemoveCcb( pFcb,
                                         pCcb);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                  AFS_TRACE_LEVEL_WARNING,
                                  "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus);

                    //
                    // We can't actually fail a close operation so reset the status
                    //

                    ntStatus = STATUS_SUCCESS;
                }

                ASSERT( pDirCB->OpenReferenceCount > 0);

                InterlockedDecrement( &pDirCB->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose (IOCtl) Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
                              &pDirCB->NameInformation.FileName,
                              pDirCB,
                              pCcb,
                              pDirCB->OpenReferenceCount);

                //
                // If this is not the root then decrement the open child reference count
                //

                if( pObjectInfo->ParentObjectInformation != NULL &&
                    pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
                {

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSClose (IOCtl) Decrement child open ref count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
                }

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                ASSERT( pFcb->OpenReferenceCount != 0);

                InterlockedDecrement( &pFcb->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose (IOCtl) Decrement count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenReferenceCount);

                break;
            }

            case AFS_ROOT_ALL:
            {

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose Acquiring Special Root ALL lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                TRUE);

                pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;

                pDirCB = pCcb->DirectoryCB;

                //
                // Remove the Ccb and de-allocate it
                //

                ntStatus = AFSRemoveCcb( pFcb,
                                         pCcb);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                  AFS_TRACE_LEVEL_WARNING,
                                  "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus);

                    //
                    // We can't actually fail a close operation so reset the status
                    //

                    ntStatus = STATUS_SUCCESS;
                }

                ASSERT( pDirCB->OpenReferenceCount > 0);

                InterlockedDecrement( &pDirCB->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose Decrement (Root ALL) count on %wZ DE %p Ccb %p Cnt %d\n",
                              &pDirCB->NameInformation.FileName,
                              pDirCB,
                              pCcb,
                              pDirCB->OpenReferenceCount);

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                ASSERT( pFcb->OpenReferenceCount > 0);

                InterlockedDecrement( &pFcb->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose (RootAll) Decrement count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenReferenceCount);

                break;
            }

            //
            // Root, file or directory node
            //

            case AFS_FILE_FCB:
            case AFS_ROOT_FCB:
            case AFS_DIRECTORY_FCB:
            case AFS_SYMBOLIC_LINK_FCB:
            case AFS_MOUNT_POINT_FCB:
            case AFS_DFS_LINK_FCB:
            case AFS_INVALID_FCB:
            {

                pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;

                //
                // We may be performing some cleanup on the Fcb so grab it exclusive to ensure no collisions
                //

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose Acquiring Dcb lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                TRUE);

                KeQueryTickCount( &pFcb->ObjectInformation->LastAccessCount);

                pDirCB = pCcb->DirectoryCB;

                //
                // If this entry is deleted then remove the object from the volume tree
                //

                if( BooleanFlagOn( pDirCB->Flags, AFS_DIR_ENTRY_DELETED))
                {

                    if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
                    {

                        //
                        // Stop anything possibly in process
                        //

                        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                                      AFS_TRACE_LEVEL_VERBOSE,
                                      "AFSClose Acquiring Fcb extents lock %08lX EXCL %08lX\n",
                                      &pFcb->NPFcb->Specific.File.ExtentsResource,
                                      PsGetCurrentThread());

                        AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
                                        TRUE);

                        pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;

                        KeSetEvent( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
                                    0,
                                    FALSE);

                        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                                      AFS_TRACE_LEVEL_VERBOSE,
                                      "AFSClose Releasing Fcb extents lock %08lX EXCL %08lX\n",
                                      &pFcb->NPFcb->Specific.File.ExtentsResource,
                                      PsGetCurrentThread());

                        AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
                    }

                    AFSAcquireExcl( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
                                    TRUE);

                    AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
                                    TRUE);

                    if ( pDirCB->OpenReferenceCount == 0)
                    {
                        AFSDbgLogMsg( 0,
                                      0,
                                      "AFSClose (Other) OpenReferenceCount is Zero on DE %08lX Ccb %08lX FileName %wZ\n",
                                      pDirCB,
                                      pCcb,
                                      &pDirCB->NameInformation.FileName);
                    }

                    ASSERT( pDirCB->OpenReferenceCount > 0);

                    InterlockedDecrement( &pDirCB->OpenReferenceCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSClose (Other) Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
                                  &pDirCB->NameInformation.FileName,
                                  pDirCB,
                                  pCcb,
                                  pDirCB->OpenReferenceCount);

                    if( pDirCB->OpenReferenceCount == 0)
                    {

                        AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                      AFS_TRACE_LEVEL_VERBOSE,
                                      "AFSClose Deleting dir entry %08lX (%08lX) for %wZ  FID %08lX-%08lX-%08lX-%08lX\n",
                                      pDirCB,
                                      pObjectInfo,
                                      &pDirCB->NameInformation.FileName,
                                      pObjectInfo->FileId.Cell,
                                      pObjectInfo->FileId.Volume,
                                      pObjectInfo->FileId.Vnode,
                                      pObjectInfo->FileId.Unique);

                        //
                        // Remove and delete the directory entry from the parent list
                        //

                        AFSDeleteDirEntry( pObjectInfo->ParentObjectInformation,
                                           pDirCB);

                        if( pObjectInfo->ObjectReferenceCount <= 0)
                        {

                            if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
                            {

                                AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
                                              AFS_TRACE_LEVEL_VERBOSE,
                                              "AFSClose Removing object %08lX from volume tree\n",
                                              pObjectInfo);

                                AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
                                                    &pObjectInfo->TreeEntry);

                                ClearFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE);
                            }

                            SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
                        }
                    }

                    AFSReleaseResource( pObjectInfo->ParentObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);

                    AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
                }
                else
                {

                    ASSERT( pDirCB->OpenReferenceCount > 0);

                    InterlockedDecrement( &pDirCB->OpenReferenceCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSClose (Other2) Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
                                  &pDirCB->NameInformation.FileName,
                                  pDirCB,
                                  pCcb,
                                  pDirCB->OpenReferenceCount);
                }

                //
                // If this is not the root then decrement the open child reference count
                //

                if( pObjectInfo != NULL &&
                    pObjectInfo->ParentObjectInformation != NULL &&
                    pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
                {

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSClose Decrement child open ref count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
                }

                if( pFcb->OpenReferenceCount == 1 &&
                    pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
                {

                    SetFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);

                    //
                    // Attempt to tear down our extent list for the file
                    // If there are remaining dirty extents then attempt to
                    // flush them as well
                    //

                    if( pFcb->Specific.File.ExtentsDirtyCount)
                    {

                        AFSFlushExtents( pFcb,
                                         &pCcb->AuthGroup);
                    }

                    //
                    // Wait for any outstanding queued flushes to complete
                    //

                    AFSWaitOnQueuedFlushes( pFcb);

                    ASSERT( pFcb->Specific.File.ExtentsDirtyCount == 0 &&
                            pFcb->Specific.File.QueuedFlushCount == 0);

                    AFSReleaseResource( &pFcb->NPFcb->Resource);

                    //
                    // Tear 'em down, we'll not be needing them again
                    //

                    AFSTearDownFcbExtents( pFcb,
                                           &pCcb->AuthGroup);
                }
                else
                {

                    if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB &&
                        pFcb->Specific.File.ExtentsDirtyCount &&
                        (pCcb->GrantedAccess & FILE_WRITE_DATA))
                    {

                        AFSFlushExtents( pFcb,
                                         &pCcb->AuthGroup);
                    }

                    AFSReleaseResource( &pFcb->NPFcb->Resource);
                }

                //
                // Remove the Ccb and de-allocate it
                //

                ntStatus = AFSRemoveCcb( pFcb,
                                         pCcb);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                  AFS_TRACE_LEVEL_WARNING,
                                  "AFSClose Failed to remove Ccb from Fcb Status %08lX\n",
                                  ntStatus);

                    //
                    // We can't actually fail a close operation so reset the status
                    //

                    ntStatus = STATUS_SUCCESS;
                }

                //
                // Decrement the reference count on the Fcb. this is protecting it from teardown.
                //

                ASSERT( pFcb->OpenReferenceCount != 0);

                InterlockedDecrement( &pFcb->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose Decrement count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenReferenceCount);

                break;
            }

            case AFS_SPECIAL_SHARE_FCB:
            {

                AFSPipeOpenCloseRequestCB stPipeClose;

                AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose Acquiring Special Share lock %08lX EXCL %08lX\n",
                              &pFcb->NPFcb->Resource,
                              PsGetCurrentThread());

                AFSAcquireExcl( &pFcb->NPFcb->Resource,
                                TRUE);

                pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;

                pDirCB = pCcb->DirectoryCB;

                RtlZeroMemory( &stPipeClose,
                               sizeof( AFSPipeOpenCloseRequestCB));

                stPipeClose.RequestId = pCcb->RequestID;

                stPipeClose.RootId = pObjectInfo->VolumeCB->ObjectInformation.FileId;

                //
                // Issue the open request to the service
                //

                /*
                AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_CLOSE,
                                   AFS_REQUEST_FLAG_SYNCHRONOUS,
                                   &pFcb->AuthGroup,
                                   &pDirCB->NameInformation.FileName,
                                   NULL,
                                   (void *)&stPipeClose,
                                   sizeof( AFSPipeOpenCloseRequestCB),
                                   NULL,
                                   NULL);
                */

                //
                // Remove the Ccb and de-allocate it
                //

                ntStatus = AFSRemoveCcb( pFcb,
                                         pCcb);

                if( !NT_SUCCESS( ntStatus))
                {

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                                  AFS_TRACE_LEVEL_WARNING,
                                  "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", ntStatus);

                    //
                    // We can't actually fail a close operation so reset the status
                    //

                    ntStatus = STATUS_SUCCESS;
                }

                ASSERT( pDirCB->OpenReferenceCount > 0);

                InterlockedDecrement( &pDirCB->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose (Share) Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
                              &pDirCB->NameInformation.FileName,
                              pDirCB,
                              pCcb,
                              pDirCB->OpenReferenceCount);

                //
                // If this is not the root then decrement the open child reference count
                //

                if( pObjectInfo->ParentObjectInformation != NULL &&
                    pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount > 0)
                {

                    InterlockedDecrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);

                    AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSClose (Share) Decrement child open ref count on Parent object %08lX Cnt %d\n",
                                  pObjectInfo->ParentObjectInformation,
                                  pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
                }

                AFSReleaseResource( &pFcb->NPFcb->Resource);

                ASSERT( pFcb->OpenReferenceCount != 0);

                InterlockedDecrement( &pFcb->OpenReferenceCount);

                AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSClose (Share) Decrement count on Fcb %08lX Cnt %d\n",
                              pFcb,
                              pFcb->OpenReferenceCount);

                break;
            }

            default:

                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "AFSClose Processing unknown node type %d\n",
                              pFcb->Header.NodeTypeCode);

                break;
        }

try_exit:

        //
        // Complete the request
        //

        AFSCompleteRequest( Irp,
                            ntStatus);
    }
    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
    {

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSClose\n");

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #20
0
NTSTATUS
AFSQueryEA( IN PDEVICE_OBJECT DeviceObject,
            IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_EAS_NOT_SUPPORTED;
    AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;

    __try
    {

        if( DeviceObject == AFSDeviceObject)
        {

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }

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

        ntStatus = AFSCheckLibraryState( Irp);

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

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

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

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

        AFSClearLibraryRequest();

try_exit:

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

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSQueryEA\n");

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #21
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;
}
Example #22
0
NTSTATUS
AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
                    IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
    IO_STACK_LOCATION *pIrpSp;
    FS_INFORMATION_CLASS FsInformationClass;
    void *pBuffer = NULL;
    ULONG ulLength = 0;
    BOOLEAN bReleaseResource = FALSE;
    PFILE_OBJECT pFileObject = NULL;
    AFSFcb *pFcb = NULL;
    AFSObjectInfoCB *pObjectInfo = NULL;
    AFSVolumeCB *pVolumeCB = NULL;

    pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __try
    {

        pFileObject = pIrpSp->FileObject;

        if( pFileObject == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQueryVolumeInfo Failing request with NULL FileObject\n");

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

        pFcb = (AFSFcb *)pFileObject->FsContext;

        if( pFcb == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQueryVolumeInfo Failing request with NULL Fcb\n");

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

        pObjectInfo = pFcb->ObjectInformation;

        if( pObjectInfo == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n");

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

        pVolumeCB = pObjectInfo->VolumeCB;

        ulLength = pIrpSp->Parameters.QueryVolume.Length;
        FsInformationClass = pIrpSp->Parameters.QueryVolume.FsInformationClass;
        pBuffer = Irp->AssociatedIrp.SystemBuffer;

        AFSAcquireShared( pVolumeCB->VolumeLock,
                          TRUE);

        bReleaseResource = TRUE;

        //
        // Don't allow requests against IOCtl nodes
        //

        if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQueryVolumeInfo Failing request against PIOCtl Fcb\n");

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }
        else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n");

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }
        else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n");

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

        //
        // Process the request
        //

        switch( FsInformationClass)
        {

            case FileFsVolumeInformation:
            {

                ntStatus = AFSQueryFsVolumeInfo( &pVolumeCB->VolumeInformation,
                                                 (PFILE_FS_VOLUME_INFORMATION)pBuffer,
                                                 &ulLength);

                break;
            }

            case FileFsSizeInformation:
            {

                ntStatus = AFSQueryFsSizeInfo( &pVolumeCB->VolumeInformation,
                                               (PFILE_FS_SIZE_INFORMATION)pBuffer,
                                               &ulLength);

                break;
            }

            case FileFsDeviceInformation:
            {

                ntStatus = AFSQueryFsDeviceInfo( &pVolumeCB->VolumeInformation,
                                                 (PFILE_FS_DEVICE_INFORMATION)pBuffer,
                                                 &ulLength);

                break;
            }

            case FileFsAttributeInformation:
            {

                ntStatus = AFSQueryFsAttributeInfo( &pVolumeCB->VolumeInformation,
                                                    (PFILE_FS_ATTRIBUTE_INFORMATION)pBuffer,
                                                    &ulLength);

                break;
            }

            case FileFsFullSizeInformation:
            {

                ntStatus = AFSQueryFsFullSizeInfo( &pVolumeCB->VolumeInformation,
                                                   (PFILE_FS_FULL_SIZE_INFORMATION)pBuffer,
                                                   &ulLength);

                break;
            }

            default:

                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_WARNING,
                              "AFSQueryVolumeInfo Invalid class %d\n",
                              FsInformationClass);

                ntStatus = STATUS_INVALID_PARAMETER;

                break;
        }

try_exit:

        //
        // Setup the Irp's information field to what we actually copied in.
        //

        Irp->IoStatus.Information = pIrpSp->Parameters.QueryVolume.Length - ulLength;

        if( bReleaseResource)
        {

            AFSReleaseResource( pVolumeCB->VolumeLock);
        }

        AFSCompleteRequest( Irp,
                            ntStatus);

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

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSQueryVolumeInfo FO %08lX InfoClass %d FCB %08lX ObjectInfo %08lX VolCB %08lX\n",
                      pFileObject,
                      FsInformationClass,
                      pFcb,
                      pObjectInfo,
                      pVolumeCB);

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}
Example #23
0
NTSTATUS
AFSQuerySecurity( IN PDEVICE_OBJECT LibDeviceObject,
                  IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    PIO_STACK_LOCATION pIrpSp;
    PMDL pUserBufferMdl = NULL;
    void *pLockedUserBuffer = NULL;
    ULONG ulSDLength = 0;

    __try
    {

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);

        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSQuerySecurity Entry for FO %08lX\n",
                      pIrpSp->FileObject);

        if( AFSDefaultSD == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQuerySecurity No default SD allocated\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        ulSDLength = RtlLengthSecurityDescriptor( AFSDefaultSD);

        if( pIrpSp->Parameters.QuerySecurity.Length < ulSDLength ||
            Irp->UserBuffer == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSQuerySecurity Buffer too small\n");

            Irp->IoStatus.Information = (ULONG_PTR)ulSDLength;

            try_return( ntStatus = STATUS_BUFFER_OVERFLOW);
        }

        pLockedUserBuffer = AFSLockUserBuffer( Irp->UserBuffer,
                                               pIrpSp->Parameters.QuerySecurity.Length,
                                               &pUserBufferMdl);

        if( pLockedUserBuffer == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSQuerySecurity Failed to lock user buffer\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlCopyMemory( pLockedUserBuffer,
                       AFSDefaultSD,
                       ulSDLength);

        Irp->IoStatus.Information = (ULONG_PTR)ulSDLength;

try_exit:

        if( pUserBufferMdl != NULL)
        {
            MmUnlockPages( pUserBufferMdl);
            IoFreeMdl( pUserBufferMdl);
        }
    }
    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
    {

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSQuerySecurity\n");
    }

    AFSCompleteRequest( Irp,
                        ntStatus);

    return ntStatus;
}