Windows Vista Tips

Windows Vista Tips > Newsgroups > Windows Vista Drivers > NDIS IM - problems with NdisSend

Reply
Thread Tools Display Modes

NDIS IM - problems with NdisSend

 
 
arek.ploski@gmail.com
Guest
Posts: n/a

 
      07-23-2006
Hi,
I am developing application to encypt / decrypt TCP/IP packets data. I
know that the fastest way is to change date in a driver, but one of the
requirements is to make it possible to change cryptographic algorithm
in an easy way. I decided to change PassThru driver extended by Thomas
F. Divine (part 2 of his article) and I pass interesting packets to my
application and block them in the driver. Then I want to change the
data there and resend packets as a new ones (from a driver's point of
view). And here is my problem. When I create a new NDIS_PACKET and try
to send it with NdisSend (or even NdisSendPackets, as in NDISPROT DDK
example) I've got bluescreen. Here is a piece of my code (without any
debug and other additional lines), please tell me where is my
misunderstanding of this subject.

FltDevIoControl(){
(...)
PNDIS_PACKET pNdisPacket;
PNDIS_BUFFER pNdisBuffer;
(...)
ioBuffer = pIrp->AssociatedIrp.SystemBuffer;
inputBufferLength =
pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
(...)
case MY_IOCTL_CODE:

pNdisPacket = NULL;
pNdisBuffer = NULL;

NdisAcquireSpinLock(&(pFilterContext->PacketListSpinLock));
NdisAllocatePacket(&Status, &pNdisPacket,
pAdapt->SendPacketPoolHandle);
NdisAllocateBuffer(&Status, &pNdisBuffer,
pAdapt->SendBufferPoolHandle, ioBuffer, inputBufferLength );
NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
NdisSend(&Status, pAdapt->BindingHandle, pNdisPacket );
if (Status != NDIS_STATUS_PENDING){
NdisFreeBuffer(pNdisBuffer);
NdisFreePacket(pNdisPacket);
}
NdisReleaseSpinLock(&(pFilterContext->PacketListSpinLock));
break;
}

It seems to me that there is nothing to go wrong. Maybe I can't see
some important issues. Thank you for any advice in advance.
Arek

 
Reply With Quote
 
 
 
 
Thomas F. Divine [DDK MVP]
Guest
Posts: n/a

 
      07-23-2006
Arek,

If you are writing a device driver, saying "I've got a bluescreen" is
unacceptable. You must have a debugger attached then you will know more
about the crash.

In code below, don't hold spinlock while calling NdisSend.

What happens if NdisSend returns STATUS_PENDING? Will the data from
user-mode go away while NDIS is using it?

Do you understand that ProtocolSendComplete will be called eventually? Do
you realize that ProtocolSendComplete must do somethings differently for
packets that you send this way?

Please use a debugger.

Thomas F. Divine

<> wrote in message
news: oups.com...
> Hi,
> I am developing application to encypt / decrypt TCP/IP packets data. I
> know that the fastest way is to change date in a driver, but one of the
> requirements is to make it possible to change cryptographic algorithm
> in an easy way. I decided to change PassThru driver extended by Thomas
> F. Divine (part 2 of his article) and I pass interesting packets to my
> application and block them in the driver. Then I want to change the
> data there and resend packets as a new ones (from a driver's point of
> view). And here is my problem. When I create a new NDIS_PACKET and try
> to send it with NdisSend (or even NdisSendPackets, as in NDISPROT DDK
> example) I've got bluescreen. Here is a piece of my code (without any
> debug and other additional lines), please tell me where is my
> misunderstanding of this subject.
>
> FltDevIoControl(){
> (...)
> PNDIS_PACKET pNdisPacket;
> PNDIS_BUFFER pNdisBuffer;
> (...)
> ioBuffer = pIrp->AssociatedIrp.SystemBuffer;
> inputBufferLength =
> pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
> (...)
> case MY_IOCTL_CODE:
>
> pNdisPacket = NULL;
> pNdisBuffer = NULL;
>
> NdisAcquireSpinLock(&(pFilterContext->PacketListSpinLock));
> NdisAllocatePacket(&Status, &pNdisPacket,
> pAdapt->SendPacketPoolHandle);
> NdisAllocateBuffer(&Status, &pNdisBuffer,
> pAdapt->SendBufferPoolHandle, ioBuffer, inputBufferLength );
> NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
> NdisSend(&Status, pAdapt->BindingHandle, pNdisPacket );
> if (Status != NDIS_STATUS_PENDING){
> NdisFreeBuffer(pNdisBuffer);
> NdisFreePacket(pNdisPacket);
> }
> NdisReleaseSpinLock(&(pFilterContext->PacketListSpinLock));
> break;
> }
>
> It seems to me that there is nothing to go wrong. Maybe I can't see
> some important issues. Thank you for any advice in advance.
> Arek
>


 
Reply With Quote
 
arek.ploski@gmail.com
Guest
Posts: n/a

 
      07-23-2006
Thomas,

First of all thank you for such an impressively fast reply.

To be honest I must admit (but I am sure that it's quite obvious
that I am a newbie in drivers' subject.

Your remarks gave me a lot to think. I've changed my code, added my own
packets and buffers pools, so that I can tell apart which packets are
mine and which are not (in PTSendComplete).
Moreover I implemented solution from NDISPROT example, so now I suspend
irp call and keep it with packet and after all I can complete it in
PTSendComplete.
Now it seems like it works fine for me.

In short, my code now looks like below (again I overlooked some extra
code):

filter.c:

NdisAcquireSpinLock(&(pFilterContext->PacketListSpinLock));
NdisAllocatePacket(&Status, &pNdisPacket, pAdapt->OutPacketPoolHandle
);
NdisAllocateBuffer(&Status, &pNdisBuffer, pAdapt->OutBufferPoolHandle,
ioBuffer, inputBufferLength );
NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
NdisReleaseSpinLock(&(pFilterContext->PacketListSpinLock));

NdisInterlockedIncrement( &pAdapt->RefCount );
IoMarkIrpPending(pIrp);
InsertTailList(&(pAdapt->OutPendedListHead),
&pIrp->Tail.Overlay.ListEntry);
IoSetCancelRoutine(pIrp, CancelOutIrp);
NPROT_IRP_FROM_SEND_PKT(pNdisPacket) = pIrp;

NdisSend(&Status, pAdapt->BindingHandle, pNdisPacket );
if (Status == NDIS_STATUS_PENDING){
NtStatus = STATUS_PENDING;
}
break;

protocol.c:

if (PoolHandle == pAdapt->OutPacketPoolHandle) {
PIRP pIrp;
PIO_STACK_LOCATION pIrpSp;
UINT nBufferCount;
PNDIS_BUFFER pCurrentBuffer;
UINT TotalPacketLength;

pIrp = NPROT_IRP_FROM_SEND_PKT(Packet);
NdisAcquireSpinLock(&pAdapt->Lock);
RemoveEntryList(&pIrp->Tail.Overlay.ListEntry);
NdisReleaseSpinLock(&pAdapt->Lock);
IoSetCancelRoutine(pIrp, NULL);

pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
if (Status == NDIS_STATUS_SUCCESS) {
pIrp->IoStatus.Information = pIrpSp->Parameters.Write.Length;
pIrp->IoStatus.Status = STATUS_SUCCESS;
} else {
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}

NdisQueryPacket( (PNDIS_PACKET )Packet, NULL, (PUINT)&nBufferCount,
&pCurrentBuffer, &TotalPacketLength );
// my packets always have only one buffer
if (pCurrentBuffer)
NdisFreeBuffer(pCurrentBuffer);
NdisFreePacket(Packet);

IoCompleteRequest(pIrp, IO_NO_INCREMENT);
NdisInterlockedDecrement( &pAdapt->RefCount );
}

Thanks again for Your help and I'll apreciate it if you have any
further comments.
Arek

 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
NdisSend() pesudocode Tierrie Windows Vista Drivers 2 09-21-2005 06:07 PM
NdisSend not working for WAN Packets : Solution ??? kaursukhvinder@gmail.com Windows Vista Drivers 1 09-15-2005 04:45 AM
The relationship between NdisSend() and NdisMSendComplete() Liang Chen Windows Vista Drivers 1 08-17-2005 03:34 PM
NdisSend from ptReceive failure Kumar Windows Vista Drivers 3 11-10-2004 02:48 PM
NDIS 5.0 intermediate driver problems with Nortel's VPN Ophir Munk Windows Vista Drivers 2 10-26-2003 06:40 PM



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59