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