Annotation of ntddk/src/network/tdi/framesnd.c, revision 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.