Hello All,
Following MichaelK’s advice I checked the values of pMgSettingsRequest->arBoards[0].arGlinks[0…3].hEvent
Those values are identical to the ones in the application.
The first request is IOCTL_MG_GET_INFO which handled by the “regular” handler(not pasted). It returns a number to the application.
The second request is IOCTL_MG_INIT. It’s handler calls to ObReferenceObjectByHandle.
The Main handler is:
VOID DeviceEvtIoInCallerContext(__in WDFDEVICE Device, __in WDFREQUEST Request)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION devExt = NULL;
WDF_REQUEST_PARAMETERS requestParameters;
BOOLEAN processed = FALSE;
WdfRequestGetParameters(Request, &requestParameters);
devExt = PLxGetDeviceContext(Device);
// get the request parameters
WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
WdfRequestGetParameters(Request, &requestParameters);
if (requestParameters.Type == WdfRequestTypeDeviceControl)
{
// 1. Requests that should be processed only in the context of the app's process
if (!processed)
{
processed = RequestDispatchToSequentialQueue(Device, Request, requestParameters);
}
if (!processed)
{
//KdPrint(("Forwarding to default IOCTL\n"));
status = WdfDeviceEnqueueRequest(Device, Request);
if (!NT_SUCCESS(status))
{
KdPrint(("WdfDeviceEnqueueRequest failed\n"));
}
}
}
}
All requests first go to here:
BOOLEAN
RequestDispatchToSequentialQueue(
__in WDFDEVICE Device,
__in WDFREQUEST Request,
__in WDF_REQUEST_PARAMETERS RequestParameters
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION devExt = NULL;
size_t bytesReturned = 0;
void *pInBuffer;
void *pOutBuffer;
int Channel;
size_t Length;
//-->Legacy
MG_SETTING *pMgSettingsRequest;
MG_DESCRIPTOR *pMgDescriptorReply;
//<--Legacy
ULONG IoControlCode = RequestParameters.Parameters.DeviceIoControl.IoControlCode;
devExt = PLxGetDeviceContext(Device);
switch (IoControlCode)
{
case IOCTL_MG_INIT:
status = WdfRequestRetrieveInputBuffer(Request, sizeof(MG_SETTING),
&pInBuffer, &Length);
pMgSettingsRequest = (MG_SETTING *)pInBuffer;
status = WdfRequestRetrieveOutputBuffer(Request, sizeof(MG_DESCRIPTOR),
&pOutBuffer, &Length);
pMgDescriptorReply = (MG_DESCRIPTOR *)pOutBuffer;
RtlFillMemory(devExt->KernelCommonBuffer[SHARED_BUFFER_ID], SHARED_BUFFER_SIZE, 0x0);
//Handle request
devExt->nFrequency = pMgSettingsRequest->arBoards[0].nFrequency;
devExt->nEOMode = pMgSettingsRequest->arBoards[0].nEOMode;
devExt->fSubModeEnable = pMgSettingsRequest->arBoards[0].fSubModeEnable;
devExt->fEnhancedSimplex = pMgSettingsRequest->arBoards[0].fEnhancedSimplex;
devExt->fGlinkErrorCheck = pMgSettingsRequest->arBoards[0].fGlinkErrorCheck;
devExt->fBfcuEnable = pMgSettingsRequest->arBoards[0].fBfcuEnable;
devExt->cbHeaderSize = pMgSettingsRequest->arBoards[0].cbHeaderSize;
//Handle reply
RtlZeroMemory(pMgDescriptorReply, sizeof(MG_DESCRIPTOR));
pMgDescriptorReply->nDrvVersion = 1;
pMgDescriptorReply->nNumOfBoards = 1;
pMgDescriptorReply->arBoards[0].cbGlinkDataSize = DATA_BUFFER_SIZE;
pMgDescriptorReply->arBoards[0].cbGlinkOffsetSize = HDR_BUFFER_SIZE;
pMgDescriptorReply->arBoards[0].nBoardId = 0;
pMgDescriptorReply->arBoards[0].nFPGAVersion = READ_REGISTER_ULONG((PVOID)((UINT64)devExt->Bar1Address + MODULE_NAME_OFFSET));
pMgDescriptorReply->arBoards[0].pInfo = MmMapLockedPagesSpecifyCache(devExt->CommonBufferMdl[SHARED_BUFFER_ID],
UserMode,
MmCached,
NULL,
FALSE,
NormalPagePriority);
for (Channel = 0; Channel < N_CHANNELS; Channel++)
{
pMgDescriptorReply->arBoards[0].arGlinks[Channel].pData = MmMapLockedPagesSpecifyCache(devExt->CommonBufferMdl[Channel],
UserMode,
MmCached,
NULL,
FALSE,
NormalPagePriority);
pMgDescriptorReply->arBoards[0].arGlinks[Channel].pOffset = (char*)pMgDescriptorReply->arBoards[0].arGlinks[Channel].pData + DATA_BUFFER_SIZE;
// Event
if (devExt->hEvent[Channel])
{
ObDereferenceObject(devExt->hEvent[Channel]);
devExt->hEvent[Channel] = NULL;
}
status = ObReferenceObjectByHandle(pMgSettingsRequest->arBoards[0].arGlinks[Channel].hEvent,
SYNCHRONIZE | EVENT_MODIFY_STATE,
*ExEventObjectType,
UserMode,
&devExt->hEvent[Channel],
NULL);
if (!NT_SUCCESS(status))
{
KdPrint(("ObReferenceObjectByHandle to event %d failed. status=0x%x\n", Channel, status));
}
}
bytesReturned = sizeof(MG_DESCRIPTOR);
WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, bytesReturned);
break;
default:
return FALSE; //The IOCTL code will be handled in the default IoControl handler
}
return TRUE; //This will mark the request as processed
}
Your help is highly appreciable.
Best regards,
Zvika