PVFAT_IRP_CONTEXT IrpContext)
{
PVFATFCB pFcb;
+ PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt;
PFILE_OBJECT FileObject = IrpContext->FileObject;
DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
if (pFcb->Flags & FCB_IS_VOLUME)
{
pFcb->OpenHandleCount--;
+ DeviceExt->OpenHandleCount--;
if (pFcb->OpenHandleCount != 0)
{
FileObject->FsContext2);
pFcb->OpenHandleCount--;
+ DeviceExt->OpenHandleCount--;
if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))
return STATUS_INVALID_PARAMETER;
}
+ /* Deny create if the volume is locked */
+ if (DeviceExt->Flags & VCB_VOLUME_LOCKED)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
/* This a open operation for the volume itself */
if (FileObject->FileName.Length == 0 &&
(FileObject->RelatedFileObject == NULL || FileObject->RelatedFileObject->FsContext2 != NULL))
{
+ DPRINT1("Volume opening\n");
+
if (RequestedDisposition != FILE_OPEN &&
RequestedDisposition != FILE_OPEN_IF)
{
pFcb = DeviceExt->VolumeFcb;
vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
+ DeviceExt->OpenHandleCount++;
Irp->IoStatus.Information = FILE_OPENED;
return STATUS_SUCCESS;
}
pFcb->OpenHandleCount++;
+ DeviceExt->OpenHandleCount++;
}
else if (ParentFcb != NULL)
{
}
pFcb->OpenHandleCount++;
+ DeviceExt->OpenHandleCount++;
/* FIXME : test write access if requested */
FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
InitializeListHead(&DeviceExt->NotifyList);
+ DPRINT1("Mount success\n");
+
Status = STATUS_SUCCESS;
ByeBye:
return Status;
}
+static
+NTSTATUS
+VfatLockOrUnlockVolume(
+ PVFAT_IRP_CONTEXT IrpContext,
+ BOOLEAN Lock)
+{
+ PFILE_OBJECT FileObject;
+ PDEVICE_EXTENSION DeviceExt;
+
+ DPRINT1("VfatLockOrUnlockVolume(%p, %d)\n", IrpContext, Lock);
+
+ DeviceExt = IrpContext->DeviceExt;
+ FileObject = IrpContext->FileObject;
+
+ /* Only allow locking with the volume open */
+ if (FileObject->FsContext != DeviceExt->VolumeFcb)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Bail out if it's already in the demanded state */
+ if (((DeviceExt->Flags & VCB_VOLUME_LOCKED) && Lock) ||
+ (!(DeviceExt->Flags & VCB_VOLUME_LOCKED) && !Lock))
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Deny locking if we're not alone */
+ if (Lock && DeviceExt->OpenHandleCount != 1)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Finally, proceed */
+ if (Lock)
+ {
+ DeviceExt->Flags |= VCB_VOLUME_LOCKED;
+ }
+ else
+ {
+ DeviceExt->Flags &= ~VCB_VOLUME_LOCKED;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+VfatDismountVolume(
+ PVFAT_IRP_CONTEXT IrpContext)
+{
+ PDEVICE_EXTENSION DeviceExt;
+
+ DPRINT1("VfatDismountVolume(%p)\n", IrpContext);
+
+ DeviceExt = IrpContext->DeviceExt;
+
+ if (!(DeviceExt->Flags & VCB_VOLUME_LOCKED))
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/*
* FUNCTION: File system control
*/
Status = VfatMarkVolumeDirty(IrpContext);
break;
+ case FSCTL_LOCK_VOLUME:
+ Status = VfatLockOrUnlockVolume(IrpContext, TRUE);
+ break;
+
+ case FSCTL_UNLOCK_VOLUME:
+ Status = VfatLockOrUnlockVolume(IrpContext, FALSE);
+ break;
+
+ case FSCTL_DISMOUNT_VOLUME:
+ Status = VfatDismountVolume(IrpContext);
+ break;
+
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
}