Annotation of ntddk/src/network/tdi/rcv.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1989-1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     rcv.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This module contains code which performs the following TDI services:
        !            12: 
        !            13:         o   TdiReceive
        !            14:         o   TdiReceiveDatagram
        !            15: 
        !            16: Environment:
        !            17: 
        !            18:     Kernel mode
        !            19: 
        !            20: Revision History:
        !            21: 
        !            22: --*/
        !            23: 
        !            24: #include "st.h"
        !            25: 
        !            26: 
        !            27: NTSTATUS
        !            28: StTdiReceive(
        !            29:     IN PIRP Irp
        !            30:     )
        !            31: 
        !            32: /*++
        !            33: 
        !            34: Routine Description:
        !            35: 
        !            36:     This routine performs the TdiReceive request for the transport provider.
        !            37: 
        !            38: Arguments:
        !            39: 
        !            40:     Irp - I/O Request Packet for this request.
        !            41: 
        !            42: Return Value:
        !            43: 
        !            44:     NTSTATUS - status of operation.
        !            45: 
        !            46: --*/
        !            47: 
        !            48: {
        !            49:     NTSTATUS status;
        !            50:     PTP_CONNECTION connection;
        !            51:     KIRQL oldirql, cancelirql;
        !            52:     PTP_REQUEST tpRequest;
        !            53:     LARGE_INTEGER timeout = {0,0};
        !            54:     PIO_STACK_LOCATION irpSp;
        !            55:     PMDL ReceiveBuffer;
        !            56:     ULONG ReceiveBufferLength;
        !            57:     PTDI_REQUEST_KERNEL_RECEIVE parameters;
        !            58: 
        !            59:     //
        !            60:     // verify that the operation is taking place on a connection. At the same
        !            61:     // time we do this, we reference the connection. This ensures it does not
        !            62:     // get removed out from under us. Note also that we do the connection
        !            63:     // lookup within a try/except clause, thus protecting ourselves against
        !            64:     // really bogus handles
        !            65:     //
        !            66: 
        !            67:     irpSp = IoGetCurrentIrpStackLocation (Irp);
        !            68:     connection  = irpSp->FileObject->FsContext;
        !            69: 
        !            70:     status = StVerifyConnectionObject (connection);
        !            71: 
        !            72:     if (!NT_SUCCESS (status)) {
        !            73:         return status;
        !            74:     }
        !            75: 
        !            76:     //
        !            77:     // Initialize bytes transferred here.
        !            78:     //
        !            79: 
        !            80:     Irp->IoStatus.Information = 0;              // reset byte transfer count.
        !            81: 
        !            82: 
        !            83:     parameters = (PTDI_REQUEST_KERNEL_RECEIVE)(&irpSp->Parameters);
        !            84:     ReceiveBuffer = Irp->MdlAddress;
        !            85:     ReceiveBufferLength =parameters->ReceiveLength;
        !            86: 
        !            87:     //
        !            88:     // Queue up this receive to the connection object.
        !            89:     //
        !            90: 
        !            91:     status = StCreateRequest (
        !            92:                  Irp,                           // IRP for this request.
        !            93:                  connection,                    // context.
        !            94:                  REQUEST_FLAGS_CONNECTION,      // partial flags.
        !            95:                  ReceiveBuffer,
        !            96:                  ReceiveBufferLength,
        !            97:                  timeout,
        !            98:                  &tpRequest);
        !            99: 
        !           100:     //
        !           101:     // We have a request, now queue it. If the connection has gone south on us
        !           102:     // while we were getting things going, we will avoid actually queing the
        !           103:     // request.
        !           104:     //
        !           105: 
        !           106:     if (NT_SUCCESS (status)) {
        !           107: 
        !           108:         // This reference is removed by StDestroyRequest.
        !           109: 
        !           110:         StReferenceConnection("TdiReceive request", connection);
        !           111:         tpRequest->Owner = ConnectionType;
        !           112: 
        !           113:         IoAcquireCancelSpinLock(&cancelirql);
        !           114:         ACQUIRE_SPIN_LOCK (&connection->SpinLock,&oldirql);
        !           115:         if ((connection->Flags & CONNECTION_FLAGS_STOPPING) != 0) {
        !           116:             RELEASE_SPIN_LOCK (&connection->SpinLock,oldirql);
        !           117:             IoReleaseCancelSpinLock(cancelirql);
        !           118:             StCompleteRequest (
        !           119:                 tpRequest,
        !           120:                 connection->Status,
        !           121:                 0);
        !           122:             status = STATUS_PENDING;
        !           123:         } else {
        !           124: 
        !           125:             //
        !           126:             // Insert onto the receive queue, and make the IRP
        !           127:             // cancellable.
        !           128:             //
        !           129: 
        !           130:             InsertTailList (&connection->ReceiveQueue,&tpRequest->Linkage);
        !           131:             RELEASE_SPIN_LOCK (&connection->SpinLock,oldirql);
        !           132: 
        !           133:             //
        !           134:             // If this IRP has been cancelled, then call the
        !           135:             // cancel routine.
        !           136:             //
        !           137: 
        !           138:             if (Irp->Cancel) {
        !           139:                 Irp->CancelIrql = cancelirql;
        !           140:                 StCancelReceive((PDEVICE_OBJECT)(connection->Provider), Irp);
        !           141:                 StDereferenceConnection ("IRP cancelled", connection);   // release lookup hold.
        !           142:                 return STATUS_PENDING;
        !           143:             }
        !           144: 
        !           145:             Irp->CancelRoutine = StCancelReceive;
        !           146:             IoReleaseCancelSpinLock(cancelirql);
        !           147: 
        !           148:             AwakenReceive (connection);             // awaken if sleeping.
        !           149: 
        !           150:             status = STATUS_PENDING;
        !           151:         }
        !           152:     }
        !           153: 
        !           154:     StDereferenceConnection("temp TdiReceive", connection);
        !           155: 
        !           156:     return status;
        !           157: } /* TdiReceive */
        !           158: 
        !           159: 
        !           160: NTSTATUS
        !           161: StTdiReceiveDatagram(
        !           162:     IN PIRP Irp
        !           163:     )
        !           164: 
        !           165: /*++
        !           166: 
        !           167: Routine Description:
        !           168: 
        !           169:     This routine performs the TdiReceiveDatagram request for the transport
        !           170:     provider. Receive datagrams just get queued up to an address, and are
        !           171:     completed when a DATAGRAM or DATAGRAM_BROADCAST frame is received at
        !           172:     the address.
        !           173: 
        !           174: Arguments:
        !           175: 
        !           176:     Irp - I/O Request Packet for this request.
        !           177: 
        !           178: Return Value:
        !           179: 
        !           180:     NTSTATUS - status of operation.
        !           181: 
        !           182: --*/
        !           183: 
        !           184: {
        !           185:     NTSTATUS status;
        !           186:     KIRQL oldirql;
        !           187:     PTP_ADDRESS address;
        !           188:     PTP_ADDRESS_FILE addressFile;
        !           189:     PTP_REQUEST tpRequest;
        !           190:     LARGE_INTEGER timeout = {0,0};
        !           191:     PIO_STACK_LOCATION irpSp;
        !           192:     PMDL ReceiveBuffer;
        !           193:     ULONG ReceiveBufferLength;
        !           194: 
        !           195:     //
        !           196:     // verify that the operation is taking place on an address. At the same
        !           197:     // time we do this, we reference the address. This ensures it does not
        !           198:     // get removed out from under us. Note also that we do the address
        !           199:     // lookup within a try/except clause, thus protecting ourselves against
        !           200:     // really bogus handles
        !           201:     //
        !           202: 
        !           203:     irpSp = IoGetCurrentIrpStackLocation (Irp);
        !           204:     addressFile = irpSp->FileObject->FsContext;
        !           205: 
        !           206:     status = StVerifyAddressObject (addressFile);
        !           207: 
        !           208:     if (!NT_SUCCESS (status)) {
        !           209:         return status;
        !           210:     }
        !           211: 
        !           212:     address = addressFile->Address;
        !           213: 
        !           214:     ReceiveBuffer = Irp->MdlAddress;
        !           215:     ReceiveBufferLength =
        !           216:           ((PTDI_REQUEST_KERNEL_RECEIVEDG)(&irpSp->Parameters))->ReceiveLength;
        !           217: 
        !           218:     status = StCreateRequest (
        !           219:                  Irp,                           // IRP for this request.
        !           220:                  address,                       // context
        !           221:                  REQUEST_FLAGS_ADDRESS,        // partial flags.
        !           222:                  ReceiveBuffer,
        !           223:                  ReceiveBufferLength,
        !           224:                  timeout,
        !           225:                  &tpRequest);
        !           226: 
        !           227:     if (NT_SUCCESS (status)) {
        !           228:         StReferenceAddress ("Receive datagram", address);
        !           229:         tpRequest->Owner = AddressType;
        !           230:         ACQUIRE_SPIN_LOCK (&address->SpinLock,&oldirql);
        !           231:         if ((address->Flags & ADDRESS_FLAGS_STOPPING) != 0) {
        !           232:             RELEASE_SPIN_LOCK (&address->SpinLock,oldirql);
        !           233:             StCompleteRequest (tpRequest, STATUS_NETWORK_NAME_DELETED, 0);
        !           234:             status = STATUS_PENDING;
        !           235:         } else {
        !           236:             InsertTailList (&addressFile->ReceiveDatagramQueue,&tpRequest->Linkage);
        !           237:             RELEASE_SPIN_LOCK (&address->SpinLock,oldirql);
        !           238:         }
        !           239: 
        !           240:         status = STATUS_PENDING;
        !           241:     }
        !           242: 
        !           243:     StDereferenceAddress ("Temp rcv datagram", address);
        !           244: 
        !           245:     return status;
        !           246: } /* TdiReceiveDatagram */
        !           247: 

unix.superglobalmegacorp.com

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