Annotation of ntddk/src/network/tdi/framesnd.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1989-1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     framesnd.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module contains routines which build and send Sample transport
                     12:     frames for other modules.
                     13: 
                     14: Environment:
                     15: 
                     16:     Kernel mode
                     17: 
                     18: Revision History:
                     19: 
                     20: --*/
                     21: 
                     22: #include "st.h"
                     23: 
                     24: 
                     25: 
                     26: NTSTATUS
                     27: StSendConnect(
                     28:     IN PTP_CONNECTION Connection
                     29:     )
                     30: 
                     31: /*++
                     32: 
                     33: Routine Description:
                     34: 
                     35:     This routine sends a CONNECT frame of the appropriate type given the
                     36:     state of the specified connection.
                     37: 
                     38: Arguments:
                     39: 
                     40:     Connection - Pointer to a transport connection object.
                     41: 
                     42: Return Value:
                     43: 
                     44:     none.
                     45: 
                     46: --*/
                     47: 
                     48: {
                     49:     NTSTATUS Status;
                     50:     PDEVICE_CONTEXT DeviceContext;
                     51:     PUCHAR SourceRouting;
                     52:     UINT SourceRoutingLength;
                     53:     UINT HeaderLength;
                     54:     PSEND_PACKET_TAG SendTag;
                     55:     PTP_PACKET Packet;
                     56:     PST_HEADER StHeader;
                     57: 
                     58: 
                     59:     DeviceContext = Connection->Provider;
                     60: 
                     61:     //
                     62:     // Allocate a packet from the pool.
                     63:     //
                     64: 
                     65:     Status = StCreatePacket (DeviceContext, &Packet);
                     66:     if (!NT_SUCCESS (Status)) {                    // couldn't make frame.
                     67:         return STATUS_INSUFFICIENT_RESOURCES;
                     68:     }
                     69: 
                     70:     SendTag = (PSEND_PACKET_TAG)(Packet->NdisPacket->ProtocolReserved);
                     71:     SendTag->Type = TYPE_C_FRAME;
                     72:     SendTag->Packet = Packet;
                     73:     SendTag->Owner = (PVOID)Connection;
                     74: 
                     75:     //
                     76:     // Build the MAC header.
                     77:     //
                     78: 
                     79:     //
                     80:     // CONNECT frames go out as
                     81:     // single-route source routing.
                     82:     //
                     83: 
                     84:     MacReturnSingleRouteSR(
                     85:         &DeviceContext->MacInfo,
                     86:         &SourceRouting,
                     87:         &SourceRoutingLength);
                     88: 
                     89:     MacConstructHeader (
                     90:         &DeviceContext->MacInfo,
                     91:         Packet->Header,
                     92:         DeviceContext->MulticastAddress.Address,
                     93:         DeviceContext->LocalAddress.Address,
                     94:         sizeof(ST_HEADER),
                     95:         SourceRouting,
                     96:         SourceRoutingLength,
                     97:         &HeaderLength);
                     98: 
                     99: 
                    100:     //
                    101:     // Build the header: 'C', dest, source
                    102:     //
                    103: 
                    104:     StHeader = (PST_HEADER)(&Packet->Header[HeaderLength]);
                    105: 
                    106:     StHeader->Signature = ST_SIGNATURE;
                    107:     StHeader->Command = ST_CMD_CONNECT;
                    108:     StHeader->Flags = 0;
                    109: 
                    110:     RtlCopyMemory (StHeader->Destination, Connection->CalledAddress.NetbiosName, 16);
                    111:     RtlCopyMemory (StHeader->Source, Connection->AddressFile->Address->NetworkName->NetbiosName, 16);
                    112: 
                    113:     HeaderLength += sizeof(ST_HEADER);
                    114: 
                    115:     //
                    116:     // Modify the packet length and send the it.
                    117:     //
                    118: 
                    119:     StSetNdisPacketLength(Packet->NdisPacket, HeaderLength);
                    120: 
                    121:     StNdisSend (Packet);
                    122: 
                    123:     return STATUS_SUCCESS;
                    124: } /* StSendConnect */
                    125: 
                    126: 
                    127: NTSTATUS
                    128: StSendDisconnect(
                    129:     IN PTP_CONNECTION Connection
                    130:     )
                    131: 
                    132: /*++
                    133: 
                    134: Routine Description:
                    135: 
                    136:     This routine sends a DISCONNECT frame of the appropriate type given the
                    137:     state of the specified connection.
                    138: 
                    139: Arguments:
                    140: 
                    141:     Connection - Pointer to a transport connection object.
                    142: 
                    143: Return Value:
                    144: 
                    145:     none.
                    146: 
                    147: --*/
                    148: 
                    149: {
                    150:     NTSTATUS Status;
                    151:     PDEVICE_CONTEXT DeviceContext;
                    152:     PUCHAR SourceRouting;
                    153:     UINT SourceRoutingLength;
                    154:     UINT HeaderLength;
                    155:     PSEND_PACKET_TAG SendTag;
                    156:     PTP_PACKET Packet;
                    157:     PST_HEADER StHeader;
                    158: 
                    159: 
                    160:     DeviceContext = Connection->Provider;
                    161: 
                    162:     //
                    163:     // Allocate a packet from the pool.
                    164:     //
                    165: 
                    166:     Status = StCreatePacket (DeviceContext, &Packet);
                    167:     if (!NT_SUCCESS (Status)) {                    // couldn't make frame.
                    168:         return STATUS_INSUFFICIENT_RESOURCES;
                    169:     }
                    170: 
                    171:     SendTag = (PSEND_PACKET_TAG)(Packet->NdisPacket->ProtocolReserved);
                    172:     SendTag->Type = TYPE_D_FRAME;
                    173:     SendTag->Packet = Packet;
                    174:     SendTag->Owner = (PVOID)Connection;
                    175: 
                    176:     //
                    177:     // Build the MAC header.
                    178:     //
                    179: 
                    180:     //
                    181:     // CONNECT frames go out as
                    182:     // single-route source routing.
                    183:     //
                    184: 
                    185:     MacReturnSingleRouteSR(
                    186:         &DeviceContext->MacInfo,
                    187:         &SourceRouting,
                    188:         &SourceRoutingLength);
                    189: 
                    190:     MacConstructHeader (
                    191:         &DeviceContext->MacInfo,
                    192:         Packet->Header,
                    193:         DeviceContext->MulticastAddress.Address,
                    194:         DeviceContext->LocalAddress.Address,
                    195:         sizeof(ST_HEADER),
                    196:         SourceRouting,
                    197:         SourceRoutingLength,
                    198:         &HeaderLength);
                    199: 
                    200: 
                    201:     //
                    202:     // Build the header: 'D', dest, source
                    203:     //
                    204: 
                    205:     StHeader = (PST_HEADER)(&Packet->Header[HeaderLength]);
                    206: 
                    207:     StHeader->Signature = ST_SIGNATURE;
                    208:     StHeader->Command = ST_CMD_DISCONNECT;
                    209:     StHeader->Flags = 0;
                    210: 
                    211:     RtlCopyMemory (StHeader->Destination, Connection->CalledAddress.NetbiosName, 16);
                    212:     RtlCopyMemory (StHeader->Source, Connection->AddressFile->Address->NetworkName->NetbiosName, 16);
                    213: 
                    214:     HeaderLength += sizeof(ST_HEADER);
                    215: 
                    216:     //
                    217:     // Modify the packet length and send the it.
                    218:     //
                    219: 
                    220:     StSetNdisPacketLength(Packet->NdisPacket, HeaderLength);
                    221: 
                    222:     StNdisSend (Packet);
                    223: 
                    224:     return STATUS_SUCCESS;
                    225: 
                    226: } /* StSendDisconnect */
                    227: 
                    228: 
                    229: NTSTATUS
                    230: StSendAddressFrame(
                    231:     PTP_ADDRESS Address
                    232:     )
                    233: 
                    234: /*++
                    235: 
                    236: Routine Description:
                    237: 
                    238:     It is intended that this routine be used for sending datagrams and
                    239:     braodcast datagrams.
                    240: 
                    241:     The datagram to be sent is described in the NDIS packet contained
                    242:     in the Address. When the send completes, the send completion handler
                    243:     returns the NDIS buffer describing the datagram to the buffer pool and
                    244:     marks the address ndis packet as usable again. Thus, all datagram
                    245:     frames are sequenced through the address they are sent on.
                    246: 
                    247: Arguments:
                    248: 
                    249:     Address - pointer to the address from which to send this datagram.
                    250: 
                    251: Return Value:
                    252: 
                    253:     NTSTATUS - status of operation.
                    254: 
                    255: --*/
                    256: 
                    257: {
                    258:     PDEVICE_CONTEXT DeviceContext;
                    259: 
                    260: 
                    261:     //
                    262:     // Send the packet.
                    263:     //
                    264: 
                    265:     DeviceContext = Address->Provider;
                    266: 
                    267:     INCREMENT_COUNTER (DeviceContext, PacketsSent);
                    268: 
                    269:     StNdisSend (Address->Packet);
                    270: 
                    271:     return STATUS_PENDING;
                    272: } /* StSendAddressFrame */
                    273: 
                    274: 
                    275: VOID
                    276: StSendDatagramCompletion(
                    277:     IN PTP_ADDRESS Address,
                    278:     IN PNDIS_PACKET NdisPacket,
                    279:     IN NDIS_STATUS NdisStatus
                    280:     )
                    281: 
                    282: /*++
                    283: 
                    284: Routine Description:
                    285: 
                    286:     This routine is called as an I/O completion handler at the time a
                    287:     StSendUIMdlFrame send request is completed.  Because this handler is only
                    288:     associated with StSendUIMdlFrame, and because StSendUIMdlFrame is only
                    289:     used with datagrams and broadcast datagrams, we know that the I/O being
                    290:     completed is a datagram.  Here we complete the in-progress datagram, and
                    291:     start-up the next one if there is one.
                    292: 
                    293: Arguments:
                    294: 
                    295:     Address - Pointer to a transport address on which the datagram
                    296:         is queued.
                    297: 
                    298:     NdisPacket - pointer to the NDIS packet describing this request.
                    299: 
                    300: Return Value:
                    301: 
                    302:     none.
                    303: 
                    304: --*/
                    305: 
                    306: {
                    307:     PTP_REQUEST Request;
                    308:     PLIST_ENTRY p;
                    309:     KIRQL oldirql;
                    310:     PNDIS_BUFFER HeaderBuffer;
                    311: 
                    312:     UNREFERENCED_PARAMETER(NdisPacket);
                    313: 
                    314:     StReferenceAddress ("Complete datagram", Address);
                    315: 
                    316:     //
                    317:     // Dequeue the current request and return it to the client.  Release
                    318:     // our hold on the send datagram queue.
                    319:     //
                    320:     // *** There may be no current request, if the one that was queued
                    321:     //     was aborted or timed out.
                    322:     //
                    323: 
                    324:     ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql);
                    325:     p = RemoveHeadList (&Address->SendDatagramQueue);
                    326: 
                    327:     if (p != &Address->SendDatagramQueue) {
                    328: 
                    329:         RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql);
                    330: 
                    331:         Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage);
                    332: 
                    333:         //
                    334:         // Strip off and unmap the buffers describing data and header.
                    335:         //
                    336: 
                    337:         NdisUnchainBufferAtFront (Address->Packet->NdisPacket, &HeaderBuffer);
                    338: 
                    339:         // drop the rest of the packet
                    340: 
                    341:         NdisReinitializePacket (Address->Packet->NdisPacket);
                    342: 
                    343:         NDIS_BUFFER_LINKAGE(HeaderBuffer) = (PNDIS_BUFFER)NULL;
                    344:         NdisChainBufferAtFront (Address->Packet->NdisPacket, HeaderBuffer);
                    345: 
                    346:         //
                    347:         // Ignore NdisStatus; datagrams always "succeed".
                    348:         //
                    349: 
                    350:         StCompleteRequest (Request, STATUS_SUCCESS, Request->Buffer2Length);
                    351: 
                    352:         ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql);
                    353:         Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS;
                    354:         RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql);
                    355: 
                    356:         //
                    357:         // Send more datagrams on the Address if possible.
                    358:         //
                    359: 
                    360:         StSendDatagramsOnAddress (Address);       // do more datagrams.
                    361: 
                    362:     } else {
                    363: 
                    364:         Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS;
                    365:         RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql);
                    366: 
                    367:     }
                    368: 
                    369:     StDereferenceAddress ("Complete datagram", Address);
                    370: 
                    371: } /* StSendDatagramCompletion */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.