#define AFS_DEVICE_FLAG_HIDE_DOT_NAMES 0x00000001
#define AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN 0x00000002
#define AFS_DEVICE_FLAG_DISABLE_SHORTNAMES 0x00000004
+#define AFS_DEVICE_FLAG_DIRECT_SERVICE_IO 0x00000008
#endif
#define AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS 0x00000021
#define AFS_REQUEST_TYPE_GET_VOLUME_SIZE_INFO 0x00000022
#define AFS_REQUEST_TYPE_HARDLINK_FILE 0x00000023
+#define AFS_REQUEST_TYPE_PROCESS_READ_FILE 0x00000024
+#define AFS_REQUEST_TYPE_PROCESS_WRITE_FILE 0x00000025
//
// Request Flags, these are passed up from the file system
#define AFS_REQUEST_LOCAL_SYSTEM_PAG 0x00000200 // Indicates that the caller is or was at some point a system
// process
+#define AFS_REQUEST_FLAG_CACHE_BYPASS 0x00000400 // Indicates that the AFS_REQUEST_TYPE_PROCESS_READ_FILE or
+ // AFS_REQUEST_TYPE_PROCESS_WRITE_FILE is to be performed directly
+ // against the file server bypassing the AFS Cache file.
+
#define AFS_REQUEST_FLAG_LAST_COMPONENT 0x00000800 // During an AFS_REQUEST_TYPE_TARGET_BY_NAME the provided name
// is the last component in the path.
#define AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES 0x00000001
#define AFS_REDIR_INIT_NO_PAGING_FILE 0x00000002
#define AFS_REDIR_INIT_FLAG_DISABLE_SHORTNAMES 0x00000004
+#define AFS_REDIR_INIT_PERFORM_SERVICE_IO 0x00000008
typedef struct _AFS_REDIR_INIT_INFO_CB
{
} AFSReparseTagInfo;
+//
+// File IO CB
+//
+
+typedef struct _AFS_FILE_IO_CB
+{
+
+ LARGE_INTEGER IOOffset;
+
+ ULONG IOLength;
+
+ void *MappedIOBuffer; // Mapped buffer for access by service
+
+ void *SystemIOBuffer; // Service should not access this pointer
+
+ void *SystemIOBufferMdl; // The service should not access this pointer
+
+ LARGE_INTEGER LastAccessTime;
+
+ LARGE_INTEGER LastWriteTime;
+
+ LARGE_INTEGER ChangeTime;
+
+ LARGE_INTEGER CreateTime;
+
+ LARGE_INTEGER EndOfFile;
+
+} AFSFileIOCB;
+
+typedef struct _AFS_FILE_IO_RESULT_CB
+{
+
+ ULONG Length;
+
+ LARGE_INTEGER DataVersion;
+
+ LARGE_INTEGER Expiration; /* FILETIME */
+
+} AFSFileIOResultCB;
+
#endif /* _AFS_USER_STRUCT_H */
pEntry->ResultStatus = (ULONG) STATUS_CANCELLED;
+ if( pEntry->RequestType == AFS_REQUEST_TYPE_PROCESS_READ_FILE ||
+ pEntry->RequestType == AFS_REQUEST_TYPE_PROCESS_WRITE_FILE)
+ {
+
+ AFSFileIOCB *pFileIO = (AFSFileIOCB *)pEntry->Data;
+
+ if( pFileIO->MappedIOBuffer != NULL)
+ {
+ MmUnmapLockedPages( pFileIO->MappedIOBuffer,
+ (PMDL)pFileIO->SystemIOBufferMdl);
+
+ pFileIO->MappedIOBuffer = NULL;
+ }
+ }
+
//
// Here we will set the event of the requestor and let the blocked thread
// free the data block
pRequest->NameLength);
}
+ //
+ // If this is an IO request then need to map the system buffer to the service process
+ //
+
+ if( pEntry->RequestType == AFS_REQUEST_TYPE_PROCESS_READ_FILE ||
+ pEntry->RequestType == AFS_REQUEST_TYPE_PROCESS_WRITE_FILE)
+ {
+
+ AFSFileIOCB *pFileIO = (AFSFileIOCB *)pEntry->Data;
+
+ ASSERT( pFileIO->SystemIOBuffer != NULL);
+
+ pFileIO->MappedIOBuffer = MmMapLockedPagesSpecifyCache( (PMDL)pFileIO->SystemIOBufferMdl,
+ UserMode,
+ MmCached,
+ NULL,
+ FALSE,
+ NormalPagePriority);
+ }
+
pRequest->DataOffset = 0;
pRequest->DataLength = pEntry->DataLength;
}
//
+ // If this is an IO request, unmap the user buffer
+ //
+
+ if( pCurrentEntry->RequestType == AFS_REQUEST_TYPE_PROCESS_READ_FILE ||
+ pCurrentEntry->RequestType == AFS_REQUEST_TYPE_PROCESS_WRITE_FILE)
+ {
+
+ AFSFileIOCB *pFileIO = (AFSFileIOCB *)pCurrentEntry->Data;
+
+ if( pFileIO->MappedIOBuffer != NULL)
+ {
+ MmUnmapLockedPages( pFileIO->MappedIOBuffer,
+ (PMDL)pFileIO->SystemIOBufferMdl);
+
+ pFileIO->MappedIOBuffer = NULL;
+ }
+ }
+
+ //
// OK, move in the result information
//
SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES);
}
- if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
- RedirInitInfo->MemoryCacheLength.QuadPart != 0)
+ //
+ // Are we performing direct to service IO?
+ //
+
+ if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_PERFORM_SERVICE_IO))
{
- ntStatus = STATUS_INSUFFICIENT_RESOURCES;
+ //
+ // Send IO requests directly to service
+ //
-#ifdef AMD64
- pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
- (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
- RedirInitInfo->MemoryCacheLength.QuadPart);
-#else
- pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
- (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
- RedirInitInfo->MemoryCacheLength.LowPart);
-#endif
+ SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO);
+ }
+ else
+ {
- if( pDevExt->Specific.RDR.CacheMdl != NULL)
+ if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 &&
+ RedirInitInfo->MemoryCacheLength.QuadPart != 0)
{
- __try
- {
+ ntStatus = STATUS_INSUFFICIENT_RESOURCES;
- MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
- KernelMode,
- IoModifyAccess);
+#ifdef AMD64
+ pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
+ (void *)RedirInitInfo->MemoryCacheOffset.QuadPart,
+ RedirInitInfo->MemoryCacheLength.QuadPart);
+#else
+ pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL,
+ (void *)RedirInitInfo->MemoryCacheOffset.LowPart,
+ RedirInitInfo->MemoryCacheLength.LowPart);
+#endif
- pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
- NormalPagePriority);
- }
- __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+ if( pDevExt->Specific.RDR.CacheMdl != NULL)
{
- AFSDumpTraceFilesFnc();
-
- IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
- pDevExt->Specific.RDR.CacheMdl = NULL;
- }
+ __try
+ {
- if( pDevExt->Specific.RDR.CacheMdl != NULL)
- {
- pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
- ntStatus = STATUS_SUCCESS;
- }
+ MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl,
+ KernelMode,
+ IoModifyAccess);
- }
- }
+ pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl,
+ NormalPagePriority);
+ }
+ __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
+ {
- if( !NT_SUCCESS( ntStatus) &&
- RedirInitInfo->CacheFileNameLength == 0)
- {
+ AFSDumpTraceFilesFnc();
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
- ntStatus);
+ IoFreeMdl( pDevExt->Specific.RDR.CacheMdl);
+ pDevExt->Specific.RDR.CacheMdl = NULL;
+ }
- try_return( ntStatus);
- }
+ if( pDevExt->Specific.RDR.CacheMdl != NULL)
+ {
+ pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength;
+ ntStatus = STATUS_SUCCESS;
+ }
- if( pDevExt->Specific.RDR.CacheMdl == NULL)
- {
+ }
+ }
- if( RedirInitInfo->CacheFileNameLength == 0)
+ if( !NT_SUCCESS( ntStatus) &&
+ RedirInitInfo->CacheFileNameLength == 0)
{
AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector CacheMdl == NULL\n");
+ "AFSInitializeRedirector Unable to initialize cache file %08lX\n",
+ ntStatus);
- try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ try_return( ntStatus);
}
- //
- // Go open the cache file
- //
+ if( pDevExt->Specific.RDR.CacheMdl == NULL)
+ {
- pDevExt->Specific.RDR.CacheFile.Length = 0;
- pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));
+ if( RedirInitInfo->CacheFileNameLength == 0)
+ {
- pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
- pDevExt->Specific.RDR.CacheFile.MaximumLength,
- AFS_GENERIC_MEMORY_24_TAG);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector CacheMdl == NULL\n");
- if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
- {
+ try_return( ntStatus = STATUS_INVALID_PARAMETER);
+ }
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n");
+ //
+ // Go open the cache file
+ //
- try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
- }
+ pDevExt->Specific.RDR.CacheFile.Length = 0;
+ pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR));
- RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
- L"\\??\\",
- 4 * sizeof( WCHAR));
+ pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
+ pDevExt->Specific.RDR.CacheFile.MaximumLength,
+ AFS_GENERIC_MEMORY_24_TAG);
- pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);
+ if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL)
+ {
- RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
- RedirInitInfo->CacheFileName,
- RedirInitInfo->CacheFileNameLength);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n");
- pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
- InitializeObjectAttributes( &stObjectAttribs,
- &pDevExt->Specific.RDR.CacheFile,
- OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer,
+ L"\\??\\",
+ 4 * sizeof( WCHAR));
- ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
- GENERIC_READ | GENERIC_WRITE,
- &stObjectAttribs,
- &stIoStatus,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);
+ pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR);
- if( !NT_SUCCESS( ntStatus))
- {
+ RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)],
+ RedirInitInfo->CacheFileName,
+ RedirInitInfo->CacheFileNameLength);
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
- ntStatus);
+ pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength;
- try_return( ntStatus);
- }
+ InitializeObjectAttributes( &stObjectAttribs,
+ &pDevExt->Specific.RDR.CacheFile,
+ OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- //
- // Map to the fileobject
- //
+ ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle,
+ GENERIC_READ | GENERIC_WRITE,
+ &stObjectAttribs,
+ &stIoStatus,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS);
- ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
- SYNCHRONIZE,
- NULL,
- KernelMode,
- (void **)&pDevExt->Specific.RDR.CacheFileObject,
- NULL);
+ if( !NT_SUCCESS( ntStatus))
+ {
- if( !NT_SUCCESS( ntStatus))
- {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector ZwOpenFile failure %08lX\n",
+ ntStatus);
- AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
- AFS_TRACE_LEVEL_ERROR,
- "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
- ntStatus);
+ try_return( ntStatus);
+ }
- try_return( ntStatus);
+ //
+ // Map to the fileobject
+ //
+
+ ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle,
+ SYNCHRONIZE,
+ NULL,
+ KernelMode,
+ (void **)&pDevExt->Specific.RDR.CacheFileObject,
+ NULL);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n",
+ ntStatus);
+
+ try_return( ntStatus);
+ }
}
}
return ntStatus;
}
+static
+NTSTATUS
+AFSNonCachedReadDirect( IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN LARGE_INTEGER StartingByte)
+{
+ NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
+ IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+ PFILE_OBJECT pFileObject = pIrpSp->FileObject;
+ AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
+ AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
+ VOID *pSystemBuffer = NULL;
+ ULONG ulByteCount = 0;
+ ULONG ulReadByteCount = 0;
+ ULONG ulFlags;
+ BOOLEAN bNoIntermediateBuffering = BooleanFlagOn( pFileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING);
+ AFSDeviceExt *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
+ AFSFileIOCB stFileIORequest;
+ AFSFileIOResultCB stFileIOResult;
+ ULONG ulResultLen = 0;
+
+ __Enter
+ {
+
+ Irp->IoStatus.Information = 0;
+
+ ulByteCount = pIrpSp->Parameters.Read.Length;
+
+ if (ulByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNonCachedReadDirect (%p) Request larger than MaxIO %I64X\n",
+ Irp,
+ pDevExt->Specific.RDR.MaxIo.QuadPart);
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ pSystemBuffer = AFSLockSystemBuffer( Irp,
+ ulByteCount);
+
+ if( pSystemBuffer == NULL)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNonCachedReadDirect (%p) Failed to map system buffer\n",
+ Irp);
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ if( StartingByte.QuadPart + ulByteCount > pFcb->Header.FileSize.QuadPart)
+ {
+ ULONG zeroCount = (ULONG) (StartingByte.QuadPart + ulByteCount - pFcb->Header.FileSize.QuadPart);
+ ulReadByteCount = (ULONG)(pFcb->Header.FileSize.QuadPart - StartingByte.QuadPart);
+
+ //
+ // Clear up to EOF
+ //
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNonCachedReadDirect (%p) Zeroing to EOF zero byte length %08lX\n",
+ Irp,
+ zeroCount);
+
+ RtlZeroMemory( ((PCHAR)pSystemBuffer) + ulReadByteCount, zeroCount);
+ }
+ else
+ {
+ ulReadByteCount = ulByteCount;
+ }
+
+ //
+ // Issue the request at the service for processing
+ //
+
+ ulResultLen = sizeof( AFSFileIOResultCB);
+
+ RtlZeroMemory( &stFileIORequest,
+ sizeof( AFSFileIOCB));
+
+ RtlZeroMemory( &stFileIOResult,
+ sizeof( AFSFileIOResultCB));
+
+ stFileIORequest.SystemIOBuffer = pSystemBuffer;
+
+ stFileIORequest.SystemIOBufferMdl = Irp->MdlAddress;
+
+ stFileIORequest.IOOffset = StartingByte;
+
+ stFileIORequest.IOLength = ulReadByteCount;
+
+ ulFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
+
+ if ( bNoIntermediateBuffering)
+ {
+
+ ulFlags |= AFS_REQUEST_FLAG_CACHE_BYPASS;
+ }
+
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PROCESS_READ_FILE,
+ ulFlags,
+ &pCcb->AuthGroup,
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ &pFcb->ObjectInformation->FileId,
+ pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
+ pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
+ &stFileIORequest,
+ sizeof( AFSFileIOCB),
+ &stFileIOResult,
+ &ulResultLen);
+
+ if( NT_SUCCESS( ntStatus))
+ {
+
+ Irp->IoStatus.Information = (ULONG_PTR)stFileIOResult.Length;
+ }
+ else
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNonCachedReadDirect (%p) Failed to send read to service Status %08lX\n",
+ Irp,
+ ntStatus);
+ }
+
+try_exit:
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNonCachedReadDirect (%p) Completed request Status %08lX\n",
+ Irp,
+ ntStatus);
+
+ if (NT_SUCCESS(ntStatus) &&
+ !BooleanFlagOn( Irp->Flags, IRP_PAGING_IO) &&
+ BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO))
+ {
+ //
+ // Update the CBO if this is a sync, nopaging read
+ //
+ pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ulByteCount;
+ }
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNonCachedReadDirect Completing irp %08lX Status %08lX Info %08lX\n",
+ Irp,
+ ntStatus,
+ Irp->IoStatus.Information);
+
+ AFSCompleteRequest( Irp, ntStatus );
+ }
+
+ return ntStatus;
+}
+
//
// Function: AFSDispatch
//
PFILE_OBJECT pFileObject = NULL;
LARGE_INTEGER liStartingByte;
ULONG ulByteCount;
+ AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
pIrpSp = IoGetCurrentIrpStackLocation( Irp);
pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
// No fileobject yet? Bail.
//
if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
+ !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_REDIR_INIT_PERFORM_SERVICE_IO) &&
NULL == pDeviceExt->Specific.RDR.CacheFileObject)
{
liStartingByte.QuadPart,
ulByteCount);
- ntStatus = AFSNonCachedRead( DeviceObject, Irp, liStartingByte);
+ if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
+ {
+
+ ntStatus = AFSNonCachedReadDirect( DeviceObject, Irp, liStartingByte);
+ }
+ else
+ {
+ ntStatus = AFSNonCachedRead( DeviceObject, Irp, liStartingByte);
+ }
}
try_exit:
static
NTSTATUS
+AFSNonCachedWriteDirect( IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN LARGE_INTEGER StartingByte,
+ IN ULONG ByteCount);
+
+static
+NTSTATUS
AFSExtendingWrite( IN AFSFcb *Fcb,
IN PFILE_OBJECT FileObject,
IN LONGLONG NewLength);
BOOLEAN bLockOK;
HANDLE hCallingUser = OnBehalfOf;
ULONGLONG ullProcessId = (ULONGLONG)PsGetCurrentProcessId();
+ AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
pIrpSp = IoGetCurrentIrpStackLocation( Irp);
// Is the Cache not there yet? Exit.
//
if( !BooleanFlagOn( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE) &&
+ !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_REDIR_INIT_PERFORM_SERVICE_IO) &&
NULL == pDeviceExt->Specific.RDR.CacheFileObject)
{
ulByteCount,
bRetry ? " RETRY" : "");
- ntStatus = AFSNonCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount);
+ if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
+ {
+
+ ntStatus = AFSNonCachedWriteDirect( DeviceObject, Irp, liStartingByte, ulByteCount);
+ }
+ else
+ {
+ ntStatus = AFSNonCachedWrite( DeviceObject, Irp, liStartingByte, ulByteCount);
+ }
}
try_exit:
static
NTSTATUS
+AFSNonCachedWriteDirect( IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN LARGE_INTEGER StartingByte,
+ IN ULONG ByteCount)
+{
+ NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
+ VOID *pSystemBuffer = NULL;
+ BOOLEAN bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO);
+ IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
+ PFILE_OBJECT pFileObject = pIrpSp->FileObject;
+ AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext;
+ AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2;
+ BOOLEAN bSynchronousFo = BooleanFlagOn( pFileObject->Flags, FO_SYNCHRONOUS_IO);
+ BOOLEAN bNoIntermediateBuffering = BooleanFlagOn( pFileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING);
+ AFSDeviceExt *pDevExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
+ AFSFileIOCB stFileIORequest;
+ AFSFileIOResultCB stFileIOResult;
+ ULONG ulResultLen = 0;
+ ULONG ulFlags;
+
+ __Enter
+ {
+ Irp->IoStatus.Information = 0;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNonCachedWriteDirect (FO: %p) StartingByte %08lX:%08lX Length %08lX\n",
+ pFileObject,
+ StartingByte.HighPart,
+ StartingByte.LowPart,
+ ByteCount);
+
+ if (ByteCount > pDevExt->Specific.RDR.MaxIo.QuadPart)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNonCachedWriteDirect (%p) Request %08lX Actual %08lX larger than MaxIO %I64X\n",
+ Irp,
+ ByteCount,
+ pIrpSp->Parameters.Write.Length,
+ pDevExt->Specific.RDR.MaxIo.QuadPart);
+
+ try_return( ntStatus = STATUS_UNSUCCESSFUL);
+ }
+
+ //
+ // Get the mapping for the buffer
+ //
+ pSystemBuffer = AFSLockSystemBuffer( Irp,
+ ByteCount);
+
+ if( pSystemBuffer == NULL)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNonCachedWriteDirect (%p) Failed to map system buffer\n",
+ Irp);
+
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ //
+ // Issue the request at the service for processing
+ //
+
+ ulResultLen = sizeof( AFSFileIOResultCB);
+
+ RtlZeroMemory( &stFileIORequest,
+ sizeof( AFSFileIOCB));
+
+ RtlZeroMemory( &stFileIOResult,
+ sizeof( AFSFileIOResultCB));
+
+ stFileIORequest.SystemIOBuffer = pSystemBuffer;
+
+ stFileIORequest.SystemIOBufferMdl = Irp->MdlAddress;
+
+ stFileIORequest.IOLength = ByteCount;
+
+ stFileIORequest.IOOffset = StartingByte;
+
+ ulFlags = AFS_REQUEST_FLAG_SYNCHRONOUS;
+
+ if ( bNoIntermediateBuffering)
+ {
+
+ ulFlags |= AFS_REQUEST_FLAG_CACHE_BYPASS;
+ }
+
+ //
+ // Update file metadata
+ //
+
+ stFileIORequest.EndOfFile = pFcb->ObjectInformation->EndOfFile;
+
+ stFileIORequest.CreateTime = pFcb->ObjectInformation->CreationTime;
+
+ stFileIORequest.ChangeTime = pFcb->ObjectInformation->ChangeTime;
+
+ stFileIORequest.LastAccessTime = pFcb->ObjectInformation->LastAccessTime;
+
+ stFileIORequest.LastWriteTime = pFcb->ObjectInformation->LastWriteTime;
+
+ //
+ // Write the data to the service
+ //
+
+ ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PROCESS_WRITE_FILE,
+ ulFlags,
+ &pCcb->AuthGroup,
+ &pCcb->DirectoryCB->NameInformation.FileName,
+ &pFcb->ObjectInformation->FileId,
+ pFcb->ObjectInformation->VolumeCB->VolumeInformation.Cell,
+ pFcb->ObjectInformation->VolumeCB->VolumeInformation.CellLength,
+ &stFileIORequest,
+ sizeof( AFSFileIOCB),
+ &stFileIOResult,
+ &ulResultLen);
+
+ if( NT_SUCCESS( ntStatus))
+ {
+
+ Irp->IoStatus.Information = (ULONG_PTR)stFileIOResult.Length;
+ }
+ else
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_ERROR,
+ "AFSNonCachedWriteDirect (%p) Failed to send write to service Status %08lX\n",
+ Irp,
+ ntStatus);
+
+ }
+
+try_exit:
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNonCachedWriteDirect (FO: %p) StartingByte %08lX:%08lX Length %08lX Status %08lX\n",
+ pFileObject,
+ StartingByte.HighPart,
+ StartingByte.LowPart,
+ ByteCount,
+ ntStatus);
+
+ if (NT_SUCCESS(ntStatus) &&
+ !bPagingIo &&
+ bSynchronousFo)
+ {
+
+ pFileObject->CurrentByteOffset.QuadPart = StartingByte.QuadPart + ByteCount;
+ }
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSNonCachedWriteDirect Completing Irp %p Status %08lX Info %08lX\n",
+ Irp,
+ ntStatus,
+ Irp->IoStatus.Information);
+
+ AFSCompleteRequest( Irp, ntStatus);
+ }
+
+ return ntStatus;
+}
+
+static
+NTSTATUS
AFSCachedWrite( IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN LARGE_INTEGER StartingByte,