3 things that stand out to me w/out diving deep
- do not pass WDFDEVICE*, you can just pass the WDFDEVICE by value
- You do not need to allocate the pool and then create a WDFMEMORY to wrap it. Just create the WDFMEMORY via WdfMemoryCreate and specify the size
- You do not need to reassign the buffer to the WDFMEMORY in your read completion routine
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@rediffmail.com
Sent: Friday, January 11, 2008 1:25 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Problem reading data from serial driver at kernel level
Hi,
I had made the indicated modifications. I am now allocating memory from preallocated pool and then reusing the request in the call-back functions. There is one improvement that the Write to the serial port works correctly. But the Read from the serial port is still returning me garbage data. I am attaching the code below.
This function creates request related stuff and also allocates memory.
NTSTATUS createMemHandle(IN WDFDEVICE* pDevice)
{
NTSTATUS result=STATUS_SUCCESS;
PDEVICE_EXTENSION devExtension;
WDF_OBJECT_ATTRIBUTES reqAttrib,memAttrib;
WDF_REQUEST_SEND_OPTIONS sendOptions;
int i=0;
PAGED_CODE();
devExtension = testDevGetData(*pDevice);
devExtension->pReadBuff = NULL;
devExtension->pWriteBuff = NULL;
//#ifdef SEND_READ_REQ
WDF_OBJECT_ATTRIBUTES_INIT(&reqAttrib);
reqAttrib.ParentObject = devExtension->ioTarget;
result = WdfRequestCreate(&reqAttrib,devExtension->ioTarget,&devExtension->readRequest);
devExtension->pReadBuff = ExAllocatePoolWithTag(NonPagedPool,
sizeof(readBuffer),
‘0meM’);
if (devExtension->pReadBuff == NULL)
{
KdPrint((“Error Creating Memory for Read from ExAlloc\n”));
return result;
}
WDF_OBJECT_ATTRIBUTES_INIT(&memAttrib);
memAttrib.ParentObject = devExtension->readRequest;
result = WdfMemoryCreatePreallocated( &memAttrib,
devExtension->pReadBuff,
sizeof(readBuffer),
&devExtension->readReqMem);
if (!NT_SUCCESS(result))
{
KdPrint((“Error Creating Memory for Read 0x%x\n”,result));
return result;
}
result = WdfIoTargetFormatRequestForRead(devExtension->ioTarget,
devExtension->readRequest,
devExtension->readReqMem,
NULL,
NULL);
if (!NT_SUCCESS(result))
{
KdPrint((“Error Formating Read Request 0x%x\n”,result));
return result;
}
WdfRequestSetCompletionRoutine(devExtension->readRequest,
&RemoteIoTargetRead,
devExtension);
if ( WdfRequestSend(devExtension->readRequest,
devExtension->ioTarget,
WDF_NO_SEND_OPTIONS) == FALSE) {
result = WdfRequestGetStatus(devExtension->readRequest);
KdPrint((“Error Sending Read Request 0x%x\n”,result));
return result;
}
KdPrint((“Sent Read Request\n”));
return result;
//#endif
#ifdef SEND_WRITE_REQ
WDF_OBJECT_ATTRIBUTES_INIT(&reqAttrib);
reqAttrib.ParentObject = devExtension->ioTarget;
result = WdfRequestCreate(&reqAttrib,devExtension->ioTarget,&devExtension->writeRequest);
devExtension->pWriteBuff = ExAllocatePoolWithTag(NonPagedPool,
sizeof(writeBuffer),
‘1meM’);
if (devExtension->pWriteBuff == NULL)
{
KdPrint((“Error Creating Memory for Write from ExAlloc\n”));
return result;
}
WDF_OBJECT_ATTRIBUTES_INIT(&memAttrib);
memAttrib.ParentObject = devExtension->writeRequest;
result = WdfMemoryCreatePreallocated( &memAttrib,
devExtension->pWriteBuff,
sizeof(writeBuffer),
&devExtension->writeReqMem);
if (!NT_SUCCESS(result))
{
KdPrint((“Error Creating Memory for Write 0x%x\n”,result));
return result;
}
result = RtlStringCchCopyA(devExtension->pWriteBuff,18,“This is Test Data”);
if (!NT_SUCCESS(result))
{
KdPrint((“Error copying string into the buffer\n”));
return result;
}
KdPrint((“The string in buffer is %s \n”,devExtension->pWriteBuff));
result = WdfIoTargetFormatRequestForWrite(devExtension->ioTarget,
devExtension->writeRequest,
devExtension->writeReqMem,
NULL,
NULL);
if (!NT_SUCCESS(result))
{
KdPrint((“Error Formating Write Request 0x%x\n”,result));
return result;
}
WdfRequestSetCompletionRoutine(devExtension->writeRequest,
&RemoteIoTargetWrite,
devExtension);
if ( WdfRequestSend(devExtension->writeRequest,
devExtension->ioTarget,
WDF_NO_SEND_OPTIONS) == FALSE) {
result = WdfRequestGetStatus(devExtension->writeRequest);
KdPrint((“Error Sending Write Request 0x%x\n”,result));
return result;
}
KdPrint((“Sent Write Request\n”));
return result;
#endif
}
As per the above code, the Write request produces correct output at the other end.
This is the call-back function that is getting invoked everytime the Serial port has enough data.
There is also an another issue that the Serial driver is calling this function not when it reaches the size of the buffer I allocate. For ex: in this case, i have the size of readBuffer as 25 characters and the Serial driver calls this call-back when it receives 32 characters.
VOID RemoteIoTargetRead(IN WDFREQUEST Request,
IN WDFIOTARGET Target,
IN PWDF_REQUEST_COMPLETION_PARAMS Params,
IN WDFCONTEXT Context)
{
NTSTATUS result = STATUS_SUCCESS;
PVOID buff=NULL;
PDEVICE_EXTENSION devExtension = (PDEVICE_EXTENSION)Context;
WDFMEMORY outMemory = NULL;
WDF_REQUEST_REUSE_PARAMS reuseParam;
#ifdef DEBUG
DbgBreakPoint();
#endif
if (Target != devExtension->ioTarget)
{
KdPrint((“NOT From COM PORT going to end\n”));
goto end;
}
buff = WdfMemoryGetBuffer(Params->Parameters.Read.Buffer,NULL);
if (buff != NULL)
{
KdPrint((“The data obtained is %s \n”,buff));
KdPrint((“The Length of data is %d \n”,Params->Parameters.Read.Length));
}
if (!NT_SUCCESS(Params->IoStatus.Status))
{
KdPrint((“The status of the request is 0x%x \n”,Params->IoStatus.Information));
}
WDF_REQUEST_REUSE_PARAMS_INIT(&reuseParam,
WDF_REQUEST_REUSE_NO_FLAGS,
STATUS_SUCCESS);
result = WdfRequestReuse(Request,&reuseParam);
if (!NT_SUCCESS(result))
{
KdPrint((“Request REUSE failure 0x%x \n”,result));
}
result = WdfMemoryAssignBuffer( devExtension->readReqMem,
devExtension->pReadBuff,
sizeof(readBuffer));
if (!NT_SUCCESS(result))
{
KdPrint((“Assign Buffer failure 0x%x \n”,result));
}
result = WdfIoTargetFormatRequestForRead( Target,
Request,
devExtension->readReqMem,
NULL,
NULL);
if (!NT_SUCCESS(result))
{
KdPrint((“Request FORMAT failure 0x%x \n”,result));
}
WdfRequestSetCompletionRoutine(Request,
RemoteIoTargetRead,
devExtension);
if ( WdfRequestSend(Request,
Target,
WDF_NO_SEND_OPTIONS) == FALSE)
{
result = WdfRequestGetStatus(Request);
KdPrint((“Error Sending Write Request 0x%x\n”,result));
}
end:
KdPrint((“Read Request complete\n”));
}
It will be helpful if i could get any assistance in this regard…!
reg,
Thor
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer