NTSTATUS STDCALL drv_pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; BOOL top_level; FsRtlEnterFileSystem(); top_level = is_top_level(Irp); Status = STATUS_NOT_IMPLEMENTED; switch (IrpSp->MinorFunction) { case IRP_MN_CANCEL_REMOVE_DEVICE: Status = pnp_cancel_remove_device(DeviceObject, Irp); break; case IRP_MN_QUERY_REMOVE_DEVICE: Status = pnp_query_remove_device(DeviceObject, Irp); break; case IRP_MN_REMOVE_DEVICE: Status = pnp_remove_device(DeviceObject, Irp); break; case IRP_MN_START_DEVICE: Status = pnp_start_device(DeviceObject, Irp); break; case IRP_MN_SURPRISE_REMOVAL: Status = pnp_surprise_removal(DeviceObject, Irp); break; default: TRACE("passing minor function 0x%x on\n", IrpSp->MinorFunction); IoSkipCurrentIrpStackLocation(Irp); Status = IoCallDriver(Vcb->devices[0].devobj, Irp); goto end; } // // Irp->IoStatus.Status = Status; // // Irp->IoStatus.Information = 0; // // IoSkipCurrentIrpStackLocation(Irp); // // Status = IoCallDriver(Vcb->devices[0].devobj, Irp); // // // IoCompleteRequest(Irp, IO_NO_INCREMENT); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); end: if (top_level) IoSetTopLevelIrp(NULL); FsRtlExitFileSystem(); return Status; }
NTSTATUS drv_pnp(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); device_extension* Vcb = DeviceObject->DeviceExtension; NTSTATUS Status; BOOL top_level; FsRtlEnterFileSystem(); top_level = is_top_level(Irp); if (Vcb && Vcb->type == VCB_TYPE_CONTROL) { Status = bus_pnp(DeviceObject->DeviceExtension, Irp); goto exit; } else if (Vcb && Vcb->type == VCB_TYPE_VOLUME) { volume_device_extension* vde = DeviceObject->DeviceExtension; IoSkipCurrentIrpStackLocation(Irp); Status = IoCallDriver(vde->pdo, Irp); goto exit; } else if (Vcb && Vcb->type == VCB_TYPE_PDO) { Status = pdo_pnp(DeviceObject, Irp); goto end; } else if (!Vcb || Vcb->type != VCB_TYPE_FS) { Status = STATUS_INVALID_PARAMETER; goto end; } Status = STATUS_NOT_IMPLEMENTED; switch (IrpSp->MinorFunction) { case IRP_MN_CANCEL_REMOVE_DEVICE: Status = pnp_cancel_remove_device(DeviceObject); break; case IRP_MN_QUERY_REMOVE_DEVICE: Status = pnp_query_remove_device(DeviceObject, Irp); break; case IRP_MN_REMOVE_DEVICE: Status = pnp_remove_device(DeviceObject); break; case IRP_MN_SURPRISE_REMOVAL: Status = pnp_surprise_removal(DeviceObject, Irp); break; default: TRACE("passing minor function 0x%x on\n", IrpSp->MinorFunction); IoSkipCurrentIrpStackLocation(Irp); Status = IoCallDriver(Vcb->Vpb->RealDevice, Irp); goto exit; } end: Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); exit: TRACE("returning %08x\n", Status); if (top_level) IoSetTopLevelIrp(NULL); FsRtlExitFileSystem(); return Status; }
NTSTATUS STDCALL drv_read(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); UINT8* data; PFILE_OBJECT FileObject = IrpSp->FileObject; fcb* fcb = FileObject->FsContext; UINT64 start; ULONG length, bytes_read; NTSTATUS Status; BOOL top_level; FsRtlEnterFileSystem(); top_level = is_top_level(Irp); TRACE("read\n"); Irp->IoStatus.Information = 0; if (IrpSp->MinorFunction & IRP_MN_COMPLETE) { CcMdlReadComplete(IrpSp->FileObject, Irp->MdlAddress); Irp->MdlAddress = NULL; Status = STATUS_SUCCESS; bytes_read = 0; goto exit; } start = IrpSp->Parameters.Read.ByteOffset.QuadPart; length = IrpSp->Parameters.Read.Length; bytes_read = 0; if (!fcb || !fcb->Vcb || !fcb->subvol) { Status = STATUS_INTERNAL_ERROR; // FIXME - invalid param error? goto exit; } TRACE("file = %S (fcb = %p)\n", file_desc(FileObject), fcb); TRACE("offset = %llx, length = %x\n", start, length); TRACE("paging_io = %s, no cache = %s\n", Irp->Flags & IRP_PAGING_IO ? "TRUE" : "FALSE", Irp->Flags & IRP_NOCACHE ? "TRUE" : "FALSE"); if (fcb->type == BTRFS_TYPE_DIRECTORY) { Status = STATUS_INVALID_DEVICE_REQUEST; goto exit; } if (!(Irp->Flags & IRP_PAGING_IO) && !FsRtlCheckLockForReadAccess(&fcb->lock, Irp)) { WARN("tried to read locked region\n"); Status = STATUS_FILE_LOCK_CONFLICT; goto exit; } if (length == 0) { WARN("tried to read zero bytes\n"); Status = STATUS_SUCCESS; goto exit; } if (start >= fcb->Header.FileSize.QuadPart) { TRACE("tried to read with offset after file end (%llx >= %llx)\n", start, fcb->Header.FileSize.QuadPart); Status = STATUS_END_OF_FILE; goto exit; } TRACE("FileObject %p fcb %p FileSize = %llx st_size = %llx (%p)\n", FileObject, fcb, fcb->Header.FileSize.QuadPart, fcb->inode_item.st_size, &fcb->inode_item.st_size); // int3; if (Irp->Flags & IRP_NOCACHE || !(IrpSp->MinorFunction & IRP_MN_MDL)) { data = map_user_buffer(Irp); if (Irp->MdlAddress && !data) { ERR("MmGetSystemAddressForMdlSafe returned NULL\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } if (length + start > fcb->Header.ValidDataLength.QuadPart) { RtlZeroMemory(data + (fcb->Header.ValidDataLength.QuadPart - start), length - (fcb->Header.ValidDataLength.QuadPart - start)); length = fcb->Header.ValidDataLength.QuadPart - start; } } if (!(Irp->Flags & IRP_NOCACHE)) { BOOL wait; Status = STATUS_SUCCESS; _SEH2_TRY { if (!FileObject->PrivateCacheMap) { CC_FILE_SIZES ccfs; ccfs.AllocationSize = fcb->Header.AllocationSize; ccfs.FileSize = fcb->Header.FileSize; ccfs.ValidDataLength = fcb->Header.ValidDataLength; TRACE("calling CcInitializeCacheMap (%llx, %llx, %llx)\n", ccfs.AllocationSize.QuadPart, ccfs.FileSize.QuadPart, ccfs.ValidDataLength.QuadPart); CcInitializeCacheMap(FileObject, &ccfs, FALSE, cache_callbacks, FileObject); CcSetReadAheadGranularity(FileObject, READ_AHEAD_GRANULARITY); } // FIXME - uncomment this when async is working // wait = IoIsOperationSynchronous(Irp) ? TRUE : FALSE; wait = TRUE; if (IrpSp->MinorFunction & IRP_MN_MDL) { CcMdlRead(FileObject,&IrpSp->Parameters.Read.ByteOffset, length, &Irp->MdlAddress, &Irp->IoStatus); } else { TRACE("CcCopyRead(%p, %llx, %x, %u, %p, %p)\n", FileObject, IrpSp->Parameters.Read.ByteOffset.QuadPart, length, wait, data, &Irp->IoStatus); TRACE("sizes = %llx, %llx, %llx\n", fcb->Header.AllocationSize, fcb->Header.FileSize, fcb->Header.ValidDataLength); if (!CcCopyRead(FileObject, &IrpSp->Parameters.Read.ByteOffset, length, wait, data, &Irp->IoStatus)) { TRACE("CcCopyRead failed\n"); IoMarkIrpPending(Irp); Status = STATUS_PENDING; goto exit; } TRACE("CcCopyRead finished\n"); } } _SEH2_EXCEPT (EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (NT_SUCCESS(Status)) { Status = Irp->IoStatus.Status; bytes_read = Irp->IoStatus.Information; } else ERR("EXCEPTION - %08x\n", Status); } else {