コード例 #1
0
ファイル: AFSProcessSupport.cpp プロジェクト: bagdxk/openafs
BOOLEAN
AFSIs64BitProcess( IN ULONGLONG ProcessId)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    BOOLEAN bIs64Bit = FALSE;
    AFSProcessCB *pProcessCB = NULL;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;

    __Enter
    {

        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSIs64BitProcess Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n",
                      pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                      PsGetCurrentThread()));

        AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                          TRUE);

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                       (ULONGLONG)ProcessId,
                                       (AFSBTreeEntry **)&pProcessCB);

        if( pProcessCB != NULL)
        {
            bIs64Bit = BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }

        AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
    }

    return bIs64Bit;
}
コード例 #2
0
ファイル: AFSVolumeInfo.cpp プロジェクト: jisqyv/openafs
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;
}
コード例 #3
0
ファイル: AFSFlushBuffers.cpp プロジェクト: bagdxk/openafs
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;
}
コード例 #4
0
ファイル: AFSLogSupport.cpp プロジェクト: jisqyv/openafs
void
AFSDumpTraceFiles()
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    HANDLE hDirectory = NULL;
    OBJECT_ATTRIBUTES   stObjectAttribs;
    IO_STATUS_BLOCK stIoStatus;
    LARGE_INTEGER liTime, liLocalTime;
    TIME_FIELDS timeFields;
    ULONG ulBytesWritten = 0;
    HANDLE hDumpFile = NULL;
    ULONG ulBytesProcessed, ulCopyLength;
    LARGE_INTEGER liOffset;
    ULONG ulDumpLength = 0;
    BOOLEAN bSetEvent = FALSE;

    __Enter
    {

        AFSAcquireShared( &AFSDbgLogLock,
                          TRUE);

        ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;

        AFSReleaseResource( &AFSDbgLogLock);

        if( AFSDumpFileLocation.Length == 0 ||
            AFSDumpFileLocation.Buffer == NULL ||
            AFSDbgBufferLength == 0 ||
            ulDumpLength == 0 ||
            AFSDumpFileName.MaximumLength == 0 ||
            AFSDumpFileName.Buffer == NULL ||
            AFSDumpBuffer == NULL)
        {
            try_return( ntStatus);
        }

        //
        // Go open the cache file
        //

        InitializeObjectAttributes( &stObjectAttribs,
                                    &AFSDumpFileLocation,
                                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                    NULL,
                                    NULL);

        ntStatus = ZwCreateFile( &hDirectory,
                                 GENERIC_READ | GENERIC_WRITE,
                                 &stObjectAttribs,
                                 &stIoStatus,
                                 NULL,
                                 0,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 FILE_OPEN,
                                 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent,
                                          Executive,
                                          KernelMode,
                                          FALSE,
                                          NULL);

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        bSetEvent = TRUE;

        AFSDumpFileName.Length = 0;

        RtlZeroMemory( AFSDumpFileName.Buffer,
                       AFSDumpFileName.MaximumLength);

        KeQuerySystemTime( &liTime);

        ExSystemTimeToLocalTime( &liTime,
                                 &liLocalTime);

        RtlTimeToTimeFields( &liLocalTime,
                             &timeFields);

        ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer,
                                        AFSDumpFileName.MaximumLength/sizeof( WCHAR),
                                        L"AFSDumpFile %d.%d.%d %d.%d.%d.log",
                                                  timeFields.Month,
                                                  timeFields.Day,
                                                  timeFields.Year,
                                                  timeFields.Hour,
                                                  timeFields.Minute,
                                                  timeFields.Second);

        if( !NT_SUCCESS( ntStatus))
        {
            try_return( ntStatus);
        }

        RtlStringCbLengthW( AFSDumpFileName.Buffer,
                            AFSDumpFileName.MaximumLength,
                            (size_t *)&ulBytesWritten);

        AFSDumpFileName.Length = (USHORT)ulBytesWritten;

        InitializeObjectAttributes( &stObjectAttribs,
                                    &AFSDumpFileName,
                                    OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                    hDirectory,
                                    NULL);

        ntStatus = ZwCreateFile( &hDumpFile,
                                 GENERIC_READ | GENERIC_WRITE,
                                 &stObjectAttribs,
                                 &stIoStatus,
                                 NULL,
                                 0,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 FILE_CREATE,
                                 FILE_SYNCHRONOUS_IO_NONALERT,
                                 NULL,
                                 0);

        if( !NT_SUCCESS( ntStatus))
        {
            try_return( ntStatus);
        }

        //
        // Write out the trace buffer
        //

        liOffset.QuadPart = 0;

        ulBytesProcessed = 0;

        while( ulBytesProcessed < ulDumpLength)
        {

            ulCopyLength = AFSDumpBufferLength;

            if( ulCopyLength > ulDumpLength - ulBytesProcessed)
            {
                ulCopyLength = ulDumpLength - ulBytesProcessed;
            }

            RtlCopyMemory( AFSDumpBuffer,
                           (void *)((char *)AFSDbgBuffer + ulBytesProcessed),
                           ulCopyLength);

            ntStatus = ZwWriteFile( hDumpFile,
                                    NULL,
                                    NULL,
                                    NULL,
                                    &stIoStatus,
                                    AFSDumpBuffer,
                                    ulCopyLength,
                                    &liOffset,
                                    NULL);

            if( !NT_SUCCESS( ntStatus))
            {
                break;
            }

            liOffset.QuadPart += ulCopyLength;

            ulBytesProcessed += ulCopyLength;
        }

try_exit:

        if( hDumpFile != NULL)
        {
            ZwClose( hDumpFile);
        }

        if( hDirectory != NULL)
        {
            ZwClose( hDirectory);
        }

        if( bSetEvent)
        {
            KeSetEvent( &AFSDumpFileEvent,
                        0,
                        FALSE);
        }
    }

    return;
}
コード例 #5
0
ファイル: AFSLogSupport.cpp プロジェクト: jisqyv/openafs
NTSTATUS
AFSGetTraceBuffer( IN ULONG TraceBufferLength,
                   OUT void *TraceBuffer,
                   OUT ULONG_PTR *CopiedLength)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    ULONG ulCopyLength = 0;
    char *pCurrentLocation = NULL;

    __Enter
    {

        AFSAcquireShared( &AFSDbgLogLock,
                          TRUE);

        if( TraceBufferLength < AFSDbgBufferLength)
        {

            try_return( ntStatus = STATUS_INVALID_PARAMETER);
        }

        //
        // If we have wrapped then copy in the remaining portion
        //

        pCurrentLocation = (char *)TraceBuffer;

        *CopiedLength = 0;

        if( BooleanFlagOn( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED))
        {

            ulCopyLength = AFSDbgLogRemainingLength;

            RtlCopyMemory( pCurrentLocation,
                           AFSDbgCurrentBuffer,
                           ulCopyLength);

            pCurrentLocation[ 0] = '0'; // The buffer is NULL terminated ...

            pCurrentLocation += ulCopyLength;

            *CopiedLength = ulCopyLength;
        }

        ulCopyLength = AFSDbgBufferLength - AFSDbgLogRemainingLength;

        if( ulCopyLength > 0)
        {

            RtlCopyMemory( pCurrentLocation,
                           AFSDbgBuffer,
                           ulCopyLength);

            *CopiedLength += ulCopyLength;
        }

try_exit:

        AFSReleaseResource( &AFSDbgLogLock);
    }

    return ntStatus;
}
コード例 #6
0
ファイル: AFSFSControl.cpp プロジェクト: bagdxk/openafs
NTSTATUS
AFSProcessUserFsRequest( IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    ULONG ulFsControlCode;
    AFSFcb *pFcb = NULL;
    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp );
    AFSCcb *pCcb = NULL;
    ULONG ulOutputBufferLen, ulInputBufferLen;

    __Enter
    {

        ulFsControlCode = pIrpSp->Parameters.FileSystemControl.FsControlCode;

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

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

        if( pFcb == NULL ||
            pCcb == NULL ||
            pCcb->DirectoryCB == NULL)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE_2,
                          "AFSProcessUserFsRequest Invalid Fcb\n"));

            try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
        }

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

            ntStatus = AFSProcessShareFsCtrl( Irp,
                                              pFcb,
                                              pCcb);

            try_return( ntStatus);
        }

        ulOutputBufferLen = pIrpSp->Parameters.FileSystemControl.OutputBufferLength;
        ulInputBufferLen = pIrpSp->Parameters.FileSystemControl.InputBufferLength;

        //
        // Process the request
        //

        switch( ulFsControlCode )
        {

            case FSCTL_REQUEST_OPLOCK_LEVEL_1:
            case FSCTL_REQUEST_OPLOCK_LEVEL_2:
            case FSCTL_REQUEST_BATCH_OPLOCK:
            case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
            case FSCTL_OPBATCH_ACK_CLOSE_PENDING:
            case FSCTL_OPLOCK_BREAK_NOTIFY:
            case FSCTL_OPLOCK_BREAK_ACK_NO_2:
            case FSCTL_REQUEST_FILTER_OPLOCK :
            {
                //
                // Note that implementing this call will probably need us
                // to call the server as well as adding code in read and
                // write and caching.  Also that it is unlikely that
                // anyone will ever call us at this point - RDR doesn't
                // allow it
                //

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_LOCK_VOLUME:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_LOCK_VOLUME request\n"));

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_UNLOCK_VOLUME:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_UNLOCK_VOLUME request\n"));

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_DISMOUNT_VOLUME:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_DISMOUNT_VOLUME request\n"));

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_MARK_VOLUME_DIRTY:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_MARK_VOLUME_DIRTY request\n"));

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_IS_VOLUME_DIRTY:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_IS_VOLUME_DIRTY request\n"));

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_IS_VOLUME_MOUNTED:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_IS_VOLUME_MOUNTED request\n"));

                ntStatus = STATUS_NOT_IMPLEMENTED;

                break;
            }

            case FSCTL_IS_PATHNAME_VALID:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_IS_PATHNAME_VALID request\n"));

                ntStatus = STATUS_SUCCESS;

                break;
            }

#ifndef FSCTL_CSC_INTERNAL
#define FSCTL_CSC_INTERNAL                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 107, METHOD_NEITHER, FILE_ANY_ACCESS)
#endif
            case FSCTL_CSC_INTERNAL:
            {
                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_CSC_INTERNAL request\n"));

                ntStatus = STATUS_INVALID_DEVICE_REQUEST;

                break;
            }

            case FSCTL_GET_REPARSE_POINT:
            {

                REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
                REPARSE_DATA_BUFFER *pMSFTReparseBuffer = (REPARSE_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
                ULONG ulRemainingLen = ulOutputBufferLen;
                AFSReparseTagInfo *pReparseInfo = NULL;
                BOOLEAN bRelative = FALSE;
                BOOLEAN bDriveLetter = FALSE;
                WCHAR * PathBuffer = NULL;

                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_GET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
                              &pCcb->DirectoryCB->NameInformation.FileName,
                              pFcb->ObjectInformation->FileType,
                              pFcb->ObjectInformation->FileAttributes));

                //
                // Check if we have the reparse entry set on the entry
                //

                if( !BooleanFlagOn( pFcb->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
                {

                    ntStatus = STATUS_NOT_A_REPARSE_POINT;

                    break;
                }


                switch ( pFcb->ObjectInformation->FileType) {
                case AFS_FILE_TYPE_MOUNTPOINT:

                    if( ulOutputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
                    {

                        ntStatus = STATUS_BUFFER_TOO_SMALL;

                        Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);

                        break;
                    }

                    ulRemainingLen -= FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);

                    break;

                default:

                    if( ulOutputBufferLen < FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
                    {

                        ntStatus = STATUS_BUFFER_TOO_SMALL;

                        Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer);

                        break;
                    }

                    ulRemainingLen -= FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer);

                    break;
                }

                //
                // Populate the data in the reparse buffer
                //

                pReparseBuffer->ReparseDataLength  = 0;

                AFSAcquireExcl( &pCcb->DirectoryCB->NonPaged->Lock,
                                TRUE);

                if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                {

                    //
                    // We'll reset the DV to ensure we validate the metadata content
                    //

                    pFcb->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;

                    SetFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);

                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSProcessUserFsRequest Verifying symlink %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                                  &pCcb->DirectoryCB->NameInformation.FileName,
                                  pFcb->ObjectInformation->FileId.Cell,
                                  pFcb->ObjectInformation->FileId.Volume,
                                  pFcb->ObjectInformation->FileId.Vnode,
                                  pFcb->ObjectInformation->FileId.Unique));

                    ntStatus = AFSVerifyEntry( &pCcb->AuthGroup,
					       pCcb->DirectoryCB,
					       FALSE);

                    if( !NT_SUCCESS( ntStatus))
                    {

                        AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                      AFS_TRACE_LEVEL_ERROR,
                                      "AFSProcessUserFsRequest Failed to verify symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
                                      &pCcb->DirectoryCB->NameInformation.FileName,
                                      pFcb->ObjectInformation->FileId.Cell,
                                      pFcb->ObjectInformation->FileId.Volume,
                                      pFcb->ObjectInformation->FileId.Vnode,
                                      pFcb->ObjectInformation->FileId.Unique,
                                      ntStatus));

                        AFSReleaseResource( &pCcb->DirectoryCB->NonPaged->Lock);

                        break;
                    }
                }

                pReparseInfo = (AFSReparseTagInfo *)&pReparseBuffer->GenericReparseBuffer.DataBuffer[ 0];

                switch( pFcb->ObjectInformation->FileType)
                {

                    case AFS_FILE_TYPE_SYMLINK:
                    {

                        if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                        {

                            ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;

                            break;
                        }

                        bRelative = AFSIsRelativeName( &pCcb->DirectoryCB->NameInformation.TargetName);

                        if ( bRelative)
                        {

                            if( ulRemainingLen < (ULONG) FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                pCcb->DirectoryCB->NameInformation.TargetName.Length)
                            {

                                ntStatus = STATUS_BUFFER_TOO_SMALL;

                                Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length;

                                break;
                            }

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.Flags = SYMLINK_FLAG_RELATIVE;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset = 0;

                            PathBuffer = pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer;

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            pReparseBuffer->ReparseDataLength = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) -
                                FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
                        }
                        else
                        {

                            if( ulRemainingLen < (ULONG) FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                /* Display Name */
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 1 * sizeof( WCHAR) +
                                /* Substitute Name */
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 7 * sizeof( WCHAR))
                            {

                                ntStatus = STATUS_BUFFER_TOO_SMALL;

                                Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length + 1 * sizeof( WCHAR) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length + 7 * sizeof( WCHAR);

                                break;
                            }

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.Flags = 0;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 7 * sizeof( WCHAR);

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 1 * sizeof( WCHAR);

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset =
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset = 0;

                            PathBuffer = pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer;

                            /* Display Name */
                            *PathBuffer++ = L'\\';

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            PathBuffer += pCcb->DirectoryCB->NameInformation.TargetName.Length / sizeof( WCHAR);

                            /* Substitute Name */
                            *PathBuffer++ = L'\\';
                            *PathBuffer++ = L'?';
                            *PathBuffer++ = L'?';
                            *PathBuffer++ = L'\\';
                            *PathBuffer++ = L'U';
                            *PathBuffer++ = L'N';
                            *PathBuffer++ = L'C';

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            pReparseBuffer->ReparseDataLength = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) -
                                FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
                        }

                        break;
                    }

                    case AFS_FILE_TYPE_MOUNTPOINT:
                    {
                        UNICODE_STRING Cell, Volume;
                        USHORT Type;

                        if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                        {
                            ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;

                            break;
                        }

                        if ( !AFSParseMountPointTarget( &pCcb->DirectoryCB->NameInformation.TargetName,
                                                        &Type,
                                                        &Volume,
                                                        &Cell))
                        {
                            ntStatus = STATUS_INVALID_PARAMETER;

                            break;
                        }

                        if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) + Volume.Length + Cell.Length)
                        {

                            ntStatus = STATUS_BUFFER_TOO_SMALL;

                            Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                                        FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) +
                                                        Volume.Length + Cell.Length;

                            break;
                        }

                        pReparseInfo->SubTag = OPENAFS_SUBTAG_MOUNTPOINT;

                        pReparseInfo->AFSMountPoint.Type = Type;

                        pReparseInfo->AFSMountPoint.MountPointCellLength = Cell.Length;

                        pReparseInfo->AFSMountPoint.MountPointVolumeLength = Volume.Length;

                        RtlCopyMemory( pReparseInfo->AFSMountPoint.Buffer,
                                       Cell.Buffer,
                                       Cell.Length);

                        RtlCopyMemory( &pReparseInfo->AFSMountPoint.Buffer[ Cell.Length / sizeof( WCHAR)],
                                       Volume.Buffer,
                                       Volume.Length);

                        pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) + Volume.Length + Cell.Length);

                        break;
                    }

                    case AFS_FILE_TYPE_DFSLINK:
                    {

                        if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                        {

                            ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;

                            break;
                        }

                        bRelative = ( pCcb->DirectoryCB->NameInformation.TargetName.Buffer[0] == L'\\');

                        bDriveLetter = (bRelative == FALSE && pCcb->DirectoryCB->NameInformation.TargetName.Buffer[1] == L':');

                        if ( bRelative)
                        {

                            if( ulRemainingLen < (ULONG) FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                pCcb->DirectoryCB->NameInformation.TargetName.Length)
                            {

                                ntStatus = STATUS_BUFFER_TOO_SMALL;

                                Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length;

                                break;
                            }

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.Flags = SYMLINK_FLAG_RELATIVE;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset = 0;

                            PathBuffer = pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer;

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            pReparseBuffer->ReparseDataLength = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) -
                                FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
                        }
                        else if ( bDriveLetter)
                        {

                            if( ulRemainingLen < (ULONG) FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                /* Display Name */
                                pCcb->DirectoryCB->NameInformation.TargetName.Length +
                                /* Substitute Name */
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 4 * sizeof( WCHAR))
                            {

                                ntStatus = STATUS_BUFFER_TOO_SMALL;

                                Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length + 4 * sizeof( WCHAR);

                                break;
                            }

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.Flags = 0;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 4 * sizeof( WCHAR);

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset =
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset = 0;

                            PathBuffer = pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer;

                            /* Display Name */
                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            PathBuffer += pCcb->DirectoryCB->NameInformation.TargetName.Length / sizeof( WCHAR);

                            /* Substitute Name */
                            *PathBuffer++ = L'\\';
                            *PathBuffer++ = L'?';
                            *PathBuffer++ = L'?';
                            *PathBuffer++ = L'\\';

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            pReparseBuffer->ReparseDataLength = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) -
                                FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
                        }
                        else
                        {

                            if( ulRemainingLen < (ULONG) FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                /* Display Name */
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 1 * sizeof( WCHAR) +
                                /* Substitute Name */
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 7 * sizeof( WCHAR))
                            {

                                ntStatus = STATUS_BUFFER_TOO_SMALL;

                                Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length + 1 * sizeof( WCHAR) +
                                    pCcb->DirectoryCB->NameInformation.TargetName.Length + 7 * sizeof( WCHAR);

                                break;
                            }

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.Flags = 0;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 7 * sizeof( WCHAR);

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength =
                                pCcb->DirectoryCB->NameInformation.TargetName.Length + 1 * sizeof( WCHAR);

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset =
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength;

                            pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameOffset = 0;

                            PathBuffer = pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer;

                            /* Display Name */
                            *PathBuffer++ = L'\\';

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            PathBuffer += pCcb->DirectoryCB->NameInformation.TargetName.Length / sizeof( WCHAR);

                            /* Substitute Name */
                            *PathBuffer++ = L'\\';
                            *PathBuffer++ = L'?';
                            *PathBuffer++ = L'?';
                            *PathBuffer++ = L'\\';
                            *PathBuffer++ = L'U';
                            *PathBuffer++ = L'N';
                            *PathBuffer++ = L'C';

                            RtlCopyMemory( PathBuffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
                                           pCcb->DirectoryCB->NameInformation.TargetName.Length);

                            pReparseBuffer->ReparseDataLength = FIELD_OFFSET( REPARSE_DATA_BUFFER, SymbolicLinkReparseBuffer.PathBuffer) -
                                FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.PrintNameLength +
                                pMSFTReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
                        }

                        break;
                    }

                    default:

                        ntStatus = STATUS_NOT_A_REPARSE_POINT;

                        break;
                }

                if ( ntStatus == STATUS_SUCCESS)
                {

                    ulRemainingLen -= pReparseBuffer->ReparseDataLength;

                    if ( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
                    {

                        pReparseBuffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;

                        RtlCopyMemory( &pReparseBuffer->ReparseGuid,
                                       &GUID_AFS_REPARSE_GUID,
                                       sizeof( GUID));

                        Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer)
                            + pReparseBuffer->ReparseDataLength;
                    }
                    else
                    {

                        pReparseBuffer->ReparseTag = IO_REPARSE_TAG_SYMLINK;

                        Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_DATA_BUFFER, GenericReparseBuffer.DataBuffer)
                            + pReparseBuffer->ReparseDataLength;
                    }
                }

                AFSReleaseResource( &pCcb->DirectoryCB->NonPaged->Lock);

                break;
            }

            case FSCTL_SET_REPARSE_POINT:
            {

                REPARSE_GUID_DATA_BUFFER *pReparseGUIDBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
                REPARSE_DATA_BUFFER *pReparseBuffer = NULL;
                AFSReparseTagInfo *pReparseInfo = NULL;
                AFSObjectInfoCB *pParentObjectInfo = NULL;
                UNICODE_STRING uniTargetName;
                ULONGLONG ullIndex = 0;
                LONG lCount;

                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "AFSProcessUserFsRequest Processing FSCTL_SET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
                              &pCcb->DirectoryCB->NameInformation.FileName,
                              pFcb->ObjectInformation->FileType,
                              pFcb->ObjectInformation->FileAttributes));

                if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
                {

                    ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                    break;
                }

                if( (pReparseGUIDBuffer->ReparseTag & 0x0000FFFF) == IO_REPARSE_TAG_OPENAFS_DFS)
                {

                    if( RtlCompareMemory( &pReparseGUIDBuffer->ReparseGuid,
                                          &GUID_AFS_REPARSE_GUID,
                                          sizeof( GUID)) != sizeof( GUID))
                    {

                        ntStatus = STATUS_REPARSE_ATTRIBUTE_CONFLICT;

                        break;
                    }

                    if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                                                        sizeof( AFSReparseTagInfo))
                    {

                        ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                        break;
                    }

                    pReparseInfo = (AFSReparseTagInfo *)pReparseGUIDBuffer->GenericReparseBuffer.DataBuffer;

                    switch( pReparseInfo->SubTag)
                    {

                        case OPENAFS_SUBTAG_SYMLINK:
                        {

                            if( ulInputBufferLen < (ULONG)(FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                                           FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) +
                                                           pReparseInfo->AFSSymLink.SymLinkTargetLength))
                            {

                                ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                                break;
                            }

                            uniTargetName.Length = pReparseInfo->AFSSymLink.SymLinkTargetLength;
                            uniTargetName.MaximumLength = uniTargetName.Length;

                            uniTargetName.Buffer = (WCHAR *)pReparseInfo->AFSSymLink.Buffer;

                            break;
                        }

                        case OPENAFS_SUBTAG_UNC:
                        {

                            if( ulInputBufferLen < (ULONG)(FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
                                                           FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) +
                                                           pReparseInfo->UNCReferral.UNCTargetLength))
                            {

                                ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                                break;
                            }

                            uniTargetName.Length = pReparseInfo->UNCReferral.UNCTargetLength;
                            uniTargetName.MaximumLength = uniTargetName.Length;

                            uniTargetName.Buffer = (WCHAR *)pReparseInfo->UNCReferral.Buffer;

                            break;
                        }

                        case OPENAFS_SUBTAG_MOUNTPOINT:
                            //
                            // Not yet handled
                            //
                        default:
                        {

                            ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                            break;
                        }
                    }
                }
                else
                {
                    //
                    // Handle Microsoft Reparse Tags
                    //

                    switch( pReparseGUIDBuffer->ReparseTag)
                    {

                        case IO_REPARSE_TAG_MOUNT_POINT:
                        {

                            pReparseBuffer = (REPARSE_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;

                            uniTargetName.Length = pReparseBuffer->MountPointReparseBuffer.PrintNameLength;
                            uniTargetName.MaximumLength = uniTargetName.Length;

                            uniTargetName.Buffer = (WCHAR *)((char *)pReparseBuffer->MountPointReparseBuffer.PathBuffer +
                                                              pReparseBuffer->MountPointReparseBuffer.PrintNameOffset);

                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                          AFS_TRACE_LEVEL_VERBOSE_2,
                                          "AFSProcessUserFsRequest IO_REPARSE_TAG_MOUNT_POINT request %wZ\n",
                                          &uniTargetName));

                            ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                            break;
                        }

                        case IO_REPARSE_TAG_SYMLINK:
                        {

                            pReparseBuffer = (REPARSE_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;

                            uniTargetName.Length = pReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
                            uniTargetName.MaximumLength = uniTargetName.Length;

                            uniTargetName.Buffer = (WCHAR *)((char *)pReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer +
                                                              pReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset);

                            AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                          AFS_TRACE_LEVEL_VERBOSE_2,
                                          "AFSProcessUserFsRequest IO_REPARSE_TAG_SYMLINK request %wZ\n",
                                          &uniTargetName));
                            break;
                        }

                        default:
                        {

                            ntStatus = STATUS_IO_REPARSE_DATA_INVALID;

                            break;
                        }
                    }
                }

                if( !NT_SUCCESS( ntStatus))
                {

                    break;
                }

                //
                // First thing is to locate/create our object information block
                // for this entry
                //

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

                if ( AFSIsVolumeFID( &pFcb->ObjectInformation->ParentFileId))
                {

                    pParentObjectInfo = &pFcb->ObjectInformation->VolumeCB->ObjectInformation;
                }
                else
                {
                    ullIndex = AFSCreateLowIndex( &pFcb->ObjectInformation->ParentFileId);

                    ntStatus = AFSLocateHashEntry( pFcb->ObjectInformation->VolumeCB->ObjectInfoTree.TreeHead,
                                                   ullIndex,
                                                   (AFSBTreeEntry **)&pParentObjectInfo);
                }

                if ( NT_SUCCESS( ntStatus))
                {

                    lCount = AFSObjectInfoIncrement( pParentObjectInfo,
                                                     AFS_OBJECT_REFERENCE_FS_REQ);

                    AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSProcessUserFsRequest Increment count on object %p Cnt %d\n",
                                  pParentObjectInfo,
                                  lCount));

                    KeQueryTickCount( &pParentObjectInfo->LastAccessCount);
                }

                AFSReleaseResource( pFcb->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);

                if ( NT_SUCCESS( ntStatus))
                {

                    //
                    // Extract out the information to the call to the service
                    //

                    ntStatus = AFSCreateSymlink( &pCcb->AuthGroup,
                                                 pParentObjectInfo,
                                                 &pCcb->DirectoryCB->NameInformation.FileName,
                                                 pFcb->ObjectInformation,
                                                 &uniTargetName);

                    AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE_2,
                                  "AFSProcessUserFsRequest Processed FSCTL_SET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x Status %08lX\n",
                                  &pCcb->DirectoryCB->NameInformation.FileName,
                                  pFcb->ObjectInformation->FileType,
                                  pFcb->ObjectInformation->FileAttributes,
                                  ntStatus));

                    AFSAcquireShared( pFcb->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock,
                                      TRUE);

                    lCount = AFSObjectInfoDecrement( pParentObjectInfo,
                                                     AFS_OBJECT_REFERENCE_FS_REQ);

                    AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "AFSProcessUserFsRequest Decrement count on object %p Cnt %d\n",
                                  pParentObjectInfo,
                                  lCount));

                    AFSReleaseResource( pFcb->ObjectInformation->VolumeCB->ObjectInfoTree.TreeLock);
                }

                break;
            }

            case FSCTL_DELETE_REPARSE_POINT:
            {

                REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;

                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing FSCTL_DELETE_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
                              &pCcb->DirectoryCB->NameInformation.FileName,
                              pFcb->ObjectInformation->FileType,
                              pFcb->ObjectInformation->FileAttributes));

                //
                // Check if we have the reparse entry set on the entry
                //

                if( !BooleanFlagOn( pFcb->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
                {

                    ntStatus = STATUS_NOT_A_REPARSE_POINT;

                    break;
                }

                if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
                {

                    ntStatus = STATUS_INVALID_PARAMETER;

                    break;
                }

                if( (pReparseBuffer->ReparseTag & 0x0000FFFF) != IO_REPARSE_TAG_OPENAFS_DFS)
                {

                    ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;

                    break;
                }

                if( RtlCompareMemory( &pReparseBuffer->ReparseGuid,
                                      &GUID_AFS_REPARSE_GUID,
                                      sizeof( GUID)) != sizeof( GUID))
                {

                    ntStatus = STATUS_REPARSE_ATTRIBUTE_CONFLICT;

                    break;
                }

                //
                // Claim success.  The typical usage is setting delete on close
                // as the next operation on the reparse point before closing
                // the handle.
                //

                ntStatus = STATUS_SUCCESS;

                break;
            }

#ifndef FSCTL_SET_PURGE_FAILURE_MODE
#define FSCTL_SET_PURGE_FAILURE_MODE        CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 156, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif

            case FSCTL_SET_PURGE_FAILURE_MODE:
            {

                //
                // For the time being just succeed this call
                //

                ntStatus = STATUS_SUCCESS;

                break;
            }

            default :
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE_2,
                              "AFSProcessUserFsRequest Processing default (%08lX) request\n",
                              ulFsControlCode));

                ntStatus = STATUS_INVALID_DEVICE_REQUEST;

                break;
            }
        }

try_exit:

        NOTHING;
    }

    return ntStatus;
}
コード例 #7
0
ファイル: AFSProcessSupport.cpp プロジェクト: bagdxk/openafs
GUID *
AFSValidateProcessEntry( IN HANDLE  ProcessId,
                         IN BOOLEAN bProcessTreeLocked)
{

    GUID *pAuthGroup = NULL;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    ULONGLONG ullProcessID = (ULONGLONG)ProcessId;
    UNICODE_STRING uniSIDString;
    ULONG ulSIDHash = 0;
    AFSSIDEntryCB *pSIDEntryCB = NULL;
    ULONG ulSessionId = 0;
    ULONGLONG ullTableHash = 0;
    AFSThreadCB *pParentThreadCB = NULL;
    UNICODE_STRING uniGUID;
    BOOLEAN bImpersonation = FALSE;

    __Enter
    {

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

        if ( !bProcessTreeLocked)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n",
                          pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                          PsGetCurrentThread()));

            AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                              TRUE);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Entry for ProcessID %I64X\n",
                      __FUNCTION__,
                      ullProcessID));

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                       ullProcessID,
                                       (AFSBTreeEntry **)&pProcessCB);

        if( !NT_SUCCESS( ntStatus) ||
            pProcessCB == NULL)
        {

            if ( !bProcessTreeLocked)
            {

                AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);

                AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                                TRUE);
            }

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           ullProcessID,
                                           (AFSBTreeEntry **)&pProcessCB);

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSProcessCreate( 0,
                                  ProcessId,
                                  0,
                                  0);
            }

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "%s Failed to locate process entry for ProcessID %I64X\n",
                              __FUNCTION__,
                              ullProcessID));

                try_return( ntStatus = STATUS_UNSUCCESSFUL);
            }

            if ( !bProcessTreeLocked)
            {

                AFSConvertToShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
            }
        }

        //
        // Locate and lock the ParentProcessCB if we have one
        //

        if( pProcessCB->ParentProcessId != 0)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Locating process entry for Parent ProcessID %I64X\n",
                          __FUNCTION__,
                          pProcessCB->ParentProcessId));

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           (ULONGLONG)pProcessCB->ParentProcessId,
                                           (AFSBTreeEntry **)&pParentProcessCB);

            if( NT_SUCCESS( ntStatus) &&
                pParentProcessCB != NULL)
            {
                AFSAcquireExcl( &pParentProcessCB->Lock,
                                TRUE);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located process entry for Parent ProcessID %I64X\n",
                              __FUNCTION__,
                              pProcessCB->ParentProcessId));
            }
        }
        else
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s No parent ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));
        }

        AFSAcquireExcl( &pProcessCB->Lock,
                        TRUE);

#if defined(_WIN64)

        //
        // Mark the process as 64-bit if it is.
        //

        if( !IoIs32bitProcess( NULL))
        {

            SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
        else
        {

            ClearFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
#endif

        //
        // Locate the SID for the caller
        //

        ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to locate callers SID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus);
        }

        ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);

        if( ulSessionId == (ULONG)-1)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to retrieve session ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        //
        // If there is an Auth Group for the current process,
        // our job is finished.
        //

        if ( bImpersonation == FALSE)
        {
            pAuthGroup = pProcessCB->ActiveAuthGroup;

            if( pAuthGroup != NULL &&
                !AFSIsNoPAGAuthGroup( pAuthGroup))
            {

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( *pAuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n",
                              __FUNCTION__,
                              &uniGUID,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId));

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

                try_return( ntStatus = STATUS_SUCCESS);
            }

            //
            // The current process does not yet have an Auth Group.  Try to inherit
            // one from the parent process thread that created this process.
            //

            if( pParentProcessCB != NULL)
            {

                for ( pParentThreadCB = pParentProcessCB->ThreadList;
                      pParentThreadCB != NULL;
                      pParentThreadCB = pParentThreadCB->Next)
                {

                    if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId)
                    {
                        break;
                    }
                }

                //
                // If the creating thread was found and it has a thread specific
                // Auth Group, use that even if it is the No PAG
                //

                if( pParentThreadCB != NULL &&
                    pParentThreadCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentThreadCB->ThreadId));

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

                //
                // If the parent thread was not found or does not have an auth group
                //

                else if( pParentProcessCB->ActiveAuthGroup != NULL &&
                         !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentProcessCB->TreeEntry.HashIndex));

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

                //
                // If an Auth Group was inherited, set it to be the active group
                //

                if( pProcessCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pAuthGroup = pProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                                  __FUNCTION__,
                                  &uniGUID,
                                  &uniSIDString,
                                  ullProcessID,
                                  ulSessionId));

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

                    try_return( ntStatus);
                }
            }
        }

        //
        // If no Auth Group was inherited, assign one based upon the Session and SID
        //

        ntStatus = RtlHashUnicodeString( &uniSIDString,
                                         TRUE,
                                         HASH_STRING_ALGORITHM_DEFAULT,
                                         &ulSIDHash);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n",
                          __FUNCTION__,
                          &uniSIDString,
                          ullProcessID,
                          ulSessionId,
                          ntStatus));

            try_return( ntStatus);
        }

        ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);

        AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                          TRUE);

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                       (ULONGLONG)ullTableHash,
                                       (AFSBTreeEntry **)&pSIDEntryCB);

        if( !NT_SUCCESS( ntStatus) ||
            pSIDEntryCB == NULL)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

            AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                            TRUE);

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                           (ULONGLONG)ullTableHash,
                                           (AFSBTreeEntry **)&pSIDEntryCB);

            if( !NT_SUCCESS( ntStatus) ||
                pSIDEntryCB == NULL)
            {

                pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                         sizeof( AFSSIDEntryCB),
                                                                         AFS_AG_ENTRY_CB_TAG);

                if( pSIDEntryCB == NULL)
                {

                    AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                }

                RtlZeroMemory( pSIDEntryCB,
                               sizeof( AFSSIDEntryCB));

                pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;

                while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s  SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n",
                              __FUNCTION__,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId,
                              &uniGUID));

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

                if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
                {
                    pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
                }
                else
                {
                    AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                        &pSIDEntryCB->TreeEntry);
                }
            }

            AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
        }


        AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

        //
        // Store the auth group into the process cb
        //

        pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId,
                      &uniGUID));

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

        //
        // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID
        // is LOCAL_SYSTEM
        //

        if( AFSIsLocalSystemSID( &uniSIDString))
        {
            SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH);

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n",
                          __FUNCTION__,
                          ullProcessID,
                          ulSessionId));
        }

        //
        // Return the auth group
        //

        pAuthGroup = pProcessCB->ActiveAuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniGUID,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

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

try_exit:

        if( pProcessCB != NULL)
        {

            if( bImpersonation == FALSE &&
                !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) &&
                NT_SUCCESS( ntStatus))
            {
                ntStatus = AFSProcessSetProcessDacl( pProcessCB);

                if( !NT_SUCCESS( ntStatus))
                {
                    pAuthGroup = NULL;
                }
                else
                {
                    SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET);
                }
            }

            AFSReleaseResource( &pProcessCB->Lock);
        }

        if( pParentProcessCB != NULL)
        {
            AFSReleaseResource( &pParentProcessCB->Lock);
        }

        if( uniSIDString.Length > 0)
        {
            RtlFreeUnicodeString( &uniSIDString);
        }

        if ( !bProcessTreeLocked)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
        }
    }

    return pAuthGroup;
}
コード例 #8
0
ファイル: AFSLibrarySupport.cpp プロジェクト: bagdxk/openafs
NTSTATUS
AFSCheckLibraryState( IN PIRP Irp)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
    PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);

    __Enter
    {

        AFSAcquireShared( &pDevExt->Specific.Control.LibraryStateLock,
                          TRUE);

        AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Entry State %08lX Irp %p Function %08lX\n",
                      __FUNCTION__,
                      pRDRDevExt->DeviceFlags,
                      Irp,
                      pIrpSp->MajorFunction));

        if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
        {

            try_return( ntStatus = STATUS_DEVICE_NOT_READY);
        }

        if( !BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED))
        {

            if( Irp != NULL)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Queuing request %p\n",
                              __FUNCTION__,
                              Irp));

                ntStatus = AFSQueueLibraryRequest( Irp);

                AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Queued request %p Status %08lX\n",
                              __FUNCTION__,
                              Irp,
                              ntStatus));
            }
            else
            {

                ntStatus = STATUS_TOO_LATE;

                AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Failing request %p\n",
                              __FUNCTION__,
                              Irp));
            }

            try_return( ntStatus);
        }

        if( InterlockedIncrement( &pDevExt->Specific.Control.InflightLibraryRequests) == 1)
        {
            KeClearEvent( &pDevExt->Specific.Control.InflightLibraryEvent);
        }

try_exit:

        AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Completed Irp %p Status %08lX Inflight Count %08lX\n",
                      __FUNCTION__,
                      Irp,
                      ntStatus,
                      pDevExt->Specific.Control.InflightLibraryRequests));

        AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);
    }

    return ntStatus;
}