/** * IRP_MJ_PNP:IRP_MN_QUERY_BUS_INFORMATION handler * * IRQL == PASSIVE_LEVEL, any thread * Do not send this IRP * Completed by PDO (here) * * @return * Success: * Irp->IoStatus.Status == STATUS_SUCCESS * Irp->IoStatus.Information populated from paged memory * Error: * Irp->IoStatus.Status == STATUS_INSUFFICIENT_RESOURCES * Irp->IoStatus.Information == 0 * * TODO: Maybe it's best for a PDO to query its parent for this info, * instead of carrying it around */ static NTSTATUS STDCALL WvDummyPnpQueryBusInfo( IN DEVICE_OBJECT * dev_obj, IN IRP * irp ) { S_WVL_DUMMY_PDO * dummy; VOID * pnp_bus_info; NTSTATUS status; ASSERT(dev_obj); ASSERT(irp); dummy = dev_obj->DeviceExtension; ASSERT(dummy); /* Allocate for a copy of the bus info */ pnp_bus_info = wv_palloc(sizeof dummy->PnpBusInfo); if (!pnp_bus_info) { DBG("wv_palloc failed\n"); status = STATUS_INSUFFICIENT_RESOURCES; irp->IoStatus.Information = 0; goto pnp_bus_info; } /* Copy the bus info */ RtlCopyMemory(pnp_bus_info, dummy->PnpBusInfo, sizeof dummy->PnpBusInfo); irp->IoStatus.Information = (ULONG_PTR) pnp_bus_info; status = STATUS_SUCCESS; /* irp->IoStatus.Information (pnp_bus_info) not freed */ pnp_bus_info: irp->IoStatus.Status = status; WvlPassIrpUp(dev_obj, irp, IO_NO_INCREMENT); return status; }
/** * Handle a PnP ID query with a WV_S_DUMMY_IDS object. * * @v Irp The PnP ID query IRP to handle. * @v DummyIds The object containing the IDs to respond with. * @ret NTSTATUS The status of the operation. */ static NTSTATUS STDCALL WvDummyIds( IN PIRP Irp, IN WV_SP_DUMMY_IDS DummyIds ) { PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(Irp); BUS_QUERY_ID_TYPE query_type = io_stack_loc->Parameters.QueryId.IdType; const CHAR * start; const WCHAR * ids; UINT32 len; NTSTATUS status; start = (const CHAR *) DummyIds + DummyIds->Offset; ids = (const WCHAR *) start; switch (query_type) { case BusQueryDeviceID: ids += DummyIds->DevOffset; len = DummyIds->DevLen; break; case BusQueryInstanceID: ids += DummyIds->InstanceOffset; len = DummyIds->InstanceLen; break; case BusQueryHardwareIDs: ids += DummyIds->HardwareOffset; len = DummyIds->HardwareLen; break; case BusQueryCompatibleIDs: ids += DummyIds->CompatOffset; len = DummyIds->CompatLen; break; default: return WvlIrpComplete(Irp, 0, STATUS_NOT_SUPPORTED); } /* Allocate the return buffer. */ Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(len * sizeof *ids); if (Irp->IoStatus.Information == 0) { DBG("wv_palloc failed.\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto alloc_info; } /* Copy the working buffer to the return buffer. */ RtlCopyMemory( (PVOID) Irp->IoStatus.Information, ids, len * sizeof *ids ); status = STATUS_SUCCESS; /* irp->IoStatus.Information not freed. */ alloc_info: return WvlIrpComplete(Irp, Irp->IoStatus.Information, status); }
NTSTATUS STDCALL WvDiskPnpQueryDevText( IN PDEVICE_OBJECT dev_obj, IN PIRP irp, IN WVL_SP_DISK_T disk ) { IN WV_SP_DEV_T dev = WvDevFromDevObj(dev_obj); WCHAR (*str)[512]; PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp); NTSTATUS status; UINT32 str_len; /* Allocate a string buffer. */ str = wv_mallocz(sizeof *str); if (str == NULL) { DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto alloc_str; } /* Determine the query type. */ switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) { case DeviceTextDescription: str_len = swprintf(*str, WVL_M_WLIT L" Disk") + 1; irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof *str); if (irp->IoStatus.Information == 0) { DBG("wv_palloc DeviceTextDescription\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto alloc_info; } RtlCopyMemory( (PWCHAR) irp->IoStatus.Information, str, str_len * sizeof *str ); status = STATUS_SUCCESS; goto alloc_info; case DeviceTextLocationInformation: if (disk->disk_ops.PnpQueryId) { io_stack_loc->MinorFunction = IRP_MN_QUERY_ID; io_stack_loc->Parameters.QueryId.IdType = BusQueryInstanceID; return disk->disk_ops.PnpQueryId(dev_obj, irp, disk); } /* Else, fall through... */ default: irp->IoStatus.Information = 0; status = STATUS_NOT_SUPPORTED; } /* irp->IoStatus.Information not freed. */ alloc_info: wv_free(str); alloc_str: return WvlIrpComplete(irp, irp->IoStatus.Information, status); }
/** * IRP_MJ_PNP:IRP_MN_QUERY_ID handler * * IRQL == PASSIVE_LEVEL, any thread * Ok to send this IRP * Completed by PDO (here) * * @param Parameters.QueryId.IdType (I/O stack location) * * @return * Success: * Irp->IoStatus.Status == STATUS_SUCCESS * Irp->IoStatus.Information populated from paged memory * Error: * Irp->IoStatus.Information == 0 * Irp->IoStatus.Status == STATUS_INSUFFICIENT_RESOURCES * or * Irp->IoStatus.Status == STATUS_NOT_SUPPORTED */ static NTSTATUS STDCALL WvDummyPnpQueryId( IN DEVICE_OBJECT * dev_obj, IN IRP * irp ) { S_WVL_DUMMY_PDO * dummy; IO_STACK_LOCATION * io_stack_loc; const UCHAR * ptr; const WCHAR * ids; BUS_QUERY_ID_TYPE query_type; UINT32 len; VOID * response; NTSTATUS status; ASSERT(dev_obj); dummy = dev_obj->DeviceExtension; ASSERT(dummy); ASSERT(irp); io_stack_loc = IoGetCurrentIrpStackLocation(irp); ASSERT(io_stack_loc); ptr = (const VOID *) dummy->DummyIds; ptr += dummy->DummyIds->Offset; ids = (const VOID *) ptr; query_type = io_stack_loc->Parameters.QueryId.IdType; switch (query_type) { case BusQueryDeviceID: ids += dummy->DummyIds->DevOffset; len = dummy->DummyIds->DevLen; break; case BusQueryHardwareIDs: ids += dummy->DummyIds->HardwareOffset; len = dummy->DummyIds->HardwareLen; break; case BusQueryCompatibleIDs: ids += dummy->DummyIds->CompatOffset; len = dummy->DummyIds->CompatLen; break; case BusQueryInstanceID: ids += dummy->DummyIds->InstanceOffset; len = dummy->DummyIds->InstanceLen; break; default: status = STATUS_NOT_SUPPORTED; irp->IoStatus.Information = 0; goto err_query_type; } /* Allocate the respone */ response = wv_palloc(len * sizeof *ids); if (!response) { DBG("Couldn't allocate response\n"); status = STATUS_INSUFFICIENT_RESOURCES; irp->IoStatus.Information = 0; goto err_response; } /* Copy the IDs into the response */ RtlCopyMemory(response, ids, len * sizeof *ids); irp->IoStatus.Information = (ULONG_PTR) response; status = STATUS_SUCCESS; /* irp->IoStatus.Information not freed */ err_response: err_query_type: irp->IoStatus.Status = status; WvlPassIrpUp(dev_obj, irp, IO_NO_INCREMENT); return status; }
static NTSTATUS STDCALL AoeBusPnpQueryDevText_( IN WVL_SP_BUS_T bus, IN PIRP irp ) { WCHAR (*str)[512]; PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp); NTSTATUS status; UINT32 str_len; /* Allocate a string buffer. */ str = wv_mallocz(sizeof *str); if (str == NULL) { DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto alloc_str; } /* Determine the query type. */ switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) { case DeviceTextDescription: str_len = swprintf(*str, L"AoE Bus") + 1; irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str); if (irp->IoStatus.Information == 0) { DBG("wv_palloc DeviceTextDescription\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto alloc_info; } RtlCopyMemory( (PWCHAR) irp->IoStatus.Information, str, str_len * sizeof **str ); status = STATUS_SUCCESS; goto alloc_info; case DeviceTextLocationInformation: str_len = AoeBusPnpId_( NULL, BusQueryInstanceID, str ); irp->IoStatus.Information = (ULONG_PTR) wv_palloc(str_len * sizeof **str); if (irp->IoStatus.Information == 0) { DBG("wv_palloc DeviceTextLocationInformation\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto alloc_info; } RtlCopyMemory( (PWCHAR) irp->IoStatus.Information, str, str_len * sizeof **str ); status = STATUS_SUCCESS; goto alloc_info; default: irp->IoStatus.Information = 0; status = STATUS_NOT_SUPPORTED; } /* irp->IoStatus.Information not freed. */ alloc_info: wv_free(str); alloc_str: return WvlIrpComplete(irp, irp->IoStatus.Information, status); }