📄 blockio.c
字号:
}
if (AbnormalTermination()) {
if (bBugCheck) {
RfsdBugCheck(RFSD_BUGCHK_BLOCK, 0, 0, 0);
}
for (i = 0; i < Count; i++) {
if (RfsdBDL[i].Irp != NULL ) {
if ( RfsdBDL[i].Irp->MdlAddress != NULL ) {
IoFreeMdl( RfsdBDL[i].Irp->MdlAddress );
}
IoFreeIrp( RfsdBDL[i].Irp );
}
}
}
}
return Status;
}
NTSTATUS
RfsdReadSync(
IN PRFSD_VCB Vcb,
IN ULONGLONG Offset,
IN ULONG Length,
OUT PVOID Buffer,
BOOLEAN bVerify
)
{
PKEVENT Event = NULL;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
ASSERT(Vcb != NULL);
ASSERT(Vcb->TargetDeviceObject != NULL);
ASSERT(Buffer != NULL);
__try {
Event = ExAllocatePool(NonPagedPool, sizeof(KEVENT));
if (NULL == Event) {
__leave;
}
KeInitializeEvent(Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(
IRP_MJ_READ,
Vcb->TargetDeviceObject,
Buffer,
Length,
(PLARGE_INTEGER)(&Offset),
Event,
&IoStatus
);
if (!Irp) {
Status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
if (bVerify) {
SetFlag( IoGetNextIrpStackLocation(Irp)->Flags,
SL_OVERRIDE_VERIFY_VOLUME );
}
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(
Event,
Suspended,
KernelMode,
FALSE,
NULL
);
Status = IoStatus.Status;
}
} __finally {
if (Event) {
ExFreePool(Event);
}
}
return Status;
}
NTSTATUS
RfsdReadDisk(
IN PRFSD_VCB Vcb,
IN ULONGLONG Offset, // Byte offset (relative to disk) to read from (need not be sector-aligned!)
IN ULONG Size,
IN OUT PVOID Buffer,
IN BOOLEAN bVerify ) // True if the volume should be verified before reading
{
NTSTATUS Status;
PUCHAR Buf;
ULONG Length;
ULONGLONG Lba;
// Align the offset and length to the sector boundaries
Lba = Offset & (~((ULONGLONG)SECTOR_SIZE - 1));
Length = (ULONG)(Size + Offset + SECTOR_SIZE - 1 - Lba) &
(~((ULONG)SECTOR_SIZE - 1));
// Allocate a temporary buffer to read the sector-aligned data into
Buf = ExAllocatePool(PagedPool, Length);
if (!Buf) {
RfsdPrint((DBG_ERROR, "RfsdReadDisk: no enough memory.\n"));
Status = STATUS_INSUFFICIENT_RESOURCES;
goto errorout;
}
// Read the data
Status = RfsdReadSync( Vcb,
Lba,
Length,
Buf,
FALSE );
if (!NT_SUCCESS(Status)) {
RfsdPrint((DBG_ERROR, "RfsdReadDisk: Read Block Device error.\n"));
goto errorout;
}
// Copy the requested data into the user's buffer
RtlCopyMemory(Buffer, &Buf[Offset - Lba], Size);
errorout:
if (Buf)
ExFreePool(Buf);
return Status;
}
NTSTATUS
RfsdDiskIoControl (
IN PDEVICE_OBJECT DeviceObject,
IN ULONG IoctlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT PULONG OutputBufferSize)
{
ULONG OutBufferSize = 0;
KEVENT Event;
PIRP Irp;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
ASSERT(DeviceObject != NULL);
if (OutputBufferSize)
{
OutBufferSize = *OutputBufferSize;
}
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildDeviceIoControlRequest(
IoctlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
OutBufferSize,
FALSE,
&Event,
&IoStatus
);
if (Irp == NULL) {
RfsdPrint((DBG_ERROR, "RfsdDiskIoControl: Building IRQ error!\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}
if (OutputBufferSize) {
*OutputBufferSize = (ULONG) IoStatus.Information;
}
return Status;
}
NTSTATUS
RfsdMediaEjectControlCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Contxt
)
{
PKEVENT Event = (PKEVENT)Contxt;
KeSetEvent( Event, 0, FALSE );
UNREFERENCED_PARAMETER( DeviceObject );
return STATUS_SUCCESS;
}
VOID
RfsdMediaEjectControl (
IN PRFSD_IRP_CONTEXT IrpContext,
IN PRFSD_VCB Vcb,
IN BOOLEAN bPrevent
)
{
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
PREVENT_MEDIA_REMOVAL Prevent;
IO_STATUS_BLOCK IoStatus;
ExAcquireResourceExclusiveLite(
&Vcb->MainResource,
TRUE );
if (bPrevent != IsFlagOn(Vcb->Flags, VCB_REMOVAL_PREVENTED)) {
if (bPrevent) {
SetFlag(Vcb->Flags, VCB_REMOVAL_PREVENTED);
} else {
ClearFlag(Vcb->Flags, VCB_REMOVAL_PREVENTED);
}
}
ExReleaseResourceForThreadLite(
&Vcb->MainResource,
ExGetCurrentResourceThread());
Prevent.PreventMediaRemoval = bPrevent;
KeInitializeEvent( &Event, NotificationEvent, FALSE );
Irp = IoBuildDeviceIoControlRequest( IOCTL_DISK_MEDIA_REMOVAL,
Vcb->TargetDeviceObject,
&Prevent,
sizeof(PREVENT_MEDIA_REMOVAL),
NULL,
0,
FALSE,
NULL,
&IoStatus );
if (Irp != NULL) {
IoSetCompletionRoutine( Irp,
RfsdMediaEjectControlCompletion,
&Event,
TRUE,
TRUE,
TRUE );
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
if (Status == STATUS_PENDING) {
Status = KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
NULL );
}
}
}
NTSTATUS
RfsdDiskShutDown(PRFSD_VCB Vcb)
{
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
Vcb->TargetDeviceObject,
NULL,
0,
NULL,
&Event,
&IoStatus);
if (Irp) {
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
Status = IoStatus.Status;
}
} else {
Status = IoStatus.Status;
}
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -