reg. changing MTU using OID_GEN_MAXIMUM_FRAME_SIZE and OID_GEN_MAXIMUM_TOTAL_SIZE

Hello,
I am developing NDIS IM driver on windows XP. I need to add one byte of data in IM (passthru) driver. So i tried to modify the MTU using OID_GEN_MAXIMUM_FRAME_SIZE and OID_GEN_MAXIMUM_TOTAL_SIZE in ‘MPQueryInformation’ function but the MTU does not change and i am getting “PSCHED: Requery FRAME_SIZE” error. Could anyone please tell what this means and how to resolve it.

Following is the code i wrote to modify the MTU.

NDIS_STATUS

MPQueryInformation(

IN NDIS_HANDLE MiniportAdapterContext,

IN NDIS_OID Oid,

IN PVOID InformationBuffer,

IN ULONG InformationBufferLength,

OUT PULONG BytesWritten,

OUT PULONG BytesNeeded

)

{

PADAPT pAdapt = (PADAPT)MiniportAdapterContext;

NDIS_STATUS Status = NDIS_STATUS_FAILURE;

ULONG ulInfo = 0;

PVOID pInfo = (PVOID) &ulInfo;

ULONG ulInfoLen = sizeof(ulInfo);

ULONG ulBytesAvailable = ulInfoLen;

BOOLEAN bForwardRequest = TRUE;

switch(Oid)

{

case OID_GEN_SUPPORTED_LIST:

pInfo = (PVOID) AFDXSupportedOids;

ulBytesAvailable = ulInfoLen = sizeof(AFDXSupportedOids);

break;

case OID_PNP_QUERY_POWER:

//

// Do not forward this.

//

Status = NDIS_STATUS_SUCCESS;

break;

case OID_GEN_SUPPORTED_GUIDS:

//

// Do not forward this, otherwise we will end up with multiple

// instances of private GUIDs that the underlying miniport

// supports.

//

Status = NDIS_STATUS_NOT_SUPPORTED;

break;

case OID_GEN_MAXIMUM_FRAME_SIZE:

ulInfo = ETH_MAX_PACKET_SIZE - ETH_HEADER_SIZE - 1; //-1 for AFDX seq no.

bForwardRequest = FALSE;

break;

case OID_GEN_MAXIMUM_TOTAL_SIZE:

ulInfo = ETH_MAX_PACKET_SIZE - 1; //-1 for AFDX seq no.

bForwardRequest = FALSE;

break;

default:

break;

}

if (bForwardRequest == FALSE)

{

if (Status == NDIS_STATUS_SUCCESS)

{

if (ulInfoLen <= InformationBufferLength)

{

// Copy result into InformationBuffer

*BytesWritten = ulInfoLen;

if(ulInfoLen)

{

NdisMoveMemory(InformationBuffer, pInfo, ulInfoLen);

}

}

else

{

// too short

*BytesNeeded = ulInfoLen;

Status = NDIS_STATUS_BUFFER_TOO_SHORT;

}

}

}

else

{

//

// If the miniport below is unbinding, just fail any request

//

NdisAcquireSpinLock(&pAdapt->Lock);

if (pAdapt->UnbindingInProcess == TRUE)

{

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_FAILURE;

}

NdisReleaseSpinLock(&pAdapt->Lock);

//

// All other queries are failed, if the miniport is not at D0,

//

if (pAdapt->MPDeviceState > NdisDeviceStateD0)

{

Status = NDIS_STATUS_FAILURE;

}

pAdapt->Request.RequestType = NdisRequestQueryInformation;

pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;

pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;

pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;

pAdapt->BytesNeeded = BytesNeeded;

pAdapt->BytesReadOrWritten = BytesWritten;

//

// If the miniport below is binding, fail the request

//

NdisAcquireSpinLock(&pAdapt->Lock);

if (pAdapt->UnbindingInProcess == TRUE)

{

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_FAILURE;

}

//

// If the Protocol device state is OFF, mark this request as being

// pended. We queue this until the device state is back to D0.

//

if ((pAdapt->PTDeviceState > NdisDeviceStateD0)

&& (pAdapt->StandingBy == FALSE))

{

pAdapt->QueuedRequest = TRUE;

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_PENDING;

}

//

// This is in the process of powering down the system, always fail the request

//

if (pAdapt->StandingBy == TRUE)

{

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_FAILURE;

}

pAdapt->OutstandingRequests = TRUE;

NdisReleaseSpinLock(&pAdapt->Lock);

//

// default case, most requests will be passed to the miniport below

//

NdisRequest(&Status,

pAdapt->BindingHandle,

&pAdapt->Request);

if (Status != NDIS_STATUS_PENDING)

{

PtRequestComplete(pAdapt, &pAdapt->Request, Status);

Status = NDIS_STATUS_PENDING;

}

}

return(Status);

}

I am new to driver development. Any help would be highly appreciated. Thanks!

With Regards,
Subashini


::DISCLAIMER::

The contents of this e-mail and any attachment(s) are confidential and intended for the named recipient(s) only.
It shall not attach any liability on the originator or HCL or its affiliates. Any views or opinions presented in
this email are solely those of the author and may not necessarily reflect the opinions of HCL or its affiliates.
Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of
this message without the prior written consent of the author of this e-mail is strictly prohibited. If you have
received this email in error please delete it and notify the sender immediately. Before opening any mail and
attachments please check them for viruses and defect.


When modifying a query result I normally make changes in the request complete handler (“on the way up”). If the query has completed successfully you will know the actual frame and total sizes that the lower-level miniport supports. You can save these real values for your own use and then modify them by subtracting your extra byte.

If you modify in the query information handler (“on the way down”) then you don’t actually know the frame and total sizes of the lower-level adapter.

In any case, if you make mods in the query information handler just think of it as a simple function. When you make modifications, fill in the information buffer and bytes written and return status. This is illustrated below.

I recommend making your changes in the request complete handler.

You need to also read the docs for OID_GEN_MAXIMUM_TOTAL_SIZE paying attention to the packet priority requirements.

In any case you can verify that your modification works using NDIScope from http://pcausa.com/Utilities/ndistools.htm.

Even when done properly you may be given some packets that are too large. Try just dropping oversize packets and see if system adjusts. In worst case - fragment the packets yourself.

Dave will probably have better information to give you when he gets a chance.

Thomas F. Divine
http://www.pcausa.com

NDIS_STATUS

MPQueryInformation(

IN NDIS_HANDLE MiniportAdapterContext,

IN NDIS_OID Oid,

IN PVOID InformationBuffer,

IN ULONG InformationBufferLength,

OUT PULONG BytesWritten,

OUT PULONG BytesNeeded

)

{

// For Queries Answered From Here…

{

// Checks for size, etc.

// Fill in Information Buffer

// Fill in Bytes Written

return STATUS_SUCCESS;

}

// Query Passthru To Lower Levels

}

From: Subashini Venkatapathy - ERS, HCL Tech
Sent: Tuesday, December 28, 2010 12:11 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] reg. changing MTU using OID_GEN_MAXIMUM_FRAME_SIZE and OID_GEN_MAXIMUM_TOTAL_SIZE

Hello,

I am developing NDIS IM driver on windows XP. I need to add one byte of data in IM (passthru) driver. So i tried to modify the MTU using OID_GEN_MAXIMUM_FRAME_SIZE and OID_GEN_MAXIMUM_TOTAL_SIZE in ‘MPQueryInformation’ function but the MTU does not change and i am getting “PSCHED: Requery FRAME_SIZE” error. Could anyone please tell what this means and how to resolve it.

Following is the code i wrote to modify the MTU.

NDIS_STATUS

MPQueryInformation(

IN NDIS_HANDLE MiniportAdapterContext,

IN NDIS_OID Oid,

IN PVOID InformationBuffer,

IN ULONG InformationBufferLength,

OUT PULONG BytesWritten,

OUT PULONG BytesNeeded

)

{

PADAPT pAdapt = (PADAPT)MiniportAdapterContext;

NDIS_STATUS Status = NDIS_STATUS_FAILURE;

ULONG ulInfo = 0;

PVOID pInfo = (PVOID) &ulInfo;

ULONG ulInfoLen = sizeof(ulInfo);

ULONG ulBytesAvailable = ulInfoLen;

BOOLEAN bForwardRequest = TRUE;

switch(Oid)

{

case OID_GEN_SUPPORTED_LIST:

pInfo = (PVOID) AFDXSupportedOids;

ulBytesAvailable = ulInfoLen = sizeof(AFDXSupportedOids);

break;

case OID_PNP_QUERY_POWER:

//

// Do not forward this.

//

Status = NDIS_STATUS_SUCCESS;

break;

case OID_GEN_SUPPORTED_GUIDS:

//

// Do not forward this, otherwise we will end up with multiple

// instances of private GUIDs that the underlying miniport

// supports.

//

Status = NDIS_STATUS_NOT_SUPPORTED;

break;

case OID_GEN_MAXIMUM_FRAME_SIZE:

ulInfo = ETH_MAX_PACKET_SIZE - ETH_HEADER_SIZE - 1; //-1 for AFDX seq no.

bForwardRequest = FALSE;

break;

case OID_GEN_MAXIMUM_TOTAL_SIZE:

ulInfo = ETH_MAX_PACKET_SIZE - 1; //-1 for AFDX seq no.

bForwardRequest = FALSE;

break;

default:

break;

}

if (bForwardRequest == FALSE)

{

if (Status == NDIS_STATUS_SUCCESS)

{

if (ulInfoLen <= InformationBufferLength)

{

// Copy result into InformationBuffer

*BytesWritten = ulInfoLen;

if(ulInfoLen)

{

NdisMoveMemory(InformationBuffer, pInfo, ulInfoLen);

}

}

else

{

// too short

*BytesNeeded = ulInfoLen;

Status = NDIS_STATUS_BUFFER_TOO_SHORT;

}

}

}

else

{

//

// If the miniport below is unbinding, just fail any request

//

NdisAcquireSpinLock(&pAdapt->Lock);

if (pAdapt->UnbindingInProcess == TRUE)

{

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_FAILURE;

}

NdisReleaseSpinLock(&pAdapt->Lock);

//

// All other queries are failed, if the miniport is not at D0,

//

if (pAdapt->MPDeviceState > NdisDeviceStateD0)

{

Status = NDIS_STATUS_FAILURE;

}

pAdapt->Request.RequestType = NdisRequestQueryInformation;

pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;

pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;

pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;

pAdapt->BytesNeeded = BytesNeeded;

pAdapt->BytesReadOrWritten = BytesWritten;

//

// If the miniport below is binding, fail the request

//

NdisAcquireSpinLock(&pAdapt->Lock);

if (pAdapt->UnbindingInProcess == TRUE)

{

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_FAILURE;

}

//

// If the Protocol device state is OFF, mark this request as being

// pended. We queue this until the device state is back to D0.

//

if ((pAdapt->PTDeviceState > NdisDeviceStateD0)

&& (pAdapt->StandingBy == FALSE))

{

pAdapt->QueuedRequest = TRUE;

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_PENDING;

}

//

// This is in the process of powering down the system, always fail the request

//

if (pAdapt->StandingBy == TRUE)

{

NdisReleaseSpinLock(&pAdapt->Lock);

Status = NDIS_STATUS_FAILURE;

}

pAdapt->OutstandingRequests = TRUE;

NdisReleaseSpinLock(&pAdapt->Lock);

//

// default case, most requests will be passed to the miniport below

//

NdisRequest(&Status,

pAdapt->BindingHandle,

&pAdapt->Request);

if (Status != NDIS_STATUS_PENDING)

{

PtRequestComplete(pAdapt, &pAdapt->Request, Status);

Status = NDIS_STATUS_PENDING;

}

}

return(Status);

}

I am new to driver development. Any help would be highly appreciated. Thanks!

With Regards,

Subashini


::DISCLAIMER::

The contents of this e-mail and any attachment(s) are confidential and intended for the named recipient(s) only.
It shall not attach any liability on the originator or HCL or its affiliates. Any views or opinions presented in
this email are solely those of the author and may not necessarily reflect the opinions of HCL or its affiliates.
Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of
this message without the prior written consent of the author of this e-mail is strictly prohibited. If you have
received this email in error please delete it and notify the sender immediately. Before opening any mail and
attachments please check them for viruses and defect.



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

> Dave will probably have better information to give you when he gets a
chance.

Not likely J I spend as much time reading ndis.com and pcausa.com as the
next guy. Thanks Thomas for making life in NDIS just a little bit nicer.

I will ask, however, why you feel it necessary to tell TCPIP.SYS (or any
other network element bound above your IM driver) that the MTU is different?
Are you trying to ?shrink? the reported MTY by one octet so that you can be
assured of putting your one octet into the frame (at the end I assume)?

Thomas has explained the most important part of modifying the responses to
the OID_GEN_MAXIMUM_XXX_SIZE queries (do it on the completion and pay
attention to the interaction between the values reported).

But what is missing from your original post is a better explanation of
exactly what you mean by ?add one byte?. Would that be in the transmit
path? The receive path? Do you ever ?remove one byte? to compensate?

Also, where is your IM driver bound (what altitude) relative to PSCHED and
other IM drivers? Does it matter (I suppose it probably does if you modify
the network frame in some non-standard way)?

Good Luck,

Dave Cattley

Hello,
Thanks for your response and sorry for my delayed reply.

I will be adding one octet in the transmit path and removing it in the receive path. I am trying to shrink the reported MTU by one octet to assure adding one octet into the frame at the transmit path.

I have only one IM driver. I dont know how it is related to PSCHED?

Should i modify the MTU in the ptreceivecomplete function? Please conform.

Thanks,
Subashini