2016-07-27 3 views
0

J'écris actuellement un pilote qui expose les ports COM virtuels. Dans le pilote, j'envoie un IOCTL interne du port FDO vers le bas de la pile, qui est géré à partir de la file d'attente PDO IO. Pour une raison quelconque, les données de sortie ne sont pas écrites dans la mémoire de sortie fournie.IOCTL interne de WDF ne renvoyant pas la sortie

J'ai confirmé via windbg que IoCtl_Vcp_GetPortInfo (voir ci-dessous) est appelé, et fonctionne comme prévu. La requête est complétée avec STATUS_SUCCESS. Au moment où j'appelle WdfRequestComplete, le tampon de sortie a des données valides. Toutefois, lorsque le contrôle revient à GetPortInfo (voir ci-dessous), le tampon fourni n'a pas été remplacé. J'ai confirmé cela avec un point d'arrêt matériel sur l'accès pour le tampon de réception. Il n'est pas lu ou écrit pendant l'appel WdfIoTargetSendInteralIoctlSynchronously.

Le code responsable de l'envoi du IOCTL est ci-dessous:

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; 
} 

Le code qui gère l'IOCTL:

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; 
} 

La définition du code IOCTL:

#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) 

Répondre

0

Réglage de la demande informations d'achèvement avec le nombre d'octets de sortie corrige le problème.