problem in using NdisMIndicateReceivePacket in ProtocolReceive function

Hi,
I am developing an IM filter driver using NDIS5.1. In protocol receive function, when the call from NdisGetReceivedPacket returns NULL, I am allocating a packet, and copying the data to the buffer that is chained to it but when I indicate the packet using NdisMIndicateReceivePacket, I get a fatal error. Following is the code which I have written when the call from NdisGetReceivedPacket returns NULL. Could anyone please tell me where I have gone wrong. I am new to driver development, I referred some samples and wrote this but still I am not able to fix it. Any help or guidance would be highly appreciated. Thanks in advance!

PNDIS_PACKET pRcvPacket;

//
// The miniport below us uses the old-style (not packet)
// receive indication. Fall through.
//

if (HeaderBufferSize != sizeof(EthHdr))
{
Status = NDIS_STATUS_NOT_ACCEPTED;
break;
}

NdisDprAllocatePacket(&Status, &pRcvPacket, pAdapt->RecvPacketPoolHandle);

if (Status == NDIS_STATUS_SUCCESS)
{
PRECV_RSVD RecvRsvd;
PNDIS_BUFFER pRecvNdisBfr;
PUCHAR pRcvData = NULL;

NdisAllocateMemoryWithTag(&pRcvData, PacketSize + HeaderBufferSize, TAG);

NdisAllocateBuffer(&Status, &pRecvNdisBfr, pAdapt->hRecvBufferPool, pRcvData, PacketSize + HeaderBufferSize);

if (NDIS_STATUS_SUCCESS!=Status)
{
ASSERT(0);
}

NdisChainBufferAtFront(pRcvPacket, pRecvNdisBfr);

NDIS_SET_PACKET_STATUS(pRcvPacket, 0);

if (pRcvPacket == NULL)
{
if (pRcvData != NULL)
{
NdisFreeMemory(pRcvData, PacketSize + HeaderBufferSize, 0);
pRcvData = NULL;
}
if (pRecvNdisBfr != NULL)
{
NdisFreeBuffer(pRecvNdisBfr);
}
}

NdisMoveMemory(pRcvData, HeaderBuffer, HeaderBufferSize);

if (PacketSize <= LookAheadBufferSize)
{
NdisMoveMemory(pRcvData + HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);

pRcvPacket->Private.Head->Next = NULL;
pRcvPacket->Private.Tail = NULL;
RecvRsvd = (PRECV_RSVD)(pRcvPacket->MiniportReserved);
RecvRsvd->OriginalPkt = NULL;
NDIS_SET_PACKET_HEADER_SIZE(pRcvPacket, HeaderBufferSize);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &pRcvPacket, 1);

if(NDIS_GET_PACKET_STATUS(pRcvPacket) != NDIS_STATUS_PENDING)
{
NdisFreeBuffer(pRecvNdisBfr);
NdisFreeMemory(pRcvData, PacketSize + HeaderBufferSize, 0);
NdisDprFreePacket(pRcvPacket);
}
}

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.


Have you analyzed the crash dump with windbg?

Have a nice day
GV

----- Original Message -----
From: Subashini Venkatapathy ,Chennai
To: Windows System Software Devs Interest List
Sent: Tuesday, September 22, 2009 7:52 AM
Subject: [ntdev] problem in using NdisMIndicateReceivePacket in ProtocolReceive function

Hi,

I am developing an IM filter driver using NDIS5.1. In protocol receive function, when the call from NdisGetReceivedPacket returns NULL, I am allocating a packet, and copying the data to the buffer that is chained to it but when I indicate the packet using NdisMIndicateReceivePacket, I get a fatal error. Following is the code which I have written when the call from NdisGetReceivedPacket returns NULL. Could anyone please tell me where I have gone wrong. I am new to driver development, I referred some samples and wrote this but still I am not able to fix it. Any help or guidance would be highly appreciated. Thanks in advance!

PNDIS_PACKET pRcvPacket;

//

// The miniport below us uses the old-style (not packet)

// receive indication. Fall through.

//

if (HeaderBufferSize != sizeof(EthHdr))

{

Status = NDIS_STATUS_NOT_ACCEPTED;

break;

}

NdisDprAllocatePacket(&Status, &pRcvPacket, pAdapt->RecvPacketPoolHandle);

if (Status == NDIS_STATUS_SUCCESS)

{

PRECV_RSVD RecvRsvd;

PNDIS_BUFFER pRecvNdisBfr;

PUCHAR pRcvData = NULL;

NdisAllocateMemoryWithTag(&pRcvData, PacketSize + HeaderBufferSize, TAG);

NdisAllocateBuffer(&Status, &pRecvNdisBfr, pAdapt->hRecvBufferPool, pRcvData, PacketSize + HeaderBufferSize);

if (NDIS_STATUS_SUCCESS!=Status)

{

ASSERT(0);

}

NdisChainBufferAtFront(pRcvPacket, pRecvNdisBfr);

NDIS_SET_PACKET_STATUS(pRcvPacket, 0);

if (pRcvPacket == NULL)

{

if (pRcvData != NULL)

{

NdisFreeMemory(pRcvData, PacketSize + HeaderBufferSize, 0);

pRcvData = NULL;

}

if (pRecvNdisBfr != NULL)

{

NdisFreeBuffer(pRecvNdisBfr);

}

}

NdisMoveMemory(pRcvData, HeaderBuffer, HeaderBufferSize);

if (PacketSize <= LookAheadBufferSize)

{

NdisMoveMemory(pRcvData + HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);

pRcvPacket->Private.Head->Next = NULL;

pRcvPacket->Private.Tail = NULL;

RecvRsvd = (PRECV_RSVD)(pRcvPacket->MiniportReserved);

RecvRsvd->OriginalPkt = NULL;

NDIS_SET_PACKET_HEADER_SIZE(pRcvPacket, HeaderBufferSize);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &pRcvPacket, 1);

if(NDIS_GET_PACKET_STATUS(pRcvPacket) != NDIS_STATUS_PENDING)

{

NdisFreeBuffer(pRecvNdisBfr);

NdisFreeMemory(pRcvData, PacketSize + HeaderBufferSize, 0);

NdisDprFreePacket(pRcvPacket);

}

}

With Regards,

Subashini


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
OSR Seminars – OSR

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum 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.


Are you using a debugger? If so, you should be able to step through this
code and find the problem. If you are not using a debugger then expect to
fail.

What is the "fatal error"?

Have you modified your MiniportReturnPacket handler to distinguish between
your own indications and passthrough indications? When MiniportReturnPacket
is called you should call NdisReturnPackets if the packet is a passthrough
packet. If the packet is one that you actually allocated in your
ProtocolReceive handler, then you MUST NOT call NdisReturnPackets; Instead,
you should free the resources that you allocated yourself.

You should check for success of NdisAllocateMemoryWithTag before calling
NdisAllocateBuffer.

What do you do if LookAheadBufferSize < PacketSize?

Good luck!

Thomas

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Subashini
Venkatapathy ,Chennai
Sent: Tuesday, September 22, 2009 10:52 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] problem in using NdisMIndicateReceivePacket in
ProtocolReceive function

Hi,

I am developing an IM filter driver using NDIS5.1. In protocol receive
function, when the call from NdisGetReceivedPacket returns NULL, I am
allocating a packet, and copying the data to the buffer that is chained to
it but when I indicate the packet using NdisMIndicateReceivePacket, I get a
fatal error. Following is the code which I have written when the call from
NdisGetReceivedPacket returns NULL. Could anyone please tell me where I have
gone wrong. I am new to driver development, I referred some samples and
wrote this but still I am not able to fix it. Any help or guidance would be
highly appreciated. Thanks in advance!

PNDIS_PACKET pRcvPacket;

//

// The miniport below us uses the old-style (not packet)

// receive indication. Fall through.

//

if (HeaderBufferSize != sizeof(EthHdr))

{

Status = NDIS_STATUS_NOT_ACCEPTED;

break;

}

NdisDprAllocatePacket(&Status, &pRcvPacket,
pAdapt->RecvPacketPoolHandle);

if (Status == NDIS_STATUS_SUCCESS)

{

PRECV_RSVD RecvRsvd;

PNDIS_BUFFER pRecvNdisBfr;

PUCHAR pRcvData = NULL;

NdisAllocateMemoryWithTag(&pRcvData, PacketSize +
HeaderBufferSize, TAG);

NdisAllocateBuffer(&Status, &pRecvNdisBfr,
pAdapt->hRecvBufferPool, pRcvData, PacketSize + HeaderBufferSize);

if (NDIS_STATUS_SUCCESS!=Status)

{

ASSERT(0);

}

NdisChainBufferAtFront(pRcvPacket, pRecvNdisBfr);

NDIS_SET_PACKET_STATUS(pRcvPacket, 0);

if (pRcvPacket == NULL)

{

if (pRcvData != NULL)

{

NdisFreeMemory(pRcvData,
PacketSize + HeaderBufferSize, 0);

pRcvData = NULL;

}

if (pRecvNdisBfr != NULL)

{

NdisFreeBuffer(pRecvNdisBfr);

}

}

NdisMoveMemory(pRcvData, HeaderBuffer,
HeaderBufferSize);

if (PacketSize <= LookAheadBufferSize)

{

NdisMoveMemory(pRcvData +
HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);

pRcvPacket->Private.Head->Next = NULL;

pRcvPacket->Private.Tail = NULL;

RecvRsvd =
(PRECV_RSVD)(pRcvPacket->MiniportReserved);

RecvRsvd->OriginalPkt = NULL;

NDIS_SET_PACKET_HEADER_SIZE(pRcvPacket,
HeaderBufferSize);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &pRcvPacket, 1);

if(NDIS_GET_PACKET_STATUS(pRcvPacket)
!= NDIS_STATUS_PENDING)

{

NdisFreeBuffer(pRecvNdisBfr);

NdisFreeMemory(pRcvData,
PacketSize + HeaderBufferSize, 0);

NdisDprFreePacket(pRcvPacket);

}

}

With Regards,

Subashini


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:

To unsubscribe, visit the List Server section of OSR Online at

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.



> If you are not using a debugger then expect to fail.

Well, in this particular case Linus’s famous “real programmers don’t need debuggers” holds true. All you have to do is take a brief look at the code, and you will immediately notice the following “masterpiece”

NdisChainBufferAtFront(pRcvPacket, pRecvNdisBfr);
NDIS_SET_PACKET_STATUS(pRcvPacket, 0);
if (pRcvPacket == NULL) {…

Therefore, the OP first actually uses a pointer, and then checks whether it is valid. …

This is the very first thing that one notices, although there may be some other bugs as well (his code
is not that easily readable)…

Anton Bassov

I noticed that too, and I believe that I mentioned that he should check it.

OTOH, it’s not likely that the allocate failed. The crash is probably in the
Realtek miniport when he returns the packet that he allocated to a driver
that isn’t expecting it (or may not have a functional MiniportReturnPacket
handler that works at all since it isn’t indicating packets…).

Of course, some versions of the Realtek driver indicate partial packets -
requiring a call to NdisTransferData. Wonder if he is lucky enough to have
that one? By lucky I mean that it is a behavior that needs to be
accommodated and few adapters these days actually have this bad behavior.

Of course, some day he may get a different adapter that calls
ProtocolReceivePacket. Or: Surprise, NdisGetReceivePacket actually returns
non-NULL.

We’ll be hearing from this poster for a long time. Wish him luck!

Thomas

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Tuesday, September 22, 2009 11:43 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] problem in using NdisMIndicateReceivePacket in
ProtocolReceive function

If you are not using a debugger then expect to fail.

Well, in this particular case Linus’s famous “real programmers don’t need
debuggers” holds true. All you have to do is take a brief look at the code,
and you will immediately notice the following “masterpiece”

NdisChainBufferAtFront(pRcvPacket, pRecvNdisBfr);
NDIS_SET_PACKET_STATUS(pRcvPacket, 0);
if (pRcvPacket == NULL) {…

Therefore, the OP first actually uses a pointer, and then checks whether it
is valid. …

This is the very first thing that one notices, although there may be some
other bugs as well (his code
is not that easily readable)…

Anton Bassov


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

> I noticed that too, and I believe that I mentioned that he should check it.

…oops… now I see what you were speaking about, but this is already another bug of exactly the same nature (actually, I did not even notice that one) - you were speaking about packet data, while I was speaking about packet descriptor. Therefore, we noticed two different bugs. What neither of us noticed is that in addition to packet data and descriptor, the same applies to buffer descriptor - the OP does not seem to validate descriptor returned by NdisAllocateBuffer() either.

To summarize, up to this point we have noticed already three potential bugs, and we are speaking about just a dozen of lines of code. Not so bad ratio, don’t you think…

OTOH, it’s not likely that the allocate failed.

WEll, this is just an indication of his coding style…

The crash is probably in the Realtek miniport > when he returns the packet that
he allocated to a driver that isn’t expecting it

Well, this is already another level of bug - what we’ve seen in so far are just “technical” bugs, but this is already an “architectural” one. Certainly, we cannot make any definitive statements without actually seeing his code, but judging from what we’ve seen in so far, I am almost sure that his MPReturnPacket() does not make any distinction between packets that he had allocated himself and the ones that he had received from underlying miniport - I bet he passes everything through…

We’ll be hearing from this poster for a long time.

Yes, it seems to be more than likely to happen this way. Furthermore, I think he is quite likely to get “offended” when we tell him to fix his coding style, look at samples, read documentation,etc…

Anton Bassov

Hello,
As all of you have pointed out i did not handle it in MiniportReturnPacket handler. Thank you so much for your guidance. I fixed it and now it is working fine. Thanks!

With Regards,
Subashini V

> i did not handle it in MiniportReturnPacket handler. Thank you so much for your guidance.

I fixed it and now it is working fine. Thanks!

Just make sure that your handler makes a distinction between packets that you have allocated and the ones you have received from MP in PtReceivePacket() - packet of both of types are going to be returned to your MiniportReturnPacket handler. Therefore, if you don’t make any distinction between them your driver will fail with adapter that relies upon packet-based indications. Alternatively, you can set NDIS_STATUS_RESOURCES before indicating a packet that you have allocated yourself. If you do it this way you will be able to release a packet right after having indicated it.

In any case, fix pointer-related bugs that we have pointed out - otherwise you driver will fail sooner or later, even if it works fine in 99.9% of cases…

Anton Bassov

Ya sure I will do that. Thank you so much for all your guidance.
It was of great help to me. Thanks!

With Regards,
Subashini

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.com
Sent: Wednesday, September 23, 2009 2:58 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] problem in using NdisMIndicateReceivePacket in ProtocolReceive function

i did not handle it in MiniportReturnPacket handler. Thank you so much for your guidance.
I fixed it and now it is working fine. Thanks!

Just make sure that your handler makes a distinction between packets that you have allocated and the ones you have received from MP in PtReceivePacket() - packet of both of types are going to be returned to your MiniportReturnPacket handler. Therefore, if you don't make any distinction between them your driver will fail with adapter that relies upon packet-based indications. Alternatively, you can set NDIS_STATUS_RESOURCES before indicating a packet that you have allocated yourself. If you do it this way you will be able to release a packet right after having indicated it.

In any case, fix pointer-related bugs that we have pointed out - otherwise you driver will fail sooner or later, even if it works fine in 99.9% of cases....

Anton Bassov


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:

To unsubscribe, visit the List Server section of OSR Online at ListServer/Forum

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.


One additional thought:

In this specific case (ProtocolReceive called with no packet…) there is
really no need to actually create a new packet in its entirety. Instead,
just allocate the flat buffer, copy HeaderBuffer and LookAheadBuffer to it.
Make changes to your flat buffer copy and then call NdisMEthIndicateReceive.

Of course, this won’t work if LookAheadBufferSize < PacketSize.

Thomas

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hcl.in
Sent: Wednesday, September 23, 2009 3:37 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] problem in using NdisMIndicateReceivePacket in
ProtocolReceive function

Hello,
As all of you have pointed out i did not handle it in MiniportReturnPacket
handler. Thank you so much for your guidance. I fixed it and now it is
working fine. Thanks!

With Regards,
Subashini V


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