fsctl.c
来自「一个类似windows」· C语言 代码 · 共 565 行 · 第 1/2 页
C
565 行
case 255:
DPRINT("VolumeDescriptorSetTerminator found!\n");
break;
default:
DPRINT1("Unknown volume descriptor type %u found!\n", VdHeader->VdType);
break;
}
}
ExFreePool(Buffer);
return(STATUS_SUCCESS);
}
static NTSTATUS
CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt = NULL;
PDEVICE_OBJECT NewDeviceObject = NULL;
PDEVICE_OBJECT DeviceToMount;
PIO_STACK_LOCATION Stack;
PFCB Fcb = NULL;
PCCB Ccb = NULL;
PVPB Vpb;
NTSTATUS Status;
CDINFO CdInfo;
DPRINT("CdfsMountVolume() called\n");
if (DeviceObject != CdfsGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
Vpb = Stack->Parameters.MountVolume.Vpb;
Status = CdfsGetVolumeData(DeviceToMount, &CdInfo);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
Status = IoCreateDevice(CdfsGlobalData->DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_FILE_SYSTEM,
// FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&NewDeviceObject);
if (!NT_SUCCESS(Status))
goto ByeBye;
NewDeviceObject->Flags = NewDeviceObject->Flags | DO_DIRECT_IO;
NewDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
DeviceExt = (PVOID)NewDeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt,
sizeof(DEVICE_EXTENSION));
Vpb->SerialNumber = CdInfo.SerialNumber;
Vpb->VolumeLabelLength = CdInfo.VolumeLabelLength;
RtlCopyMemory(Vpb->VolumeLabel, CdInfo.VolumeLabel, CdInfo.VolumeLabelLength * sizeof(WCHAR));
RtlCopyMemory(&DeviceExt->CdInfo, &CdInfo, sizeof(CDINFO));
NewDeviceObject->Vpb = DeviceToMount->Vpb;
DeviceExt->VolumeDevice = NewDeviceObject;
DeviceExt->StorageDevice = DeviceToMount;
DeviceExt->StorageDevice->Vpb->DeviceObject = NewDeviceObject;
DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
DeviceExt->StorageDevice);
Fcb = CdfsCreateFCB(NULL);
if (Fcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
Ccb = ExAllocatePoolWithTag(NonPagedPool,
sizeof(CCB),
TAG_CCB);
if (Ccb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
RtlZeroMemory(Ccb,
sizeof(CCB));
DeviceExt->StreamFileObject->FsContext = Fcb;
DeviceExt->StreamFileObject->FsContext2 = Ccb;
DeviceExt->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
DeviceExt->StreamFileObject->PrivateCacheMap = NULL;
DeviceExt->StreamFileObject->Vpb = DeviceExt->Vpb;
Ccb->PtrFileObject = DeviceExt->StreamFileObject;
Fcb->FileObject = DeviceExt->StreamFileObject;
Fcb->DevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
Fcb->Flags = FCB_IS_VOLUME_STREAM;
Fcb->RFCB.FileSize.QuadPart = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
Fcb->RFCB.ValidDataLength = Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
Fcb->Entry.ExtentLocationL = 0;
Fcb->Entry.DataLengthL = (DeviceExt->CdInfo.VolumeSpaceSize + DeviceExt->CdInfo.VolumeOffset) * BLOCKSIZE;
#ifdef USE_ROS_CC_AND_FS
Status = CcRosInitializeFileCache(DeviceExt->StreamFileObject,
PAGE_SIZE);
if (!NT_SUCCESS (Status))
{
DbgPrint("CcRosInitializeFileCache failed\n");
goto ByeBye;
}
#else
CcInitializeCacheMap(DeviceExt->StreamFileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
TRUE,
NULL,
NULL);
#endif
ExInitializeResourceLite(&DeviceExt->VcbResource);
ExInitializeResourceLite(&DeviceExt->DirResource);
KeInitializeSpinLock(&DeviceExt->FcbListLock);
InitializeListHead(&DeviceExt->FcbListHead);
Status = STATUS_SUCCESS;
ByeBye:
if (!NT_SUCCESS(Status))
{
/* Cleanup */
if (DeviceExt && DeviceExt->StreamFileObject)
ObDereferenceObject(DeviceExt->StreamFileObject);
if (Fcb)
ExFreePool(Fcb);
if (Ccb)
ExFreePool(Ccb);
if (NewDeviceObject)
IoDeleteDevice(NewDeviceObject);
}
DPRINT("CdfsMountVolume() done (Status: %lx)\n", Status);
return(Status);
}
static NTSTATUS
CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt;
PDEVICE_OBJECT DeviceToVerify;
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
CDINFO CdInfo;
PLIST_ENTRY Entry;
PFCB Fcb;
DPRINT1 ("CdfsVerifyVolume() called\n");
#if 0
if (DeviceObject != CdfsGlobalData->DeviceObject)
{
DPRINT1("DeviceObject != CdfsGlobalData->DeviceObject\n");
return(STATUS_INVALID_DEVICE_REQUEST);
}
#endif
DeviceExt = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation (Irp);
DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject;
ExAcquireResourceExclusiveLite (&DeviceExt->VcbResource,
TRUE);
if (!(DeviceToVerify->Flags & DO_VERIFY_VOLUME))
{
DPRINT1 ("Volume has been verified!\n");
ExReleaseResourceLite (&DeviceExt->VcbResource);
return STATUS_SUCCESS;
}
DPRINT1 ("Device object %p Device to verify %p\n", DeviceObject, DeviceToVerify);
Status = CdfsGetVolumeData (DeviceToVerify,
&CdInfo);
if (NT_SUCCESS(Status) &&
CdInfo.SerialNumber == DeviceToVerify->Vpb->SerialNumber &&
CdInfo.VolumeLabelLength == DeviceToVerify->Vpb->VolumeLabelLength &&
!wcsncmp (CdInfo.VolumeLabel, DeviceToVerify->Vpb->VolumeLabel, CdInfo.VolumeLabelLength))
{
DPRINT1 ("Same volume!\n");
/* FIXME: Flush and purge metadata */
Status = STATUS_SUCCESS;
}
else
{
DPRINT1 ("Different volume!\n");
/* FIXME: force volume dismount */
Entry = DeviceExt->FcbListHead.Flink;
while (Entry != &DeviceExt->FcbListHead)
{
Fcb = (PFCB)CONTAINING_RECORD(Entry, FCB, FcbListEntry);
DPRINT1("OpenFile %S RefCount %ld\n", Fcb->PathName, Fcb->RefCount);
Entry = Entry->Flink;
}
Status = STATUS_WRONG_VOLUME;
}
DeviceToVerify->Flags &= ~DO_VERIFY_VOLUME;
ExReleaseResourceLite (&DeviceExt->VcbResource);
return Status;
}
NTSTATUS STDCALL
CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
DPRINT("CdfsFileSystemControl() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
DPRINT1("CDFS: IRP_MN_USER_FS_REQUEST\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
case IRP_MN_MOUNT_VOLUME:
DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
Status = CdfsMountVolume(DeviceObject, Irp);
break;
case IRP_MN_VERIFY_VOLUME:
DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n");
Status = CdfsVerifyVolume(DeviceObject, Irp);
break;
default:
DPRINT1("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?