Hello,
Okay, this is a little bit comlicated because I have several requests and suchs, but I shortened the code to the code handling this special case. The data needed in the communication contains a header, which is 12 bytes long. It contains a field how many elements are requested and what the size of these elements is. In the test case I request a single DWORD. Therefor the number of elements is “1”, the size of the element sizeof(DWORD) (== 4).
For control purposes the driver not only returns the requested data but also returnes the received header currently.
The KdPrint command returnes a returned length of “16”. This is also returned DeviceIoControl and therefor correct.
The returned header is correct.
Code:
VOID EvtIoDeviceControl(
WDFQUEUE Queue,
WDFREQUEST Request,
size_t OutBufLen,
size_t InBufLen,
ULONG ulIoControlCode)
{
[…]
size_t FilledBuffer;
WDFMEMORY InMemory;
WDFMEMORY OutMemory;
switch(ulIoControlCode)
{
[…]
case IOCTL_WRITE_MEM_BUFFERED:
nStatus = WdfRequestRetrieveInputMemory(Request, &InMemory);
nStatus = WdfRequestRetrieveOutputMemory(Request, &OutMemory);
nStatus = HandleRequest(
ulIoControlCode,
&InMemory,
InBufLen,
&OutMemory,
OutBufLen,
pMappedResources); /* Contains the address and the size of the mapped memory*/
FilledBuffer = OutBufLen;
KdPrint((“Returned length: %d\n”, FilledBuffer));
WdfRequestSetInformation(Request, FilledBuffer);
nsStatus = STATUS_SUCCESS;
break;
[…]
}
NTSTATUS SDNHHandleRequest(
ULONG ulIoControlCode,
WDFMEMORY *pInMemory,
size_t InMemLen,
WDFMEMORY *pOutMemory,
size_t OutMemLen,
PADMINISTRATION pMappedResources)
{
NTSTATUS nRetVal = STATUS_SUCCESS;
MESSAGE_HEADER InMessageHeader;
nRetVal = WdfMemoryCopyToBuffer(*pInMemory, 0, &InMessageHeader, sizeof(MESSAGE_HEADER)) /* Size is “12”*/;
[…]
nRetVal = HandleRead(
&InMessageHeader,
pInMemory,
InMemLen,
pOutMemory,
OutMemLen,
pMappedResources);
[…]
return nRetVal;
}
NTSTATUS HandleRead(
PMESSAGE_HEADER pInMessageHeader,
WDFMEMORY *pInMemory,
size_t InMemLen,
WDFMEMORY *pOutMemory,
size_t OutMemLen,
PADMINISTRATION pMappedResources)
{
NTSTATUS nRetVal = STATUS_SUCCESS;
size_t OutMessageBufferSize = OutMemLen - sizeof(MESSAGE_HEADER);
ULONG ulOffsetInBytes = pInMessageHeader->ulElementOffset * pInMessageHeader->ulElementSize;
ULONG ulMemoryChunkSizeInBytes = pIntMessageHeader->ulElementNum * pInMessageHeader->ulElementSize;
BYTE *pbMappedMem = pMappedResources->pbMappedMemory; /* Abbreviation*/
BYTE *pbChunkAddress = NULL;
[…]
pbChunkAddress = &(pbMappedMem[ulOffsetInBytes]);
KdPrint((“Address: 0x%08X\n”, pbChunkAddress));
KdPrint((“Content: 0x%x\n”, *((DWORD *)pbChunkAddress)));
nRetVal = WdfMemoryCopyFromBuffer(
*pOutMemory,
sizeof(MESSAGE_HEADER),
pbChunkAddress,
(size_t)ulMemoryChunkSizeInBytes);
nsRetVal = WdfMemoryCopyFromBuffer(*pOutMemory, 0, pInMessageHeader, sizeof(MESSAGE_HEADER));
[…]
return nRetVal;
}