[FASTFAT]

On the road for getting rid of IopParseDevice() hack....

- Add support for FSCTL_LOCK_VOLUME, FSCTL_UNLOCK_VOLUME, FSCTL_DISMOUNT_VOLUME in VfatFileSystemControl()
- Implement VfatLockOrUnlockVolume(). This brings some kind of volume locking to FastFAT FSD. It's likely not fully accurate and welcome to race conditions. But, its main purpose is to be used in usetup. So, this is fine for now.
- Stubplement VfatDismountVolume(). This will be implemented later on, but should be relatively straightforward as it requires volume to be locked (so, we're the last ones on it :-)).

svn path=/trunk/; revision=65129
This commit is contained in:
Pierre Schweitzer 2014-10-30 20:56:40 +00:00
parent 00bc798da9
commit ab38eafc21
4 changed files with 97 additions and 0 deletions

View file

@ -24,6 +24,7 @@ VfatCleanupFile(
PVFAT_IRP_CONTEXT IrpContext)
{
PVFATFCB pFcb;
PDEVICE_EXTENSION DeviceExt = IrpContext->DeviceExt;
PFILE_OBJECT FileObject = IrpContext->FileObject;
DPRINT("VfatCleanupFile(DeviceExt %p, FileObject %p)\n",
@ -37,6 +38,7 @@ VfatCleanupFile(
if (pFcb->Flags & FCB_IS_VOLUME)
{
pFcb->OpenHandleCount--;
DeviceExt->OpenHandleCount--;
if (pFcb->OpenHandleCount != 0)
{
@ -63,6 +65,7 @@ VfatCleanupFile(
FileObject->FsContext2);
pFcb->OpenHandleCount--;
DeviceExt->OpenHandleCount--;
if (!(*pFcb->Attributes & FILE_ATTRIBUTE_DIRECTORY) &&
FsRtlAreThereCurrentFileLocks(&pFcb->FileLock))

View file

@ -473,10 +473,18 @@ VfatCreateFile(
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)
{
@ -497,6 +505,7 @@ VfatCreateFile(
pFcb = DeviceExt->VolumeFcb;
vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject);
DeviceExt->OpenHandleCount++;
Irp->IoStatus.Information = FILE_OPENED;
return STATUS_SUCCESS;
@ -639,6 +648,7 @@ VfatCreateFile(
}
pFcb->OpenHandleCount++;
DeviceExt->OpenHandleCount++;
}
else if (ParentFcb != NULL)
{
@ -884,6 +894,7 @@ VfatCreateFile(
}
pFcb->OpenHandleCount++;
DeviceExt->OpenHandleCount++;
/* FIXME : test write access if requested */

View file

@ -612,6 +612,8 @@ VfatMount(
FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
InitializeListHead(&DeviceExt->NotifyList);
DPRINT1("Mount success\n");
Status = STATUS_SUCCESS;
ByeBye:
@ -855,6 +857,72 @@ VfatMarkVolumeDirty(
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
*/
@ -898,6 +966,18 @@ VfatFileSystemControl(
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;
}

View file

@ -296,6 +296,9 @@ typedef struct DEVICE_EXTENSION
/* Notifications */
LIST_ENTRY NotifyList;
PNOTIFY_SYNC NotifySync;
/* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
ULONG OpenHandleCount;
} DEVICE_EXTENSION, VCB, *PVCB;
typedef struct