|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.