* COPYRIGHT: GNU GENERAL PUBLIC LICENSE VERSION 2
* PROJECT: ReiserFs file system driver for Windows NT/2000/XP/Vista.
* FILE: fsctl.c
- * PURPOSE:
+ * PURPOSE:
* PROGRAMMER: Mark Piper, Matt Wu, Bo Brantén.
- * HOMEPAGE:
- * UPDATE HISTORY:
+ * HOMEPAGE:
+ * UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
IN USHORT Flag )
{
KIRQL OldIrql;
-
+
IoAcquireVpbSpinLock(&OldIrql);
-
+
Vpb->Flags |= Flag;
-
+
IoReleaseVpbSpinLock(OldIrql);
}
IN USHORT Flag )
{
KIRQL OldIrql;
-
+
IoAcquireVpbSpinLock(&OldIrql);
-
+
Vpb->Flags &= ~Flag;
-
+
IoReleaseVpbSpinLock(OldIrql);
}
if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
RfsdPrint((DBG_INFO, "RfsdLockVolume: Volume is already locked.\n"));
-
+
Status = STATUS_ACCESS_DENIED;
-
+
_SEH2_LEAVE;
}
-
+
if (Vcb->OpenFileHandleCount > (ULONG)(FileObject ? 1 : 0)) {
RfsdPrint((DBG_INFO, "RfsdLockVcb: There are still opened files.\n"));
-
+
Status = STATUS_ACCESS_DENIED;
-
+
_SEH2_LEAVE;
}
-
+
if (!RfsdIsHandleCountZero(Vcb)) {
RfsdPrint((DBG_INFO, "RfsdLockVcb: Thare are still opened files.\n"));
-
+
Status = STATUS_ACCESS_DENIED;
-
+
_SEH2_LEAVE;
}
-
+
SetFlag(Vcb->Flags, VCB_VOLUME_LOCKED);
-
+
RfsdSetVpbFlag(Vcb->Vpb, VPB_LOCKED);
Vcb->LockFile = FileObject;
-
+
RfsdPrint((DBG_INFO, "RfsdLockVcb: Volume locked.\n"));
-
+
Status = STATUS_SUCCESS;
} _SEH2_FINALLY {
// Nothing
} _SEH2_END;
-
+
return Status;
}
_SEH2_TRY {
ASSERT(IrpContext != NULL);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
DeviceObject = IrpContext->DeviceObject;
-
+
Status = STATUS_UNSUCCESSFUL;
//
Status = STATUS_INVALID_PARAMETER;
_SEH2_LEAVE;
}
-
+
Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
-
+
ASSERT(Vcb != NULL);
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
-
+
VcbResourceAcquired = TRUE;
- Status = RfsdLockVcb(Vcb, IrpSp->FileObject);
+ Status = RfsdLockVcb(Vcb, IrpSp->FileObject);
} _SEH2_FINALLY {
ExGetCurrentResourceThread()
);
}
-
+
if (!IrpContext->ExceptionInProgress) {
RfsdCompleteIrpContext(IrpContext, Status);
}
} _SEH2_END;
-
+
return Status;
}
Status = STATUS_NOT_LOCKED;
_SEH2_LEAVE;
}
-
+
if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
RfsdPrint((DBG_ERROR, ": RfsdUnlockVcb: Volume is not locked.\n"));
Status = STATUS_NOT_LOCKED;
if (Vcb->LockFile == FileObject) {
ClearFlag(Vcb->Flags, VCB_VOLUME_LOCKED);
-
+
RfsdClearVpbFlag(Vcb->Vpb, VPB_LOCKED);
-
+
RfsdPrint((DBG_INFO, "RfsdUnlockVcb: Volume unlocked.\n"));
-
+
Status = STATUS_SUCCESS;
} else {
Status = STATUS_NOT_LOCKED;
_SEH2_TRY {
ASSERT(IrpContext != NULL);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
DeviceObject = IrpContext->DeviceObject;
-
+
//
// This request is not allowed on the main device object
//
Status = STATUS_INVALID_PARAMETER;
_SEH2_LEAVE;
}
-
+
Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
-
+
ASSERT(Vcb != NULL);
-
+
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
-
+
VcbResourceAcquired = TRUE;
Status = RfsdUnlockVcb(Vcb, IrpSp->FileObject);
ExGetCurrentResourceThread()
);
}
-
+
if (!IrpContext->ExceptionInProgress) {
RfsdCompleteIrpContext(IrpContext, Status);
}
} _SEH2_END;
-
+
return Status;
}
RfsdPurgeVolume(Vcb, FALSE);
ClearFlag(Vcb->Flags, VCB_MOUNTED);
ExReleaseResourceLite(&Vcb->MainResource);
-
+
//
// Vcb is still attached on the list ......
//
Ccb = (PRFSD_CCB) IrpSp->FileObject->FsContext2;
ASSERT(Vcb != NULL);
-
+
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
PAGED_CODE();
ASSERT(IrpContext);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
Irp = IrpContext->Irp;
-
+
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-
+
#ifndef _GNU_NTIFS_
FsControlCode =
IoStackLocation->Parameters.FileSystemControl.FsControlCode;
FsControlCode = ((PEXTENDED_IO_STACK_LOCATION)
IoStackLocation)->Parameters.FileSystemControl.FsControlCode;
#endif
-
+
switch (FsControlCode) {
case FSCTL_LOCK_VOLUME:
Status = RfsdLockVolume(IrpContext);
break;
-
+
case FSCTL_UNLOCK_VOLUME:
Status = RfsdUnlockVolume(IrpContext);
break;
-
+
case FSCTL_DISMOUNT_VOLUME:
Status = RfsdDismountVolume(IrpContext);
break;
-
+
case FSCTL_IS_VOLUME_MOUNTED:
Status = RfsdIsVolumeMounted(IrpContext);
break;
Status = RfsdAllowExtendedDasdIo(IrpContext);
break;
#endif //(_WIN32_WINNT >= 0x0500)
-
+
default:
RfsdPrint((DBG_ERROR, "RfsdUserFsRequest: Invalid User Request: %xh.\n", FsControlCode));
RfsdCompleteIrpContext(IrpContext, Status);
}
-
+
return Status;
}
ASSERT(IrpContext != NULL);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
MainDeviceObject = IrpContext->DeviceObject;
//
Status = STATUS_INVALID_DEVICE_REQUEST;
_SEH2_LEAVE;
}
-
+
ExAcquireResourceExclusiveLite(
&(RfsdGlobal->Resource),
TRUE );
-
+
GlobalDataResourceAcquired = TRUE;
-
+
if (FlagOn(RfsdGlobal->Flags, RFSD_UNLOAD_PENDING)) {
Status = STATUS_UNRECOGNIZED_VOLUME;
_SEH2_LEAVE;
}
-
+
Irp = IrpContext->Irp;
-
+
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-
+
TargetDeviceObject =
IoStackLocation->Parameters.MountVolume.DeviceObject;
0,
&DiskGeometry,
&dwBytes );
-
+
if (!NT_SUCCESS(Status)) {
_SEH2_LEAVE;
}
-
+
Status = IoCreateDevice(
MainDeviceObject->DriverObject,
sizeof(RFSD_VCB),
0,
FALSE,
&VolumeDeviceObject );
-
+
if (!NT_SUCCESS(Status)) {
_SEH2_LEAVE;
}
VolumeDeviceObject->StackSize = (CCHAR)(TargetDeviceObject->StackSize + 1);
- if (TargetDeviceObject->AlignmentRequirement >
+ if (TargetDeviceObject->AlignmentRequirement >
VolumeDeviceObject->AlignmentRequirement) {
- VolumeDeviceObject->AlignmentRequirement =
+ VolumeDeviceObject->AlignmentRequirement =
TargetDeviceObject->AlignmentRequirement;
}
(IoStackLocation->Parameters.MountVolume.Vpb)->DeviceObject =
VolumeDeviceObject;
-
+
Vcb = (PRFSD_VCB) VolumeDeviceObject->DeviceExtension;
RtlZeroMemory(Vcb, sizeof(RFSD_VCB));
-
+
Vcb->Identifier.Type = RFSDVCB;
Vcb->Identifier.Size = sizeof(RFSD_VCB);
if (!NT_SUCCESS(Status)) {
_SEH2_LEAVE;
}
-
+
Vcb->BlockSize = RfsdSb->s_blocksize; // NOTE: FFS also does this here, since LoadGroup is not called in the non-ext2 drivers
Vcb->GroupDesc = NULL; // NOTE: GroupDesc is not used for ReiserFS. Setting it to NULL will keep other code from barfing.
// Vcb->SectorBits = RFSDLog(SECTOR_SIZE); // NOTE: SectorBits are unused for ReiserFS
-
- Status = RfsdInitializeVcb(IrpContext, Vcb, RfsdSb, TargetDeviceObject,
+
+ Status = RfsdInitializeVcb(IrpContext, Vcb, RfsdSb, TargetDeviceObject,
VolumeDeviceObject, IoStackLocation->Parameters.MountVolume.Vpb);
if (NT_SUCCESS(Status)) {
IoDeleteDevice(VolumeDeviceObject);
}
}
-
+
if (!IrpContext->ExceptionInProgress) {
if (NT_SUCCESS(Status)) {
ClearFlag(VolumeDeviceObject->Flags, DO_DEVICE_INITIALIZING);
RfsdCompleteIrpContext(IrpContext, Status);
}
} _SEH2_END;
-
+
return Status;
}
_SEH2_TRY {
ASSERT(IrpContext != NULL);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
DeviceObject = IrpContext->DeviceObject;
//
// This request is not allowed on the main device object
ExAcquireResourceExclusiveLite(
&RfsdGlobal->Resource,
TRUE );
-
+
GlobalResourceAcquired = TRUE;
-
+
Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
-
+
ASSERT(Vcb != NULL);
-
+
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
-
+
VcbResourceAcquired = TRUE;
-
+
if (!FlagOn(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME)) {
Status = STATUS_SUCCESS;
_SEH2_LEAVE;
Status = STATUS_WRONG_VOLUME;
_SEH2_LEAVE;
}
-
+
Irp = IrpContext->Irp;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
-
+
rfsd_sb = RfsdLoadSuper(Vcb, TRUE);
// FUTURE: use the volume name and uuid from the extended superblock to make this happen.
} else {
ClearFlag(Vcb->Flags, VCB_WRITE_PROTECTED);
}
-
+
RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify succeeded.\n"));
Status = STATUS_SUCCESS;
Status = STATUS_WRONG_VOLUME;
RfsdPurgeVolume(Vcb, FALSE);
-
+
SetFlag(Vcb->Flags, VCB_DISMOUNT_PENDING);
-
+
ClearFlag(Vcb->TargetDeviceObject->Flags, DO_VERIFY_VOLUME);
-
+
RfsdPrint((DBG_INFO, "RfsdVerifyVolume: Volume verify failed.\n"));
}
&RfsdGlobal->Resource,
ExGetCurrentResourceThread() );
}
-
+
if (!IrpContext->ExceptionInProgress) {
RfsdCompleteIrpContext(IrpContext, Status);
}
} _SEH2_END;
-
+
return Status;
}
_SEH2_TRY {
ASSERT(IrpContext != NULL);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
DeviceObject = IrpContext->DeviceObject;
//
Status = STATUS_INVALID_DEVICE_REQUEST;
_SEH2_LEAVE;
}
-
+
Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;
-
+
ASSERT(Vcb != NULL);
-
+
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
-
+
VcbResourceAcquired = TRUE;
if ( IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
_SEH2_LEAVE;
}
-/*
+/*
if (!FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
RfsdPrint((DBG_ERROR, "RfsdDismount: Volume is not locked.\n"));
-
+
Status = STATUS_ACCESS_DENIED;
-
+
_SEH2_LEAVE;
}
*/
ExGetCurrentResourceThread()
);
}
-
+
if (!IrpContext->ExceptionInProgress) {
RfsdCompleteIrpContext(IrpContext, Status);
}
} _SEH2_END;
-
+
return Status;
}
_SEH2_TRY {
ASSERT(Vcb != NULL);
-
+
ASSERT((Vcb->Identifier.Type == RFSDVCB) &&
(Vcb->Identifier.Size == sizeof(RFSD_VCB)));
-
+
if ( IsFlagOn(Vcb->Flags, VCB_READ_ONLY) ||
IsFlagOn(Vcb->Flags, VCB_WRITE_PROTECTED)) {
FlushBeforePurge = FALSE;
FcbListEntry= NULL;
InitializeListHead(&FcbList);
-
+
for (ListEntry = Vcb->FcbList.Flink;
ListEntry != &Vcb->FcbList;
ListEntry = ListEntry->Flink ) {
Fcb->ReferenceCount++;
RfsdPrint((DBG_INFO, "RfsdPurgeVolume: %s refercount=%xh\n", Fcb->AnsiFileName.Buffer, Fcb->ReferenceCount));
-
+
FcbListEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FCB_LIST_ENTRY), RFSD_POOL_TAG);
if (FcbListEntry) {
FcbListEntry->Fcb = Fcb;
-
+
InsertTailList(&FcbList, &FcbListEntry->Next);
} else {
RfsdPrint((DBG_ERROR, "RfsdPurgeVolume: Error allocating FcbListEntry ...\n"));
}
}
-
+
while (!IsListEmpty(&FcbList)) {
ListEntry = RemoveHeadList(&FcbList);
-
+
FcbListEntry = CONTAINING_RECORD(ListEntry, FCB_LIST_ENTRY, Next);
-
+
Fcb = FcbListEntry->Fcb;
if (ExAcquireResourceExclusiveLite(
ExGetCurrentResourceThread());
}
}
-
+
ExFreePool(FcbListEntry);
}
if (Vcb->SectionObject.ImageSectionObject) {
MmFlushImageSection(&Vcb->SectionObject, MmFlushForWrite);
}
-
+
if (Vcb->SectionObject.DataSectionObject) {
CcPurgeCacheSection(&Vcb->SectionObject, NULL, 0, FALSE);
}
-
+
RfsdPrint((DBG_INFO, "RfsdPurgeVolume: Volume flushed and purged.\n"));
} _SEH2_FINALLY {
PAGED_CODE();
ASSERT(Fcb != NULL);
-
+
ASSERT((Fcb->Identifier.Type == RFSDFCB) &&
(Fcb->Identifier.Size == sizeof(RFSD_FCB)));
-
+
if( !IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY) && FlushBeforePurge &&
!IsFlagOn(Fcb->Vcb->Flags, VCB_WRITE_PROTECTED)) {
- RfsdPrint((DBG_INFO, "RfsdPurgeFile: CcFlushCache on %s.\n",
+ RfsdPrint((DBG_INFO, "RfsdPurgeFile: CcFlushCache on %s.\n",
Fcb->AnsiFileName.Buffer));
ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);
}
-
+
if (Fcb->SectionObject.ImageSectionObject) {
- RfsdPrint((DBG_INFO, "RfsdPurgeFile: MmFlushImageSection on %s.\n",
+ RfsdPrint((DBG_INFO, "RfsdPurgeFile: MmFlushImageSection on %s.\n",
Fcb->AnsiFileName.Buffer));
-
+
MmFlushImageSection(&Fcb->SectionObject, MmFlushForWrite);
}
-
+
if (Fcb->SectionObject.DataSectionObject) {
RfsdPrint((DBG_INFO, "RfsdPurgeFile: CcPurgeCacheSection on %s.\n",
PAGED_CODE();
ASSERT(IrpContext);
-
+
ASSERT((IrpContext->Identifier.Type == RFSDICX) &&
(IrpContext->Identifier.Size == sizeof(RFSD_IRP_CONTEXT)));
-
+
switch (IrpContext->MinorFunction) {
case IRP_MN_USER_FS_REQUEST:
Status = RfsdUserFsRequest(IrpContext);
break;
-
+
case IRP_MN_MOUNT_VOLUME:
Status = RfsdMountVolume(IrpContext);
break;
-
+
case IRP_MN_VERIFY_VOLUME:
Status = RfsdVerifyVolume(IrpContext);
break;
-
+
default:
RfsdPrint((DBG_ERROR, "RfsdFilsSystemControl: Invalid Device Request.\n"));
Status = STATUS_INVALID_DEVICE_REQUEST;
RfsdCompleteIrpContext(IrpContext, Status);
}
-
+
return Status;
}