DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = CdfsFsdDispatch;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = CdfsFsdDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CdfsFsdDispatch;
+ DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = CdfsFsdDispatch;
CdfsGlobalData->FastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
CdfsGlobalData->FastIoDispatch.FastIoCheckIfPossible = CdfsFastIoCheckIfPossible;
ERESOURCE NameListResource;
LIST_ENTRY ShortNameList;
+ FILE_LOCK FileLock;
} FCB, *PFCB;
/* FUNCTIONS ****************************************************************/
static NTSTATUS
-CdfsCleanupFile(PDEVICE_EXTENSION DeviceExt,
+CdfsCleanupFile(PCDFS_IRP_CONTEXT IrpContext,
PFILE_OBJECT FileObject)
/*
* FUNCTION: Cleans up after a file has been closed.
*/
{
+ PDEVICE_EXTENSION DeviceExt;
PFCB Fcb;
DPRINT("CdfsCleanupFile(DeviceExt %p, FileObject %p)\n",
DeviceExt,
FileObject);
+ DeviceExt = IrpContext->DeviceObject->DeviceExtension;
Fcb = FileObject->FsContext;
if (!Fcb)
{
&(DeviceExt->NotifyList),
FileObject->FsContext2);
+ if (!CdfsFCBIsDirectory(Fcb) &&
+ FsRtlAreThereCurrentFileLocks(&Fcb->FileLock))
+ {
+ FsRtlFastUnlockAll(&Fcb->FileLock,
+ FileObject,
+ IoGetRequestorProcess(IrpContext->Irp),
+ NULL);
+ }
+
/* Uninitialize file cache if initialized for this file object. */
if (FileObject->SectionObjectPointer && FileObject->SectionObjectPointer->SharedCacheMap)
{
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&DeviceExtension->DirResource, TRUE);
- Status = CdfsCleanupFile(DeviceExtension, FileObject);
+ Status = CdfsCleanupFile(IrpContext, FileObject);
ExReleaseResourceLite(&DeviceExtension->DirResource);
KeLeaveCriticalRegion();
return STATUS_PENDING;
}
+static
+NTSTATUS
+CdfsLockControl(
+ IN PCDFS_IRP_CONTEXT IrpContext)
+{
+ PFCB Fcb;
+ NTSTATUS Status;
+
+ DPRINT("CdfsLockControl(IrpContext %p)\n", IrpContext);
+
+ if (IrpContext->DeviceObject == CdfsGlobalData->DeviceObject)
+ {
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ Fcb = IrpContext->FileObject->FsContext;
+ if (CdfsFCBIsDirectory(Fcb))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
+ Status = FsRtlProcessFileLock(&Fcb->FileLock,
+ IrpContext->Irp,
+ NULL);
+ return Status;
+}
+
static
NTSTATUS
CdfsDispatch(PCDFS_IRP_CONTEXT IrpContext)
case IRP_MJ_FILE_SYSTEM_CONTROL:
Status = CdfsFileSystemControl(IrpContext);
break;
+
+ case IRP_MJ_LOCK_CONTROL:
+ Status = CdfsLockControl(IrpContext);
+ break;
}
ASSERT((!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
Fcb->RFCB.Resource = &Fcb->MainResource;
Fcb->RFCB.IsFastIoPossible = FastIoIsNotPossible;
InitializeListHead(&Fcb->ShortNameList);
+ FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
return(Fcb);
}
{
PLIST_ENTRY Entry;
+ FsRtlUninitializeFileLock(&Fcb->FileLock);
ExDeleteResourceLite(&Fcb->PagingIoResource);
ExDeleteResourceLite(&Fcb->MainResource);
/* FUNCTIONS ****************************************************************/
static NTSTATUS
-CdfsReadFile(PDEVICE_EXTENSION DeviceExt,
+CdfsReadFile(PCDFS_IRP_CONTEXT IrpContext,
PFILE_OBJECT FileObject,
PUCHAR Buffer,
ULONG Length,
*/
{
NTSTATUS Status = STATUS_SUCCESS;
+ PDEVICE_EXTENSION DeviceExt;
PFCB Fcb;
ULONG ToRead = Length;
if (Length == 0)
return(STATUS_SUCCESS);
+ DeviceExt = IrpContext->DeviceObject->DeviceExtension;
Fcb = (PFCB)FileObject->FsContext;
if (ReadOffset >= Fcb->Entry.DataLengthL)
if (ReadOffset + Length > Fcb->Entry.DataLengthL)
ToRead = Fcb->Entry.DataLengthL - ReadOffset;
+ if (!(IrpFlags & IRP_PAGING_IO) &&
+ FsRtlAreThereCurrentFileLocks(&Fcb->FileLock))
+ {
+ if (!FsRtlCheckLockForReadAccess(&Fcb->FileLock, IrpContext->Irp))
+ {
+ return STATUS_FILE_LOCK_CONFLICT;
+ }
+ }
+
DPRINT("Reading %u bytes at %u\n", Length, ReadOffset);
if (!(IrpFlags & (IRP_NOCACHE|IRP_PAGING_IO)))
PCDFS_IRP_CONTEXT IrpContext)
{
PIRP Irp;
- PDEVICE_OBJECT DeviceObject;
- PDEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PVOID Buffer = NULL;
ASSERT(IrpContext);
Irp = IrpContext->Irp;
- DeviceObject = IrpContext->DeviceObject;
Stack = IrpContext->Stack;
- DeviceExt = DeviceObject->DeviceExtension;
FileObject = Stack->FileObject;
ReadLength = Stack->Parameters.Read.Length;
ReadOffset = Stack->Parameters.Read.ByteOffset;
if (ReadLength) Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
- Status = CdfsReadFile(DeviceExt,
+ Status = CdfsReadFile(IrpContext,
FileObject,
Buffer,
ReadLength,