STDCALL NTSTATUS IoSendIrpTopDev(struct device_object *dev_obj, ULONG major_fn, ULONG minor_fn, struct io_stack_location *sl) { NTSTATUS status; struct nt_event event; struct irp *irp; struct io_stack_location *irp_sl; struct device_object *top_dev = IoGetAttachedDeviceReference(dev_obj); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_dev, NULL, 0, NULL, &event, NULL); irp->io_status.status = STATUS_NOT_IMPLEMENTED; irp->io_status.info = 0; irp_sl = IoGetNextIrpStackLocation(irp); if (sl) memcpy(irp_sl, sl, sizeof(*irp_sl)); irp_sl->major_fn = major_fn; irp_sl->minor_fn = minor_fn; status = IoCallDriver(top_dev, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = irp->io_status.status; } ObDereferenceObject(top_dev); return status; }
static NTSTATUS VfatDiskShutDown(PVCB Vcb) { PIRP Irp; KEVENT Event; NTSTATUS Status; IO_STATUS_BLOCK IoStatus; KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice, NULL, 0, NULL, &Event, &IoStatus); if (Irp) { Status = IoCallDriver(Vcb->StorageDevice, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatus.Status; } } else { Status = IoStatus.Status; } return Status; }
BOOLEAN FsRecReadBlock(PDEVICE_OBJECT DeviceObject,PLARGE_INTEGER StartingOffset,ULONG LengthToRead,ULONG SectorSize,OUT PUCHAR* BlockData,OUT PBOOLEAN BlockReaded) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; KEVENT Event; PIRP Irp; ULONG SectorAlignLength = 0; PAGED_CODE(); if(BlockReaded) BlockReaded[0] = FALSE; KeInitializeEvent(&Event,SynchronizationEvent,FALSE); if ( LengthToRead > SectorSize ) SectorAlignLength = SectorSize * (LengthToRead + SectorSize - 1) / SectorSize; else SectorAlignLength = SectorSize; if(!BlockData) { BlockData[0] = ExAllocatePoolWithTag(PagedPool,(SectorAlignLength + PAGE_SIZE - 1) & 0xFFFFF000,POOL_TAG); } if(BlockData[0]) { Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, BlockData[0], SectorAlignLength, StartingOffset, &Event, &IoStatusBlock); if(Irp) { (IoGetNextIrpStackLocation(Irp))->Flags |= IRP_PAGING_IO; Status = IoCallDriver(DeviceObject,Irp); if(Status == STATUS_PENDING) { KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); Status = IoStatusBlock.Status; } if(!NT_SUCCESS(Status)) { if(BlockReaded) BlockReaded[0] = TRUE; return FALSE; } return TRUE; } } return FALSE; }
/* * @implemented */ VOID NTAPI IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead) { PLIST_ENTRY ListEntry; PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK StatusBlock; PIRP Irp; KEVENT Event; NTSTATUS Status; KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Get the first entry and start looping */ ListEntry = ListHead->Flink; while (ListEntry != ListHead) { /* Get the device object */ DeviceObject = CONTAINING_RECORD(ListEntry, DEVICE_OBJECT, Queue.ListEntry); ObReferenceObject(DeviceObject); IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount); /* Check if we're attached */ if (DeviceObject->AttachedDevice) { /* Get the attached device */ DeviceObject = IoGetAttachedDevice(DeviceObject); } /* Build the shutdown IRP and call the driver */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, DeviceObject, NULL, 0, NULL, &Event, &StatusBlock); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { /* Wait on the driver */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } /* Reset the event */ KeClearEvent(&Event); IopDecrementDeviceObjectRef(DeviceObject, FALSE); ObDereferenceObject(DeviceObject); /* Go to the next entry */ ListEntry = ListEntry->Flink; } }
static NTSTATUS EngpFileIoRequest( PFILE_OBJECT pFileObject, ULONG ulMajorFunction, LPVOID lpBuffer, SIZE_T nBufferSize, ULONGLONG ullStartOffset, OUT PULONG_PTR lpInformation) { PDEVICE_OBJECT pDeviceObject; KEVENT Event; PIRP pIrp; IO_STATUS_BLOCK Iosb; NTSTATUS Status; LARGE_INTEGER liStartOffset; /* Get corresponding device object */ pDeviceObject = IoGetRelatedDeviceObject(pFileObject); if (!pDeviceObject) { return STATUS_INVALID_PARAMETER; } /* Initialize an event */ KeInitializeEvent(&Event, SynchronizationEvent, FALSE); /* Build IRP */ liStartOffset.QuadPart = ullStartOffset; pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction, pDeviceObject, lpBuffer, (ULONG)nBufferSize, &liStartOffset, &Event, &Iosb); if (!pIrp) { return STATUS_INSUFFICIENT_RESOURCES; } /* Call the driver */ Status = IoCallDriver(pDeviceObject, pIrp); /* Wait if neccessary */ if (STATUS_PENDING == Status) { KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0); Status = Iosb.Status; } /* Return information to the caller about the operation. */ *lpInformation = Iosb.Information; /* Return NTSTATUS */ return Status; }
NTSTATUS XenGfxReadConfigSpace(PDEVICE_OBJECT pDeviceObject, PVOID pBuffer, ULONG Offset, ULONG Length) { KEVENT Event; NTSTATUS Status = STATUS_SUCCESS; PIRP pIrp; IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION pIsl; PDEVICE_OBJECT pTargetObject; PAGED_CODE(); do { KeInitializeEvent(&Event, NotificationEvent, FALSE); pTargetObject = IoGetAttachedDeviceReference(pDeviceObject); if (pTargetObject == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pTargetObject, NULL, 0, NULL, &Event, &IoStatusBlock); if (pIrp == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } pIsl = IoGetNextIrpStackLocation(pIrp); pIsl->MinorFunction = IRP_MN_READ_CONFIG; pIsl->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG; pIsl->Parameters.ReadWriteConfig.Buffer = pBuffer; pIsl->Parameters.ReadWriteConfig.Offset = Offset; pIsl->Parameters.ReadWriteConfig.Length = Length; // Initialize the status to error in case the bus driver does not // set it correctly. pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; Status = IoCallDriver(pTargetObject, pIrp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL ); Status = IoStatusBlock.Status; } } while (FALSE); if (pTargetObject != NULL) ObDereferenceObject(pTargetObject); return Status; }
NTSTATUS SyncReadWriteSec( IN PDEVICE_OBJECT DeviceObject, IN ULONG ulStartSec, IN ULONG ulSectors, IN PVOID pBuffer, IN UCHAR MajorFunction ) { KEVENT event; PIRP Irp; ULONG ulBytes; LARGE_INTEGER Start; IO_STATUS_BLOCK ioStatus; NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ulBytes = ulSectors * SECTOR_SIZE; Start.QuadPart = ((LONGLONG)ulStartSec)*SECTOR_SIZE; KeInitializeEvent( &event, NotificationEvent, FALSE ); Irp = IoBuildSynchronousFsdRequest( MajorFunction, deviceExtension->TargetDeviceObject, pBuffer,ulBytes, &Start,&event, &ioStatus ); ASSERT(Irp); if (!Irp) { return STATUS_INSUFFICIENT_RESOURCES; } //Irp->Flags |= IRP_PAGING_IO; status = IoCallDriver( deviceExtension->TargetDeviceObject, Irp ); if (status == STATUS_PENDING) { (VOID) KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, (PLARGE_INTEGER) NULL); status = ioStatus.Status; } return status; } // end SyncReadWriteSec()
NTSTATUS NTAPI GetBusInterface( PDEVICE_OBJECT DeviceObject, PBUS_INTERFACE_STANDARD busInterface) { KEVENT Event; NTSTATUS Status; PIRP Irp; IO_STATUS_BLOCK IoStatus; PIO_STACK_LOCATION Stack; if ((!DeviceObject) || (!busInterface)) return STATUS_UNSUCCESSFUL; KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, DeviceObject, NULL, 0, NULL, &Event, &IoStatus); if (Irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } Stack=IoGetNextIrpStackLocation(Irp); Stack->MajorFunction = IRP_MJ_PNP; Stack->MinorFunction = IRP_MN_QUERY_INTERFACE; Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD); Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD; Stack->Parameters.QueryInterface.Version = 1; Stack->Parameters.QueryInterface.Interface = (PINTERFACE)busInterface; Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL; Irp->IoStatus.Status=STATUS_NOT_SUPPORTED ; Status=IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status=IoStatus.Status; } return Status; }
static NTSTATUS HalpXboxReadSector(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN PLARGE_INTEGER SectorOffset, OUT PVOID Sector) { IO_STATUS_BLOCK StatusBlock; KEVENT Event; PIRP Irp; NTSTATUS Status; DPRINT("HalpXboxReadSector(%p %lu 0x%08x%08x %p)\n", DeviceObject, SectorSize, SectorOffset->u.HighPart, SectorOffset->u.LowPart, Sector); ASSERT(DeviceObject); ASSERT(Sector); KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Read the sector */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, Sector, SectorSize, SectorOffset, &Event, &StatusBlock); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = StatusBlock.Status; } if (!NT_SUCCESS(Status)) { DPRINT("Reading sector failed (Status 0x%08lx)\n", Status); return Status; } return Status; }
NTSTATUS WriteDiskSector(PDEVICE_OBJECT pDevice, __int64 Offset, ULONG *Size, PVOID InBuff) { PIRP Irp; PIO_STACK_LOCATION irpStack; KIRQL currentIrql; NTSTATUS ntStatus; IO_STATUS_BLOCK ioStatus; KEVENT event; USHORT kratnost = 512; Disk_GetSectorSize(pDevice, &kratnost); DbPrint(DC_LLDISKIO, DL_INFO,("WriteSector pDevice:%x Offset:%I64x Size:%x\n", pDevice, Offset, *Size)); if(*Size % kratnost) *Size=(*Size) - (*Size) % kratnost; if (0 == *Size) { DbgBreakPoint(); return STATUS_INVALID_PARAMETER; } KeInitializeEvent(&event, NotificationEvent, FALSE); if(!(Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, pDevice, InBuff, *Size, (LARGE_INTEGER*) &Offset, &event, &ioStatus))) { DbPrint(DC_LLDISKIO, DL_ERROR, ("BuildRequest for write disk failed\n")); return STATUS_INSUFFICIENT_RESOURCES; } irpStack = IoGetNextIrpStackLocation(Irp); irpStack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; ntStatus = IoCallDriver(pDevice, Irp); if(ntStatus == STATUS_PENDING) { KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL); ntStatus = ioStatus.Status; } *Size = ioStatus.Information; return ntStatus; }
NTSTATUS MakeReadWriteRequest(PDEVICE_OBJECT pDev, DWORD request, PCHAR pBuf, DWORD bufSize, PLARGE_INTEGER pOffset) { KEVENT event = {0}; PIRP pIrp = NULL; IO_STATUS_BLOCK ioStatus = {0}; NTSTATUS status = 0; KeInitializeEvent(&event, NotificationEvent, FALSE); DbgPrint("Building IRP which will be send to the HardDisk 0 device.."); pIrp = IoBuildSynchronousFsdRequest(request, pDev, pBuf, bufSize, pOffset, &event, &ioStatus ); if(pIrp == NULL) { DbgPrint("\n[!] Error at IoBuildSynchronousFsdRequest().\n"); return STATUS_UNSUCCESSFUL; } DbgPrint("[OK] -> 0x%x.\n", pIrp); DbgPrint("Calling the driver.."); status = IoCallDriver(pDev, pIrp); if(status == STATUS_PENDING) { DbgPrint("Waiting it handles our query.."); KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = ioStatus.Status; if(!NT_SUCCESS(status)) { DbgPrint("\n[!] Error at IoCallDriver+KeWaitForSingleObject : 0x%x.\n", status); return STATUS_UNSUCCESSFUL; } } return STATUS_SUCCESS; }
/***************************************************************************** * Direct R/W from config space. *****************************************************************************/ INT PCIReadConfigWord( IN PDEVICE_OBJECT DeviceObject, IN ULONG Offset, IN PVOID Value ) { PDEVICE_OBJECT TargetObject; PIRP pIrp; IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION IrpStack; KEVENT ConfigReadWordEvent; INT error = 0; TargetObject = IoGetAttachedDeviceReference(DeviceObject); KeInitializeEvent(&ConfigReadWordEvent, NotificationEvent, FALSE); pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, TargetObject, NULL, 0, NULL, &ConfigReadWordEvent, &IoStatusBlock ); if (pIrp) { /* Create the config space read IRP */ IrpStack = IoGetNextIrpStackLocation(pIrp); IrpStack->MinorFunction = IRP_MN_READ_CONFIG; IrpStack->Parameters.ReadWriteConfig.WhichSpace = \ PCI_WHICHSPACE_CONFIG; IrpStack->Parameters.ReadWriteConfig.Offset = Offset; IrpStack->Parameters.ReadWriteConfig.Length = 0x2; IrpStack->Parameters.ReadWriteConfig.Buffer = Value; pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED ; /* Send the IRP */ if (IoCallDriver(TargetObject, pIrp)==STATUS_PENDING) { KeWaitForSingleObject(&ConfigReadWordEvent, Executive, \ KernelMode, FALSE, NULL); } } else { error = -1; } ObDereferenceObject(TargetObject); return error; }
NTSTATUS PopSendQuerySystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE SystemState, POWER_ACTION PowerAction) { KEVENT Event; IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION IrpSp; PIRP Irp; NTSTATUS Status; KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER, DeviceObject, NULL, 0, NULL, &Event, &IoStatusBlock); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->MinorFunction = IRP_MN_QUERY_POWER; IrpSp->Parameters.Power.Type = SystemPowerState; IrpSp->Parameters.Power.State.SystemState = SystemState; IrpSp->Parameters.Power.ShutdownType = PowerAction; Status = PoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } return Status; }
NTSTATUS FlushBuf(IN PDEVICE_OBJECT DeviceObject) { KEVENT event; PIRP Irp; IO_STATUS_BLOCK ioStatus; NTSTATUS status = STATUS_SUCCESS; PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); KeInitializeEvent( &event, NotificationEvent, FALSE ); Irp = IoBuildSynchronousFsdRequest( IRP_MJ_FLUSH_BUFFERS, deviceExtension->TargetDeviceObject, NULL,0, NULL,&event, &ioStatus ); ASSERT(Irp); if (!Irp) { return STATUS_INSUFFICIENT_RESOURCES; } status = IoCallDriver( deviceExtension->TargetDeviceObject, Irp ); if (status == STATUS_PENDING) { (VOID) KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, (PLARGE_INTEGER) NULL); status = ioStatus.Status; } return status; } // end SyncReadWriteSec()
NTSTATUS QueryInterface(IN PDEVICE_OBJECT Pdo, IN CONST GUID InterfaceType, IN LONG Size, IN LONG Version, OUT PVOID Interface) { KEVENT Event; PIRP Irp; IO_STATUS_BLOCK IoStatus; NTSTATUS Status; PIO_STACK_LOCATION Stack = NULL; KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, Pdo, NULL, 0, NULL, &Event, &IoStatus); Stack = IoGetNextIrpStackLocation(Irp); Stack->MinorFunction = IRP_MN_QUERY_INTERFACE; Stack->Parameters.QueryInterface.InterfaceType= &InterfaceType;//USB_BUS_INTERFACE_HUB_GUID; Stack->Parameters.QueryInterface.Size = Size; Stack->Parameters.QueryInterface.Version = Version; Stack->Parameters.QueryInterface.Interface = Interface; Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL; Status = IoCallDriver(Pdo, Irp); if (Status == STATUS_PENDING) { DPRINT("Usbhub: Operation pending\n"); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); Status = IoStatus.Status; } return Status; }
static NTSTATUS ReadBytes( IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes) { PIRP Irp; IO_STATUS_BLOCK ioStatus; KEVENT event; LARGE_INTEGER zero; NTSTATUS Status; KeInitializeEvent(&event, NotificationEvent, FALSE); zero.QuadPart = 0; Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, LowerDevice, Buffer, BufferSize, &zero, &event, &ioStatus); if (!Irp) return FALSE; Status = IoCallDriver(LowerDevice, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL); Status = ioStatus.Status; } INFO_(SERENUM, "Bytes received: %lu/%lu\n", ioStatus.Information, BufferSize); *FilledBytes = ioStatus.Information; return Status; }
static NTSTATUS GetDeviceId( PDEVICE_OBJECT DeviceObject, BUS_QUERY_ID_TYPE IdType, PWSTR *DeviceId) { PIO_STACK_LOCATION IrpStack; IO_STATUS_BLOCK IoStatus; PDEVICE_OBJECT TargetObject; KEVENT Event; PIRP Irp; NTSTATUS Status; PAGED_CODE(); /* Initialize the event */ KeInitializeEvent(&Event, NotificationEvent, FALSE); TargetObject = IoGetAttachedDeviceReference(DeviceObject); /* Build the IRP */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, TargetObject, NULL, 0, NULL, &Event, &IoStatus); if (Irp == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; } /* PNP IRPs all begin life as STATUS_NOT_SUPPORTED */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; /* Get the top of stack */ IrpStack = IoGetNextIrpStackLocation(Irp); /* Set the top of stack */ RtlZeroMemory(IrpStack, sizeof(IO_STACK_LOCATION)); IrpStack->MajorFunction = IRP_MJ_PNP; IrpStack->MinorFunction = IRP_MN_QUERY_ID; IrpStack->Parameters.QueryId.IdType = IdType; /* Call the driver */ Status = IoCallDriver(TargetObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatus.Status; } if (NT_SUCCESS(Status)) { *DeviceId = (PWSTR)IoStatus.Information; } done: /* Dereference the target device object */ ObDereferenceObject(TargetObject); return Status; }
NTSTATUS NdasDluSendIoctlSrb( IN PDEVICE_OBJECT DeviceObject, IN ULONG IoctlCode, IN PVOID InputBuffer, IN LONG InputBufferLength, OUT PVOID OutputBuffer, IN LONG OutputBufferLength ) { PIRP irp; KEVENT event; PSRB_IO_CONTROL psrbIoctl; LONG srbIoctlLength; PVOID srbIoctlBuffer; LONG srbIoctlBufferLength; NTSTATUS status; PIO_STACK_LOCATION irpStack; SCSI_REQUEST_BLOCK srb; LARGE_INTEGER startingOffset; IO_STATUS_BLOCK ioStatusBlock; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); psrbIoctl = NULL; irp = NULL; // // build an SRB for the miniport // srbIoctlBufferLength = (InputBufferLength>OutputBufferLength)?InputBufferLength:OutputBufferLength; srbIoctlLength = sizeof(SRB_IO_CONTROL) + srbIoctlBufferLength; psrbIoctl = (PSRB_IO_CONTROL)ExAllocatePoolWithTag(NonPagedPool , srbIoctlLength, NDAS_DLU_PTAG_SRB_IOCTL); if(psrbIoctl == NULL) { KDPrint(1, ("STATUS_INSUFFICIENT_RESOURCES\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } RtlZeroMemory(psrbIoctl, srbIoctlLength); psrbIoctl->HeaderLength = sizeof(SRB_IO_CONTROL); RtlCopyMemory(psrbIoctl->Signature, NDASSCSI_IOCTL_SIGNATURE, 8); psrbIoctl->Timeout = 10; psrbIoctl->ControlCode = IoctlCode; psrbIoctl->Length = srbIoctlBufferLength; srbIoctlBuffer = (PUCHAR)psrbIoctl + sizeof(SRB_IO_CONTROL); RtlCopyMemory(srbIoctlBuffer, InputBuffer, InputBufferLength); // // Initialize the notification event. // KeInitializeEvent(&event, NotificationEvent, FALSE); startingOffset.QuadPart = 1; // // Build IRP for this request. // Note we do this synchronously for two reasons. If it was done // asynchronously then the completion code would have to make a special // check to deallocate the buffer. Second if a completion routine were // used then an additional IRP stack location would be needed. // irp = IoBuildSynchronousFsdRequest( IRP_MJ_SCSI, DeviceObject, psrbIoctl, srbIoctlLength, &startingOffset, &event, &ioStatusBlock); irpStack = IoGetNextIrpStackLocation(irp); if (irp == NULL) { KDPrint(1,("STATUS_INSUFFICIENT_RESOURCES\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } // // Set major and minor codes. // irpStack->MajorFunction = IRP_MJ_SCSI; irpStack->MinorFunction = 1; // // Fill in SRB fields. // irpStack->Parameters.Others.Argument1 = &srb; // // Zero out the srb. // RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK)); srb.PathId = 0; srb.TargetId = 0; srb.Lun = 0; srb.Function = SRB_FUNCTION_IO_CONTROL; srb.Length = sizeof(SCSI_REQUEST_BLOCK); srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE; srb.QueueAction = SRB_SIMPLE_TAG_REQUEST; srb.QueueTag = SP_UNTAGGED; srb.OriginalRequest = irp; // // Set timeout to requested value. // srb.TimeOutValue = psrbIoctl->Timeout; // // Set the data buffer. // srb.DataBuffer = psrbIoctl; srb.DataTransferLength = srbIoctlLength; // // Flush the data buffer for output. This will insure that the data is // written back to memory. Since the data-in flag is the the port driver // will flush the data again for input which will ensure the data is not // in the cache. // /* KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE); */ status = IoCallDriver( DeviceObject, irp ); // // Wait for request to complete. // if (status == STATUS_PENDING) { (VOID)KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL ); status = ioStatusBlock.Status; } // // get the result // if(status == STATUS_SUCCESS) { if(OutputBuffer && OutputBufferLength) RtlCopyMemory(OutputBuffer, srbIoctlBuffer, OutputBufferLength); KDPrint(1,("Ioctl(%08lx) succeeded!\n", IoctlCode)); } cleanup: if(psrbIoctl) ExFreePool(psrbIoctl); return status; }
/************************************************************************* * * Function: Ext2MountVolume() * * Description: * This routine is used for performing a verify read... * * Expected Interrupt Level (for execution) : * IRQL_PASSIVE_LEVEL * * Arguments: * TargetDeviceObject - The target of the query * PartitionInformation - Receives the result of the query * * Return Value: * NTSTATUS - The return status for the operation * *************************************************************************/ BOOLEAN Ext2PerformVerifyDiskRead( IN PDEVICE_OBJECT TargetDeviceObject, IN PVOID Buffer, IN LONGLONG Lbo, IN ULONG NumberOfBytesToRead ) { KEVENT Event; PIRP Irp; LARGE_INTEGER ByteOffset; NTSTATUS Status; IO_STATUS_BLOCK Iosb; // // Initialize the event we're going to use // KeInitializeEvent( &Event, NotificationEvent, FALSE ); // // Build the irp for the operation // ByteOffset.QuadPart = Lbo; Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, TargetDeviceObject, Buffer, NumberOfBytesToRead, &ByteOffset, &Event, &Iosb ); if ( Irp == NULL ) { Status = FALSE; } Ext2SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); // // Call the device to do the read and wait for it to finish. // Status = IoCallDriver( TargetDeviceObject, Irp ); if (Status == STATUS_PENDING) { (VOID)KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL ); Status = Iosb.Status; } ASSERT(Status != STATUS_VERIFY_REQUIRED); // // Special case this error code because this probably means we used // the wrong sector size and we want to reject STATUS_WRONG_VOLUME. // if (Status == STATUS_INVALID_PARAMETER) { DbgPrint("Ext2PerformVerifyDiskRead Invalid Param\n"); return FALSE; } if (Status == STATUS_NO_MEDIA_IN_DEVICE) { DbgPrint("Ext2PerformVerifyDiskRead NO MEDIA in DEVICE!!! BS!!\n"); return FALSE; } // // If it doesn't succeed then either return or raise the error. // if (!NT_SUCCESS(Status)) { DbgPrint("Ext2PerformVerifyDiskRead Fail Status %x\n",Status); return FALSE; } // // And return to our caller // return TRUE; }
BOOLEAN NTAPI FsRecReadBlock(IN PDEVICE_OBJECT DeviceObject, IN PLARGE_INTEGER Offset, IN ULONG Length, IN ULONG SectorSize, IN OUT PVOID *Buffer, OUT PBOOLEAN DeviceError OPTIONAL) { IO_STATUS_BLOCK IoStatusBlock; KEVENT Event; PIRP Irp; NTSTATUS Status; PAGED_CODE(); /* Assume failure */ if (DeviceError) *DeviceError = FALSE; /* Check if the caller requested too little */ if (Length < SectorSize) { /* Read at least the sector size */ Length = SectorSize; } else { /* Otherwise, just round up the request to sector size */ Length = ROUND_UP(Length, SectorSize); } /* Check if the caller gave us a buffer */ if (!*Buffer) { /* He didn't, allocate one */ *Buffer = ExAllocatePoolWithTag(NonPagedPool, ROUND_TO_PAGES(Length), FSREC_TAG); if (!*Buffer) return FALSE; } /* Build the IRP */ KeInitializeEvent(&Event, SynchronizationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, *Buffer, Length, Offset, &Event, &IoStatusBlock); if (!Irp) return FALSE; /* Override verification */ IoGetNextIrpStackLocation(Irp)->Flags |= SL_OVERRIDE_VERIFY_VOLUME; /* Do the request */ Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* Check if we couldn't get the data */ if (!NT_SUCCESS(Status)) { /* Check if caller wanted to know about the device and fail */ if (DeviceError) *DeviceError = TRUE; return FALSE; } /* All went well */ return TRUE; }
// // I/O Control to the LanscsiMiniport. // Buffers must be allocated from NonPagedPool // // NOTE: Do not use LANSCSIMINIPORT_IOCTL_QUERYINFO. // It uses separate input/output buffer. // It will be obsolete. // NTSTATUS LSBus_IoctlToLSMPDevice( PPDO_DEVICE_DATA PdoData, ULONG IoctlCode, PVOID InputBuffer, LONG InputBufferLength, PVOID OutputBuffer, LONG OutputBufferLength ) { PDEVICE_OBJECT AttachedDevice; PIRP irp; KEVENT event; PSRB_IO_CONTROL psrbIoctl; LONG srbIoctlLength; PVOID srbIoctlBuffer; LONG srbIoctlBufferLength; NTSTATUS status; PIO_STACK_LOCATION irpStack; SCSI_REQUEST_BLOCK srb; LARGE_INTEGER startingOffset; IO_STATUS_BLOCK ioStatusBlock; AttachedDevice = NULL; psrbIoctl = NULL; irp = NULL; // // get a ScsiPort device or attached one. // AttachedDevice = IoGetAttachedDeviceReference(PdoData->Self); if(AttachedDevice == NULL) { Bus_KdPrint_Def( BUS_DBG_SS_ERROR, ("STATUS_INVALID_DEVICE\n")); return STATUS_NO_SUCH_DEVICE; } // // build an SRB for the miniport // srbIoctlBufferLength = (InputBufferLength>OutputBufferLength)?InputBufferLength:OutputBufferLength; srbIoctlLength = sizeof(SRB_IO_CONTROL) + srbIoctlBufferLength; psrbIoctl = (PSRB_IO_CONTROL)ExAllocatePoolWithTag(NonPagedPool , srbIoctlLength, BUSENUM_POOL_TAG); if(psrbIoctl == NULL) { Bus_KdPrint_Def( BUS_DBG_SS_ERROR, ("STATUS_INSUFFICIENT_RESOURCES\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } RtlZeroMemory(psrbIoctl, srbIoctlLength); psrbIoctl->HeaderLength = sizeof(SRB_IO_CONTROL); RtlCopyMemory(psrbIoctl->Signature, LANSCSIMINIPORT_IOCTL_SIGNATURE, 8); psrbIoctl->Timeout = 60 * 60; psrbIoctl->ControlCode = IoctlCode; psrbIoctl->Length = srbIoctlBufferLength; srbIoctlBuffer = (PUCHAR)psrbIoctl + sizeof(SRB_IO_CONTROL); RtlCopyMemory(srbIoctlBuffer, InputBuffer, InputBufferLength); // // Initialize the notification event. // KeInitializeEvent(&event, NotificationEvent, FALSE); startingOffset.QuadPart = 1; // // Build IRP for this request. // Note we do this synchronously for two reasons. If it was done // asynchonously then the completion code would have to make a special // check to deallocate the buffer. Second if a completion routine were // used then an additional IRP stack location would be needed. // irp = IoBuildSynchronousFsdRequest( IRP_MJ_SCSI, AttachedDevice, psrbIoctl, srbIoctlLength, &startingOffset, &event, &ioStatusBlock); irpStack = IoGetNextIrpStackLocation(irp); if (irp == NULL) { Bus_KdPrint_Def( BUS_DBG_SS_ERROR, ("STATUS_INSUFFICIENT_RESOURCES\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } // // Set major and minor codes. // irpStack->MajorFunction = IRP_MJ_SCSI; irpStack->MinorFunction = 1; // // Fill in SRB fields. // irpStack->Parameters.Others.Argument1 = &srb; // // Zero out the srb. // RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK)); srb.PathId = 0; srb.TargetId = 0; srb.Lun = 0; srb.Function = SRB_FUNCTION_IO_CONTROL; srb.Length = sizeof(SCSI_REQUEST_BLOCK); srb.SrbFlags = /*SRB_FLAGS_DATA_IN |*/ SRB_FLAGS_NO_QUEUE_FREEZE /*| SRB_FLAGS_BYPASS_FROZEN_QUEUE */; srb.OriginalRequest = irp; // // Set timeout to requested value. // srb.TimeOutValue = psrbIoctl->Timeout; // // Set the data buffer. // srb.DataBuffer = psrbIoctl; srb.DataTransferLength = srbIoctlLength; // // Flush the data buffer for output. This will insure that the data is // written back to memory. Since the data-in flag is the the port driver // will flush the data again for input which will ensure the data is not // in the cache. // /* KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE); */ status = IoCallDriver( AttachedDevice, irp ); // // Wait for request to complete. // if (status == STATUS_PENDING) { (VOID)KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, (PLARGE_INTEGER)NULL ); status = ioStatusBlock.Status; } // // get the result // // if(status == STATUS_SUCCESS) { if(OutputBuffer && OutputBufferLength) RtlCopyMemory(OutputBuffer, srbIoctlBuffer, OutputBufferLength); Bus_KdPrint_Def( BUS_DBG_SS_NOISE, ("%d succeeded!\n", IoctlCode)); // } if(psrbIoctl->ControlCode == STATUS_BUFFER_TOO_SMALL) { status = STATUS_BUFFER_TOO_SMALL; } cleanup: if(psrbIoctl) ExFreePool(psrbIoctl); if(AttachedDevice) ObDereferenceObject(AttachedDevice); return status; }
/* *@implemented */ BOOLEAN STREAMAPI StreamClassReadWriteConfig( IN PVOID HwDeviceExtension, IN BOOLEAN Read, IN PVOID Buffer, IN ULONG OffSet, IN ULONG Length) { PIRP Irp; ULONG MajorFunction; KEVENT Event; PSTREAM_DEVICE_EXTENSION DeviceExtension; LARGE_INTEGER Offset; IO_STATUS_BLOCK StatusBlock; NTSTATUS Status; /* Get our DeviceExtension */ DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION)); ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension); if (Read) { /* Zero input buffer */ RtlZeroMemory(Buffer, Length); } /* Set request type */ MajorFunction = (Read ? IRP_MJ_READ : IRP_MJ_WRITE); /* Initialize event */ KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Set offset */ Offset.QuadPart = OffSet; /* Pre-init status block */ StatusBlock.Status = STATUS_NOT_SUPPORTED; /* Create Irp */ Irp = IoBuildSynchronousFsdRequest(MajorFunction, DeviceExtension->LowerDeviceObject, /* Verify */ Buffer, Length, &Offset, &Event, &StatusBlock); if (!Irp) { /* Failed to allocate memory */ return FALSE; } /* Setup a completion routine */ IoSetCompletionRoutine(Irp, StreamClassRWCompletion, (PVOID)&Event, TRUE, TRUE, TRUE); /* Call driver */ Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp); if (Status == STATUS_PENDING) { /* Request is pending, wait for result */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); /* Fetch result */ Status = StatusBlock.Status; } if (!NT_SUCCESS(Status)) { return FALSE; } /* FIXME Handle Length != InputLength */ return TRUE; }
NTSTATUS VfatFlushVolume( PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) { PLIST_ENTRY ListEntry; PVFATFCB Fcb; NTSTATUS Status, ReturnStatus = STATUS_SUCCESS; PIRP Irp; KEVENT Event; IO_STATUS_BLOCK IoStatusBlock; DPRINT("VfatFlushVolume(DeviceExt %p, VolumeFcb %p)\n", DeviceExt, VolumeFcb); ASSERT(VolumeFcb == DeviceExt->VolumeFcb); ListEntry = DeviceExt->FcbListHead.Flink; while (ListEntry != &DeviceExt->FcbListHead) { Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry); ListEntry = ListEntry->Flink; if (!vfatFCBIsDirectory(Fcb)) { ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); Status = VfatFlushFile(DeviceExt, Fcb); ExReleaseResourceLite (&Fcb->MainResource); if (!NT_SUCCESS(Status)) { DPRINT1("VfatFlushFile failed, status = %x\n", Status); ReturnStatus = Status; } } /* FIXME: Stop flushing if this is a removable media and the media was removed */ } ListEntry = DeviceExt->FcbListHead.Flink; while (ListEntry != &DeviceExt->FcbListHead) { Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry); ListEntry = ListEntry->Flink; if (vfatFCBIsDirectory(Fcb)) { ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE); Status = VfatFlushFile(DeviceExt, Fcb); ExReleaseResourceLite (&Fcb->MainResource); if (!NT_SUCCESS(Status)) { DPRINT1("VfatFlushFile failed, status = %x\n", Status); ReturnStatus = Status; } } /* FIXME: Stop flushing if this is a removable media and the media was removed */ } Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext; ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE); Status = VfatFlushFile(DeviceExt, Fcb); ExReleaseResourceLite(&DeviceExt->FatResource); /* Prepare an IRP to flush device buffers */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS, DeviceExt->StorageDevice, NULL, 0, NULL, &Event, &IoStatusBlock); if (Irp != NULL) { KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceExt->StorageDevice, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* Ignore device not supporting flush operation */ if (Status == STATUS_INVALID_DEVICE_REQUEST) { DPRINT1("Flush not supported, ignored\n"); Status = STATUS_SUCCESS; } } else { Status = STATUS_INSUFFICIENT_RESOURCES; } if (!NT_SUCCESS(Status)) { DPRINT1("VfatFlushFile failed, status = %x\n", Status); ReturnStatus = Status; } return ReturnStatus; }
// for pdo NTSTATUS DoPdoPnP(PDEVICE_OBJECT pDevice,PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; PPdoExt pPdoExt = static_cast<PPdoExt>(pDevice->DeviceExtension); PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp); switch(pIoStack->MinorFunction) { case IRP_MN_START_DEVICE: // set power state pPdoExt->m_devPowerState = PowerDeviceD0; POWER_STATE state; state.DeviceState = PowerDeviceD0; PoSetPowerState(pDevice,DevicePowerState,state); // set pnp state directly case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE: SetNewPnpState(pPdoExt,pIoStack->MinorFunction); break; // check prev state case IRP_MN_CANCEL_REMOVE_DEVICE: if(pPdoExt->m_ulCurrentPnpState == IRP_MN_QUERY_REMOVE_DEVICE) { RestorePnpState(pPdoExt); } break; // the same case IRP_MN_CANCEL_STOP_DEVICE: if(pPdoExt->m_ulCurrentPnpState == IRP_MN_QUERY_STOP_DEVICE) { RestorePnpState(pPdoExt); } break; // remove case IRP_MN_REMOVE_DEVICE: { // delete only if we have reported the device physical removal if(pPdoExt->m_bReportMissing) { SetNewPnpState(pPdoExt,IRP_MN_REMOVE_DEVICE); PDEVICE_OBJECT pFdo = pPdoExt->m_pParentFdo; if(pFdo) { PFdoExt pFdoExt = static_cast<PFdoExt>(pFdo->DeviceExtension); // update fdo's pointer ExAcquireFastMutex(&pFdoExt->m_mutexEnumPdo); pFdoExt->m_pEnumPdo = NULL; ExReleaseFastMutex(&pFdoExt->m_mutexEnumPdo); } // delete device IoDeleteDevice(pDevice); } // if it's present if(pPdoExt->m_bPresent) { // set it as stopped SetNewPnpState(pPdoExt,IRP_MN_STOP_DEVICE); } } break; // query caps case IRP_MN_QUERY_CAPABILITIES: { PDEVICE_CAPABILITIES pCaps = pIoStack->Parameters.DeviceCapabilities.Capabilities; // version check if(pCaps->Version != 1 || pCaps->Size < sizeof(DEVICE_CAPABILITIES)) { status = STATUS_UNSUCCESSFUL; break; } IO_STATUS_BLOCK ioStatus; KEVENT pnpEvent; PDEVICE_OBJECT pTargetObject; PIO_STACK_LOCATION pIrpStack; PIRP pPnpIrp; DEVICE_CAPABILITIES parentCaps; RtlZeroMemory(&parentCaps,sizeof(DEVICE_CAPABILITIES)); parentCaps.Size = sizeof(DEVICE_CAPABILITIES); parentCaps.Version = 1; parentCaps.Address = -1; parentCaps.UINumber = -1; KeInitializeEvent(&pnpEvent,NotificationEvent,FALSE); pTargetObject = IoGetAttachedDeviceReference( static_cast<PFdoExt>(pPdoExt->m_pParentFdo->DeviceExtension)->m_pLowerDevice); // get parent fdo's caps pPnpIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,pTargetObject,NULL,0,NULL,&pnpEvent,&ioStatus); if(pPnpIrp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; } else { pPnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; pIrpStack = IoGetNextIrpStackLocation(pPnpIrp); RtlZeroMemory(pIrpStack,sizeof(IO_STACK_LOCATION)); pIrpStack->MajorFunction = IRP_MJ_PNP; pIrpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; pIrpStack->Parameters.DeviceCapabilities.Capabilities = pCaps; status = IoCallDriver(pTargetObject,pPnpIrp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&pnpEvent,Executive,KernelMode,FALSE,NULL); status = ioStatus.Status; } } // dec the ref of the fdo's stack upper device ObDereferenceObject(pTargetObject); // copy the device state RtlCopyMemory(pCaps->DeviceState,parentCaps.DeviceState,(PowerSystemShutdown + 1) * sizeof(DEVICE_POWER_STATE)); // set our own supported device state pCaps->DeviceState[PowerSystemWorking] = PowerDeviceD0; if(pCaps->DeviceState[PowerSystemSleeping1] != PowerDeviceD0) pCaps->DeviceState[PowerSystemSleeping1] = PowerDeviceD3; if(pCaps->DeviceState[PowerSystemSleeping2] != PowerDeviceD0) pCaps->DeviceState[PowerSystemSleeping2] = PowerDeviceD3; if(pCaps->DeviceState[PowerSystemSleeping3] != PowerDeviceD0) pCaps->DeviceState[PowerSystemSleeping3] = PowerDeviceD3; // donot support d1 and d2 pCaps->DeviceD1 = pCaps->DeviceD2 = FALSE; // no wake pCaps->DeviceWake = PowerDeviceUnspecified; pCaps->SystemWake = PowerSystemUnspecified; pCaps->WakeFromD0 = FALSE; pCaps->WakeFromD1 = FALSE; pCaps->WakeFromD2 = FALSE; pCaps->WakeFromD3 = FALSE; // no latency pCaps->D1Latency = 0; pCaps->D2Latency = 0; pCaps->D3Latency = 0; // can eject pCaps->EjectSupported = TRUE; // don't disable pCaps->HardwareDisabled = FALSE; // can be removed pCaps->Removable = TRUE; // don't display surprise remove warning dlg pCaps->SurpriseRemovalOK = TRUE; // no unique id pCaps->UniqueID = FALSE; // nead user action for install pCaps->SilentInstall = FALSE; // bus address pCaps->Address = 0; // ui display number pCaps->UINumber = 0; } break; // query pdo id case IRP_MN_QUERY_ID: { switch(pIoStack->Parameters.QueryId.IdType) { case BusQueryInstanceID: { PVOID buffer = ExAllocatePoolWithTag(PagedPool,10,'suBT'); if(!buffer) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlStringCchPrintfW(static_cast<PWCHAR>(buffer),10,L"%04d",0); pIrp->IoStatus.Information = PtrToUlong(buffer); devDebugPrint("\tBusQueryInstanceID\n"); } break; case BusQueryDeviceID: { PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_DEVICE_ID_LENGTH,'suBT'); if(!buffer) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlCopyMemory(buffer,PDO_DEVICE_ID,PDO_DEVICE_ID_LENGTH); pIrp->IoStatus.Information = PtrToUlong(buffer); devDebugPrint("\tBusQueryDeviceID\n"); } break; case BusQueryHardwareIDs: { PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_HARDWARE_IDS_LENGTH,'suBT'); if(!buffer) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlCopyMemory(buffer,PDO_HARDWARE_IDS,PDO_HARDWARE_IDS_LENGTH); pIrp->IoStatus.Information = PtrToUlong(buffer); devDebugPrint("\tBusQueryHardwareIDs\n"); } break; case BusQueryCompatibleIDs: { PVOID buffer = ExAllocatePoolWithTag(PagedPool,PDO_COMPATIBLE_IDS_LENGTH,'suBT'); if(!buffer) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlCopyMemory(buffer,PDO_COMPATIBLE_IDS,PDO_COMPATIBLE_IDS_LENGTH); pIrp->IoStatus.Information = PtrToUlong(buffer); devDebugPrint("\tBusQueryCompatibleIDs\n"); } break; } } break; // query text case IRP_MN_QUERY_DEVICE_TEXT: { switch (pIoStack->Parameters.QueryDeviceText.DeviceTextType) { case DeviceTextDescription: if(!pIrp->IoStatus.Information) { PVOID buffer = ExAllocatePoolWithTag (PagedPool,PDO_TEXT_LENGTH,'suBT'); if(!buffer) { status = STATUS_INSUFFICIENT_RESOURCES; break; } RtlStringCchPrintfW(static_cast<PWCHAR>(buffer),PDO_TEXT_LENGTH,L"%ws",PDO_TEXT); pIrp->IoStatus.Information = PtrToUlong(buffer); devDebugPrint("\tDeviceTextDescription\n"); } break; default: status = pIrp->IoStatus.Status; break; } } break; // boot resource case IRP_MN_QUERY_RESOURCES: { PCM_RESOURCE_LIST pResList = static_cast<PCM_RESOURCE_LIST>(ExAllocatePoolWithTag(PagedPool, sizeof(CM_RESOURCE_LIST),'suBT')); if(pResList) { // shareed busnumber resource RtlZeroMemory(pResList,sizeof(CM_RESOURCE_LIST)); pResList->Count = 1; pResList->List[0].BusNumber = 0; pResList->List[0].InterfaceType = Internal; pResList->List[0].PartialResourceList.Count = 1; pResList->List[0].PartialResourceList.Revision = 1; pResList->List[0].PartialResourceList.Version = 1; pResList->List[0].PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareShared; pResList->List[0].PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeBusNumber; pResList->List[0].PartialResourceList.PartialDescriptors[0].u.BusNumber.Length = 1; pIrp->IoStatus.Information = PtrToUlong(pResList); } else { status = STATUS_INSUFFICIENT_RESOURCES; } } break; // resource requirements case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: { PIO_RESOURCE_REQUIREMENTS_LIST pList = static_cast<PIO_RESOURCE_REQUIREMENTS_LIST>( ExAllocatePoolWithTag(PagedPool,sizeof(IO_RESOURCE_REQUIREMENTS_LIST),'suBT')); if(pList) { RtlZeroMemory(pList,sizeof(IO_RESOURCE_REQUIREMENTS_LIST)); pList->ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST); pList->AlternativeLists = 1; pList->InterfaceType = InterfaceTypeUndefined; pList->BusNumber = 0; pList->List[0].Version = 1; pList->List[0].Revision = 1; pList->List[0].Count = 1; pList->List[0].Descriptors[0].Option = IO_RESOURCE_PREFERRED; pList->List[0].Descriptors[0].ShareDisposition = CmResourceShareShared; pList->List[0].Descriptors[0].Type = CmResourceTypeBusNumber; pList->List[0].Descriptors[0].u.BusNumber.MaxBusNumber = 0x10; pList->List[0].Descriptors[0].u.BusNumber.Length = 1; pIrp->IoStatus.Information = PtrToUlong(pList); } else { status = STATUS_INSUFFICIENT_RESOURCES; } } break; // bus info case IRP_MN_QUERY_BUS_INFORMATION: { PPNP_BUS_INFORMATION busInfo; busInfo = static_cast<PPNP_BUS_INFORMATION>(ExAllocatePoolWithTag(PagedPool, sizeof(PNP_BUS_INFORMATION),'suBT')); if (busInfo == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; break; } busInfo->BusTypeGuid = GUID_TIAMO_BUS; busInfo->LegacyBusType = Internal; busInfo->BusNumber = 0; pIrp->IoStatus.Information = PtrToUlong(busInfo); } break; // usage case IRP_MN_DEVICE_USAGE_NOTIFICATION: status = STATUS_UNSUCCESSFUL; break; case IRP_MN_EJECT: { // device physical removed pPdoExt->m_bPresent = FALSE; } break; //case IRP_MN_QUERY_INTERFACE: // break; // target relations case IRP_MN_QUERY_DEVICE_RELATIONS: { if(pIoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) { /*switch(pIoStack->Parameters.QueryDeviceRelations.Type) { case EjectionRelations: devDebugPrint("\tquery EjectionRelations\n"); break; case PowerRelations: devDebugPrint("\tquery PowerRelations\n"); break; case RemovalRelations: devDebugPrint("\tquery RemovalRelations\n"); break; case BusDeviceRelation: devDebugPrint("\tquery BusDeviceRelation\n"); break; case SingleBusRelations: devDebugPrint("\tquery SingleBusRelations\n"); break; }*/ break; } PDEVICE_RELATIONS pRel = static_cast<PDEVICE_RELATIONS>(ExAllocatePoolWithTag(PagedPool,sizeof(DEVICE_RELATIONS),'suBT')); if(!pRel) { status = STATUS_INSUFFICIENT_RESOURCES; break; } pRel->Count = 1; pRel->Objects[0] = pDevice; ObReferenceObject(pDevice); status = STATUS_SUCCESS; pIrp->IoStatus.Information = PtrToUlong(pRel); } break; default: status = pIrp->IoStatus.Status; break; } // pdo should complete the irp pIrp->IoStatus.Status = status; IoCompleteRequest (pIrp, IO_NO_INCREMENT); return status; }
NTSTATUS Ext2ReadSync( IN PEXT2_VCB Vcb, IN ULONGLONG Offset, IN ULONG Length, OUT PVOID Buffer, BOOLEAN bVerify ) { PKEVENT Event = NULL; PIRP Irp; IO_STATUS_BLOCK IoStatus; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; ASSERT(Vcb != NULL); ASSERT(Vcb->TargetDeviceObject != NULL); ASSERT(Buffer != NULL); __try { Event = Ext2AllocatePool(NonPagedPool, sizeof(KEVENT), 'EK2E'); if (NULL == Event) { DEBUG(DL_ERR, ( "Ex2ReadSync: failed to allocate Event.\n")); __leave; } INC_MEM_COUNT(PS_DISK_EVENT, Event, sizeof(KEVENT)); 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) { Ext2FreePool(Event, 'EK2E'); DEC_MEM_COUNT(PS_DISK_EVENT, Event, sizeof(KEVENT)); } } return Status; }
NTSTATUS VfatReadDisk( IN PDEVICE_OBJECT pDeviceObject, IN PLARGE_INTEGER ReadOffset, IN ULONG ReadLength, IN OUT PUCHAR Buffer, IN BOOLEAN Override) { PIO_STACK_LOCATION Stack; PIRP Irp; IO_STATUS_BLOCK IoStatus; KEVENT Event; NTSTATUS Status; again: KeInitializeEvent(&Event, NotificationEvent, FALSE); DPRINT("VfatReadDisk(pDeviceObject %p, Offset %I64x, Length %u, Buffer %p)\n", pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer); DPRINT ("Building synchronous FSD Request...\n"); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, pDeviceObject, Buffer, ReadLength, ReadOffset, &Event, &IoStatus); if (Irp == NULL) { DPRINT("IoBuildSynchronousFsdRequest failed\n"); return STATUS_UNSUCCESSFUL; } if (Override) { Stack = IoGetNextIrpStackLocation(Irp); Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME; } DPRINT("Calling IO Driver... with irp %p\n", Irp); Status = IoCallDriver (pDeviceObject, Irp); DPRINT("Waiting for IO Operation for %p\n", Irp); if (Status == STATUS_PENDING) { DPRINT("Operation pending\n"); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); DPRINT("Getting IO Status... for %p\n", Irp); Status = IoStatus.Status; } if (Status == STATUS_VERIFY_REQUIRED) { PDEVICE_OBJECT DeviceToVerify; DPRINT1 ("Media change detected!\n"); /* Find the device to verify and reset the thread field to empty value again. */ DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread()); IoSetDeviceToVerify(PsGetCurrentThread(), NULL); Status = IoVerifyVolume(DeviceToVerify, FALSE); if (NT_SUCCESS(Status)) { DPRINT1("Volume verification successful; Reissuing read request\n"); goto again; } } if (!NT_SUCCESS(Status)) { DPRINT("IO failed!!! VfatReadDisk : Error code: %x\n", Status); DPRINT("(pDeviceObject %p, Offset %I64x, Size %u, Buffer %p\n", pDeviceObject, ReadOffset->QuadPart, ReadLength, Buffer); return Status; } DPRINT("Block request succeeded for %p\n", Irp); return STATUS_SUCCESS; }
__drv_mustHoldCriticalRegion NTSTATUS FatCommonShutdown ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp ) /*++ Routine Description: This is the common routine for shutdown called by both the fsd and fsp threads. Arguments: Irp - Supplies the Irp being processed Return Value: NTSTATUS - The return status for the operation --*/ { KEVENT Event; PLIST_ENTRY Links; PVCB Vcb; PIRP NewIrp; IO_STATUS_BLOCK Iosb; BOOLEAN VcbDeleted; PAGED_CODE(); // // Make sure we don't get any pop-ups, and write everything through. // SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS | IRP_CONTEXT_FLAG_WRITE_THROUGH); // // Initialize an event for doing calls down to // our target device objects. // KeInitializeEvent( &Event, NotificationEvent, FALSE ); // // Indicate that shutdown has started. This is used in FatFspClose. // FatData.ShutdownStarted = TRUE; // // Get everyone else out of the way // ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); #pragma prefast( push ) #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) #pragma prefast( disable: 28193, "this will always wait" ) (VOID) FatAcquireExclusiveGlobal( IrpContext ); #pragma prefast( pop ) try { // // For every volume that is mounted we will flush the // volume and then shutdown the target device objects. // Links = FatData.VcbQueue.Flink; while (Links != &FatData.VcbQueue) { Vcb = CONTAINING_RECORD(Links, VCB, VcbLinks); Links = Links->Flink; // // If we have already been called before for this volume // (and yes this does happen), skip this volume as no writes // have been allowed since the first shutdown. // if ( FlagOn( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN) || (Vcb->VcbCondition != VcbGood) ) { continue; } FatAcquireExclusiveVolume( IrpContext, Vcb ); try { (VOID)FatFlushVolume( IrpContext, Vcb, Flush ); // // The volume is now clean, note it. We purge the // volume file cache map before marking the volume // clean incase there is a stale Bpb in the cache. // if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) { CcPurgeCacheSection( &Vcb->SectionObjectPointers, NULL, 0, FALSE ); FatMarkVolume( IrpContext, Vcb, VolumeClean ); } } except( EXCEPTION_EXECUTE_HANDLER ) { FatResetExceptionState( IrpContext ); } // // Sometimes we take an excepion while flushing the volume, such // as when autoconv has converted the volume and is rebooting. // Even in that case we want to send the shutdown irp to the // target device so it can know to flush its cache, if it has one. // try { NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN, Vcb->TargetDeviceObject, NULL, 0, NULL, &Event, &Iosb ); if (NewIrp != NULL) { if (NT_SUCCESS(IoCallDriver( Vcb->TargetDeviceObject, NewIrp ))) { (VOID) KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); KeClearEvent( &Event ); } } } except( EXCEPTION_EXECUTE_HANDLER ) { FatResetExceptionState( IrpContext ); } SetFlag( Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN ); // // Attempt to punch the volume down. // VcbDeleted = FatCheckForDismount( IrpContext, Vcb, FALSE ); if (!VcbDeleted) { #pragma prefast( suppress:28107, "prefast is having trouble figuring out that Vcb is acquired" ) FatReleaseVolume( IrpContext, Vcb ); } } } finally { FatReleaseGlobal( IrpContext ); // // Unregister the file system. // IoUnregisterFileSystem( FatDiskFileSystemDeviceObject); IoUnregisterFileSystem( FatCdromFileSystemDeviceObject); IoDeleteDevice( FatDiskFileSystemDeviceObject); IoDeleteDevice( FatCdromFileSystemDeviceObject); FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); } // // And return to our caller // DebugTrace(-1, Dbg, "FatFsdShutdown -> STATUS_SUCCESS\n", 0); return STATUS_SUCCESS; }
NTSTATUS CdCommonShutdown ( _Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp ) /*++ Routine Description: This is the common routine for handling shutdown operation called by both the fsd and fsp threads Arguments: Irp - Supplies the Irp to process Return Value: NTSTATUS - The return status for the operation --*/ { KEVENT Event; PLIST_ENTRY Links; PVCB Vcb; PIRP NewIrp; IO_STATUS_BLOCK Iosb; BOOLEAN VcbPresent; NTSTATUS Status; PAGED_CODE(); // // Make sure we don't get any pop-ups. // SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS ); // // Initialize an event for doing calls down to // our target device objects. // KeInitializeEvent( &Event, NotificationEvent, FALSE ); // // Indicate that shutdown has started. // SetFlag( CdData.Flags, CD_FLAGS_SHUTDOWN ); // // Get everyone else out of the way // CdAcquireCdData( IrpContext ); // // Now walk through all the mounted Vcb's and shutdown the target // device objects. // Links = CdData.VcbQueue.Flink; while (Links != &CdData.VcbQueue) { Vcb = CONTAINING_RECORD( Links, VCB, VcbLinks ); // // Move to the next link now since the current Vcb may be deleted. // Links = Links->Flink; // // If we have already been called before for this volume // (and yes this does happen), skip this volume as no writes // have been allowed since the first shutdown. // if (FlagOn( Vcb->VcbState, VCB_STATE_SHUTDOWN ) || (Vcb->VcbCondition != VcbMounted)) { continue; } #pragma prefast(suppress: 28103) CdAcquireVcbExclusive( IrpContext, Vcb, FALSE ); CdPurgeVolume( IrpContext, Vcb, FALSE ); // // Build an irp for this volume stack - our own irp is probably too small and // each stack may have a different stack size. // NewIrp = IoBuildSynchronousFsdRequest( IRP_MJ_SHUTDOWN, Vcb->TargetDeviceObject, NULL, 0, NULL, &Event, &Iosb ); if (NewIrp != NULL) { Status = IoCallDriver( Vcb->TargetDeviceObject, NewIrp ); if (Status == STATUS_PENDING) { (VOID)KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL ); } KeClearEvent( &Event ); } SetFlag( Vcb->VcbState, VCB_STATE_SHUTDOWN ); // // Attempt to punch the volume down. // VcbPresent = CdCheckForDismount( IrpContext, Vcb, FALSE ); if (VcbPresent) { CdReleaseVcb( IrpContext, Vcb ); } } CdReleaseCdData( IrpContext ); IoUnregisterFileSystem( CdData.FileSystemDeviceObject ); IoDeleteDevice( CdData.FileSystemDeviceObject ); CdCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); return STATUS_SUCCESS; }
NTSTATUS QueryEvtchnInterface( __in PDEVICE_OBJECT DeviceObject ) { INTERFACE Interface; IO_STATUS_BLOCK StatusBlock; KEVENT Event; PDEVICE_EXTENSION pdx; PIRP Irp; PIO_STACK_LOCATION StackLocation; NTSTATUS status; Warning("Querying Event Channel Interface.\n"); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); KeInitializeEvent(&Event, NotificationEvent, FALSE); RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK)); pdx = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, pdx->LowerDeviceObject, NULL, 0, NULL, &Event, &StatusBlock); if (Irp == NULL) { Warning("Unable to build synchronous FSD request.\n"); return STATUS_UNSUCCESSFUL; } StackLocation = IoGetNextIrpStackLocation(Irp); StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_EVTCHN_INTERFACE; StackLocation->Parameters.QueryInterface.Size = sizeof(INTERFACE); StackLocation->Parameters.QueryInterface.Version = EVTCHN_INTERFACE_VERSION; StackLocation->Parameters.QueryInterface.Interface = &Interface; Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; status = IoCallDriver(pdx->LowerDeviceObject, Irp); if (status == STATUS_PENDING) { (VOID) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); status = StatusBlock.Status; } if (!NT_SUCCESS(status)) { Warning("Failed waiting on KEvent.\n"); return status; } pdx->EvtchnInterface = Interface.Context; return STATUS_SUCCESS; }
NTSTATUS NTSectorIO( char* szDeviceName, LARGE_INTEGER* liSeekPos, DWORD dwBytes, BYTE* buffer, int wr) { ANSI_STRING ansiDeviceName; UNICODE_STRING uniDeviceName; // HANDLE hFileHandle; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatus; NTSTATUS status; PIRP irp; KEVENT event; PDEVICE_OBJECT deviceObject; PFILE_OBJECT fileObject; BOOL verify=0; RtlInitAnsiString(&ansiDeviceName,(PSTR)szDeviceName); RtlAnsiStringToUnicodeString(&uniDeviceName,&ansiDeviceName,TRUE); InitializeObjectAttributes(&ObjectAttributes,&uniDeviceName, OBJ_CASE_INSENSITIVE,NULL,NULL); again: status= IoGetDeviceObjectPointer( &uniDeviceName, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); if(!NT_SUCCESS(status)){ RtlFreeUnicodeString(&uniDeviceName); return status; } if (fileObject->DeviceObject->DeviceType != FILE_DEVICE_DISK) { RtlFreeUnicodeString(&uniDeviceName); ObDereferenceObject(fileObject); status=STATUS_IO_DEVICE_ERROR; return status; } deviceObject=fileObject->DeviceObject; irp=IoBuildSynchronousFsdRequest( wr?IRP_MJ_WRITE:IRP_MJ_READ, deviceObject, buffer, dwBytes, liSeekPos, &event, &IoStatus); ObDereferenceObject(fileObject); if(!irp) { RtlFreeUnicodeString(&uniDeviceName); return STATUS_IO_DEVICE_ERROR; } KeInitializeEvent(&event,NotificationEvent,FALSE); status = IoCallDriver(deviceObject,irp); if(status==STATUS_PENDING) { KeWaitForSingleObject(&event,Suspended,KernelMode,FALSE,NULL); status= IoStatus.Status; } if (status == STATUS_VERIFY_REQUIRED) if(!verify++) goto again; RtlFreeUnicodeString(&uniDeviceName); if (!NT_SUCCESS(status)) return status; if (!NT_SUCCESS(IoStatus.Status)) return status; #if 0 // dump sector { int count,a,b,c,i; count =0; for (i=0; i<32; i++) { for (a=count; a<count+8; a++) DbgPrint("%02X ",buffer[a]); DbgPrint(" - "); for (b=count+8; b<count+16; b++) DbgPrint("%02X ",buffer[b]); DbgPrint(" "); for (c=count;c<count+16;c++) if(buffer[c] >= ' ' ) DbgPrint("%c",buffer[c]); else DbgPrint("."); DbgPrint("\n"); count+=16; } } #endif return status; }