Re: NDISUIO problem, can't retrieve NDIS packets by Tom
Tom
Fri Sep 05 02:21:01 CDT 2003
This is the code directly from the NDISUIO sample:
The only thing I added where a few simple DEBUGP statements.
------------------------------------------------------------
VOID
ndisuioServiceReads(
IN PNDISUIO_OPEN_CONTEXT pOpenContext
)
/*++
Routine Description:
Utility routine to copy received data into user buffers and
complete READ IRPs.
Arguments:
pOpenContext - pointer to open context
Return Value:
None
--*/
{
PIRP pIrp;
PLIST_ENTRY pIrpEntry;
PNDIS_PACKET pRcvPacket;
PLIST_ENTRY pRcvPacketEntry;
PUCHAR pSrc, pDst;
ULONG BytesRemaining; // at pDst
PNDIS_BUFFER pNdisBuffer;
ULONG BytesAvailable;
DEBUGP(DL_VERY_LOUD, ("ServiceReads: open %p/%x\n",
pOpenContext, pOpenContext->Flags));
NUIO_REF_OPEN(pOpenContext); // temp ref - service reads
DEBUGP(DL_INFO, ("ServiceReads: openened context\r\n") );
NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
if( NUIO_IS_LIST_EMPTY(&pOpenContext->PendedReads) )
DEBUGP(DL_INFO, ("ServiceReads: PendedReads empty\r\n"));
if( NUIO_IS_LIST_EMPTY(&pOpenContext->RecvPktQueue) )
DEBUGP(DL_INFO, ("ServiceReads: RecvPktQueue empty\r\n") );
while (!NUIO_IS_LIST_EMPTY(&pOpenContext->PendedReads) &&
!NUIO_IS_LIST_EMPTY(&pOpenContext->RecvPktQueue))
{
DEBUGP(DL_INFO, ("ServiceReads: entering while loop\r\n") );
//
// Get the first pended Read IRP
//
pIrpEntry = pOpenContext->PendedReads.Flink;
pIrp = CONTAINING_RECORD(pIrpEntry, IRP, Tail.Overlay.ListEntry);
//
// Check to see if it is being cancelled.
//
if (IoSetCancelRoutine(pIrp, NULL))
{
//
// It isn't being cancelled, and can't be cancelled henceforth.
//
NUIO_REMOVE_ENTRY_LIST(pIrpEntry);
//
// NOTE: we decrement PendedReadCount way below in the
// while loop, to avoid letting through a thread trying
// to unbind.
//
}
else
{
//
// The IRP is being cancelled; let the cancel routine handle it.
//
DEBUGP(DL_INFO, ("ServiceReads: open %p, skipping cancelled IRP %p\n",
pOpenContext, pIrp));
continue;
}
DEBUGP(DL_VERY_LOUD, ("ServiceReads: retrieving packet\r\n") );
//
// Get the first queued receive packet
//
pRcvPacketEntry = pOpenContext->RecvPktQueue.Flink;
NUIO_REMOVE_ENTRY_LIST(pRcvPacketEntry);
pOpenContext->RecvPktCount --;
NUIO_RELEASE_LOCK(&pOpenContext->Lock);
NUIO_DEREF_OPEN(pOpenContext); // Service: dequeue rcv packet
pRcvPacket = NUIO_LIST_ENTRY_TO_RCV_PKT(pRcvPacketEntry);
//
// Copy as much data as possible from the receive packet to
// the IRP MDL.
//
#ifndef WIN9X
pDst = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);
NUIO_ASSERT(pDst != NULL); // since it was already mapped
#else
pDst = MmGetSystemAddressForMdl(pIrp->MdlAddress); // Win9x
#endif
BytesRemaining = MmGetMdlByteCount(pIrp->MdlAddress);
DEBUGP(DL_VERY_LOUD, ("BytesRemaining: %ld\r\n", BytesRemaining));
pNdisBuffer = pRcvPacket->Private.Head;
while (BytesRemaining && (pNdisBuffer != NULL))
{
#ifndef WIN9X
NdisQueryBufferSafe(pNdisBuffer, &pSrc, &BytesAvailable,
NormalPagePriority);
if (pSrc == NULL)
{
DEBUGP(DL_FATAL,
("ServiceReads: Open %p, QueryBuffer failed for buffer %p\n",
pOpenContext, pNdisBuffer));
break;
}
#else
NdisQueryBuffer(pNdisBuffer, &pSrc, &BytesAvailable);
#endif
if (BytesAvailable)
{
ULONG BytesToCopy = MIN(BytesAvailable, BytesRemaining);
NUIO_COPY_MEM(pDst, pSrc, BytesToCopy);
BytesRemaining -= BytesToCopy;
pDst += BytesToCopy;
}
NdisGetNextBuffer(pNdisBuffer, &pNdisBuffer);
}
//
// If I dump the buffer that is being returned using the IRP here it is
// full of AFAFAFAFAFAFAFAFA
// I assume i can dump the pDst =
MmGetSystemAddressForMdl(pIrp->MdlAddress)???
//
DEBUGP(DL_VERY_LOUD, ("ServiceReads: completing IRP\r\n"));
//
// Complete the IRP.
//
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = MmGetMdlByteCount(pIrp->MdlAddress) -
BytesRemaining;
DEBUGP(DL_INFO, ("ServiceReads: Open %p, IRP %p completed with %d bytes\n",
pOpenContext, pIrp, pIrp->IoStatus.Information));
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
//
// Free up the receive packet - back to the miniport if it
// belongs to it, else reclaim it (local copy).
//
if (NdisGetPoolFromPacket(pRcvPacket) != pOpenContext->RecvPacketPool)
{
NdisReturnPackets(&pRcvPacket, 1);
}
else
{
ndisuioFreeReceivePacket(pOpenContext, pRcvPacket);
}
NUIO_DEREF_OPEN(pOpenContext); // took out pended Read
NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
pOpenContext->PendedReadCount--;
}
NUIO_RELEASE_LOCK(&pOpenContext->Lock);
NUIO_DEREF_OPEN(pOpenContext); // temp ref - service reads
DEBUGP(DL_VERY_LOUD, ("ServiceReads returning\n" ));
}
------------------------------------
""Bryan S. Burgin [MSFT]"" <bburgin@online.microsoft.com> wrote in message
news:HrQIY8ycDHA.2252@cpmsftngxa06.phx.gbl...
>
>
> Ummm, should be okay. I ported this over several years ago and don't
> recall running into this. Like you, I used:
>
> C_DEFINES=$(C_DEFINES) -DWIN9X -DNDIS50=1 -DNDIS_WDM=1
> -DBINARY_COMPATIBLE
>
> I wonder what dropping -DNDIS_WDM=1 would do? I see several places in
> ndis.h where there are #if statements like:
>
> #if (BINARY_COMPATIBLE && !NDIS_WDM) hat looks like in _some_ cases
> these flags are mutually exclusive.
>
> Perhaps you could post the fragment of your code that is receiving and
> decoding the packet.
>
> Are you able to send packets on the wire, verified by sniffing the wire?
> That would verify that your handling of the packet structures is okay and
> that it's an issue of receiving or transfering the payload to your
handler.
>
> Bryan S. Burgin
> bburgin@microsoft.com
>
> This posting is provided "AS IS" with no warranties, and confers no
rights.
>
>
>
>
>