Ich schreibe gerade einen Treiber, der virtuelle COM-Ports verfügbar macht. Im Treiber sende ich eine interne IOCTL von dem Port FDO den Stack hinunter, der von der PDO IO-Warteschlange gehandhabt wird. Aus irgendeinem Grund werden die Ausgabedaten nicht in den bereitgestellten Ausgabespeicher geschrieben.WDF Interner IOCTL-Ausgang nicht ausgegeben
Ich habe durch windbg bestätigt, dass IoCtl_Vcp_GetPortInfo (siehe unten) aufgerufen wird und wie vorgesehen funktioniert. Die Anfrage wird mit STATUS_SUCCESS abgeschlossen. Zu dem Zeitpunkt, an dem ich WdfRequestComplete aufruft, hat der Ausgabepuffer gültige Daten. Wenn die Steuerung jedoch zu GetPortInfo zurückkehrt (siehe unten), wurde der bereitgestellte Puffer nicht überschrieben. Ich habe dies mit einem Hardware Breakpoint beim Zugriff auf den Empfangspuffer bestätigt. Während des Aufrufs WdfIoTargetSendInteralIoctlSynchronously wird nicht gelesen oder geschrieben.
Der Code für die IOCTL Senden unter:
NTSTATUS GetPortInfo(WDFDEVICE device, _Out_ PVCH_PORT_INFO port_info)
{
NTSTATUS status;
WDFIOTARGET io_target;
WDF_MEMORY_DESCRIPTOR output_descriptor;
PVOID buffer = ExAllocatePoolWithTag(NonPagedPool, sizeof(VCH_PORT_INFO), VCH_POOL_TAG);
//WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&output_descriptor, port_info, sizeof(VCH_PORT_INFO));
WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&output_descriptor, buffer, sizeof(VCH_PORT_INFO));
io_target = WdfDeviceGetIoTarget(device);
status = WdfIoTargetSendInternalIoctlSynchronously(io_target, NULL, IOCTL_VCP_INTERNAL_GET_PORT_INFO, NULL, &output_descriptor, NULL, NULL);
DbgBreakPoint();
if (!NT_SUCCESS(status))
return status;
memcpy(port_info, buffer, sizeof(VCH_PORT_INFO));
ExFreePoolWithTag(buffer, VCH_POOL_TAG);
return STATUS_SUCCESS;
}
Der Code, der die IOCTL Griffe:
NTSTATUS IoCtl_Vcp_GetPortInfo(WDFDEVICE device, WDFREQUEST request)
{
NTSTATUS status;
PVCH_PORT_INFO buffer;
PPORT_PDO_DESCRIPTOR descriptor = PortPdoGetContext(device);
status = WdfRequestRetrieveOutputBuffer(request, sizeof(VCH_PORT_INFO), (PVOID*)&buffer, NULL);
if (!NT_SUCCESS(status))
return status;
buffer->Address = descriptor->Address;
buffer->ForceComIndex = FALSE; // TODO: Implement
buffer->Writeable = descriptor->Writeable;
DbgBreakPoint();
return STATUS_SUCCESS;
}
Der IOCTL-Code Definition:
#define DEVICE_TYPE_VIRTUAL_COM_PORT 0xC51
#define IOCTL_VCP_INTERNAL_GET_PORT_INFO CTL_CODE(DEVICE_TYPE_VIRTUAL_COM_PORT, 0x30, METHOD_BUFFERED, FILE_READ_DATA)