|
|
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.