|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1990 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: packet.c ! 8: ! 9: Abstract: ! 10: ! 11: ! 12: Author: ! 13: ! 14: ! 15: Environment: ! 16: ! 17: Kernel mode only. ! 18: ! 19: Notes: ! 20: ! 21: ! 22: Future: ! 23: ! 24: ! 25: ! 26: Revision History: ! 27: ! 28: --*/ ! 29: ! 30: #include "stdarg.h" ! 31: #include "ntddk.h" ! 32: #include "ntiologc.h" ! 33: #include "ndis.h" ! 34: ! 35: #include "debug.h" ! 36: #include "packet.h" ! 37: ! 38: ! 39: ! 40: NTSTATUS ! 41: PacketRead( ! 42: IN PDEVICE_OBJECT DeviceObject, ! 43: IN PIRP Irp ! 44: ) ! 45: ! 46: /*++ ! 47: ! 48: Routine Description: ! 49: ! 50: This is the dispatch routine for create/open and close requests. ! 51: These requests complete successfully. ! 52: ! 53: Arguments: ! 54: ! 55: DeviceObject - Pointer to the device object. ! 56: ! 57: Irp - Pointer to the request packet. ! 58: ! 59: Return Value: ! 60: ! 61: Status is returned. ! 62: ! 63: --*/ ! 64: ! 65: { ! 66: PIO_STACK_LOCATION IrpSp; ! 67: PDEVICE_EXTENSION DeviceExtension; ! 68: PLIST_ENTRY PacketListEntry; ! 69: PNDIS_PACKET pPacket; ! 70: PMDL pMdl; ! 71: ! 72: ! 73: IF_LOUD(DbgPrint("Packet: Read\n");) ! 74: ! 75: DeviceExtension = DeviceObject->DeviceExtension; ! 76: ! 77: IrpSp = IoGetCurrentIrpStackLocation(Irp); ! 78: ! 79: // ! 80: // See if the buffer is atleast big enough to hold the ! 81: // ethernet header ! 82: // ! 83: if (IrpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) { ! 84: ! 85: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; ! 86: return STATUS_UNSUCCESSFUL; ! 87: } ! 88: ! 89: // ! 90: // Allocate an MDL to map the portion of the buffer following the ! 91: // header ! 92: // ! 93: pMdl=IoAllocateMdl( ! 94: MmGetMdlVirtualAddress(Irp->MdlAddress), ! 95: MmGetMdlByteCount(Irp->MdlAddress), ! 96: FALSE, ! 97: FALSE, ! 98: NULL ! 99: ); ! 100: ! 101: ! 102: if (pMdl == NULL) { ! 103: IF_LOUD(DbgPrint("Packet: Read-Failed to allocate Mdl\n");) ! 104: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; ! 105: return STATUS_UNSUCCESSFUL; ! 106: } ! 107: ! 108: // ! 109: // Build the mdl to point to the the portion of the buffer followin ! 110: // the header ! 111: // ! 112: IoBuildPartialMdl( ! 113: Irp->MdlAddress, ! 114: pMdl, ! 115: ((PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress))+ETHERNET_HEADER_LENGTH, ! 116: 0 ! 117: ); ! 118: ! 119: // ! 120: // Clear the next link in the new MDL ! 121: // ! 122: pMdl->Next=NULL; ! 123: ! 124: // ! 125: // Try to get a packet from our list of free ones ! 126: // ! 127: PacketListEntry=ExInterlockedRemoveHeadList(&DeviceExtension->FreePacketList, ! 128: &DeviceExtension->FreePacketListSpinLock); ! 129: ! 130: if (PacketListEntry == NULL) { ! 131: IF_LOUD(DbgPrint("Packet: Read- No free packets\n");) ! 132: ! 133: IoFreeMdl(pMdl); ! 134: Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; ! 135: return STATUS_UNSUCCESSFUL; ! 136: } ! 137: ! 138: // ! 139: // Get a pointer to the packet itself ! 140: // ! 141: ! 142: pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved); ! 143: RESERVED(pPacket)->Irp=Irp; ! 144: RESERVED(pPacket)->pMdl=pMdl; ! 145: ! 146: IoMarkIrpPending(Irp); ! 147: Irp->IoStatus.Status = STATUS_PENDING; ! 148: ! 149: ! 150: // ! 151: // Attach our new MDL to the packet ! 152: // ! 153: NdisChainBufferAtFront(pPacket,pMdl); ! 154: ! 155: // ! 156: // Put this packet in a list of pending reads. ! 157: // The receive indication handler will attemp to remove packets ! 158: // from this list for use in transfer data calls ! 159: // ! 160: ExInterlockedInsertTailList( ! 161: &DeviceExtension->RcvList, ! 162: PacketListEntry, ! 163: &DeviceExtension->RcvQSpinLock); ! 164: ! 165: ! 166: ! 167: ! 168: return(STATUS_PENDING); ! 169: ! 170: } ! 171: ! 172: ! 173: ! 174: ! 175: NDIS_STATUS ! 176: PacketReceiveIndicate ( ! 177: IN NDIS_HANDLE ProtocolBindingContext, ! 178: IN NDIS_HANDLE MacReceiveContext, ! 179: IN PVOID HeaderBuffer, ! 180: IN UINT HeaderBufferSize, ! 181: IN PVOID LookAheadBuffer, ! 182: IN UINT LookaheadBufferSize, ! 183: IN UINT PacketSize ! 184: ) ! 185: ! 186: { ! 187: PIO_STACK_LOCATION IrpSp; ! 188: PDEVICE_EXTENSION DeviceExtension; ! 189: PIRP Irp; ! 190: PLIST_ENTRY PacketListEntry; ! 191: PNDIS_PACKET pPacket; ! 192: ULONG SizeToTransfer; ! 193: NDIS_STATUS Status; ! 194: UINT BytesTransfered; ! 195: PVOID pBuffer; ! 196: ULONG BufferLength; ! 197: ! 198: IF_LOUD(DbgPrint("Packet: ReceiveIndicate\n");) ! 199: ! 200: DeviceExtension= (PDEVICE_EXTENSION)ProtocolBindingContext; ! 201: ! 202: if (HeaderBufferSize > ETHERNET_HEADER_LENGTH) { ! 203: ! 204: return NDIS_STATUS_SUCCESS; ! 205: } ! 206: ! 207: // ! 208: // See if there are any pending read that we can satisfy ! 209: // ! 210: PacketListEntry=ExInterlockedRemoveHeadList(&DeviceExtension->RcvList, ! 211: &DeviceExtension->RcvQSpinLock); ! 212: ! 213: if (PacketListEntry == NULL) { ! 214: return NDIS_STATUS_SUCCESS; ! 215: } ! 216: ! 217: pPacket=CONTAINING_RECORD(PacketListEntry,NDIS_PACKET,ProtocolReserved); ! 218: ! 219: Irp=RESERVED(pPacket)->Irp; ! 220: IrpSp = IoGetCurrentIrpStackLocation(Irp); ! 221: ! 222: // ! 223: // This is the length of our partial MDL ! 224: // ! 225: BufferLength=IrpSp->Parameters.Read.Length-ETHERNET_HEADER_LENGTH; ! 226: ! 227: // ! 228: // Find out how much to transfer ! 229: // ! 230: SizeToTransfer = (PacketSize < BufferLength) ? ! 231: PacketSize : BufferLength; ! 232: ! 233: // ! 234: // copy the ethernet header into the actual readbuffer ! 235: // ! 236: NdisMoveMappedMemory( ! 237: MmGetSystemAddressForMdl(Irp->MdlAddress), ! 238: HeaderBuffer, ! 239: HeaderBufferSize ! 240: ); ! 241: ! 242: // ! 243: // Call the Mac to transfer the packet ! 244: // ! 245: ! 246: NdisTransferData( ! 247: &Status, ! 248: DeviceExtension->AdapterHandle, ! 249: MacReceiveContext, ! 250: 0, ! 251: SizeToTransfer, ! 252: pPacket, ! 253: &BytesTransfered); ! 254: ! 255: if (Status != NDIS_STATUS_PENDING) { ! 256: ! 257: // ! 258: // If it didn't pend, call the completeion routine now ! 259: // ! 260: PacketTransferDataComplete( ! 261: DeviceExtension, ! 262: pPacket, ! 263: Status, ! 264: BytesTransfered ! 265: ); ! 266: ! 267: ! 268: } ! 269: ! 270: ! 271: ! 272: return NDIS_STATUS_SUCCESS; ! 273: ! 274: } ! 275: ! 276: ! 277: VOID ! 278: PacketTransferDataComplete ( ! 279: IN NDIS_HANDLE ProtocolBindingContext, ! 280: IN PNDIS_PACKET pPacket, ! 281: IN NDIS_STATUS Status, ! 282: IN UINT BytesTransfered ! 283: ) ! 284: ! 285: { ! 286: PIO_STACK_LOCATION IrpSp; ! 287: PDEVICE_EXTENSION DeviceExtension; ! 288: PIRP Irp; ! 289: PMDL pMdl; ! 290: ! 291: IF_LOUD(DbgPrint("Packet: TransferDataComplete\n");) ! 292: ! 293: DeviceExtension= (PDEVICE_EXTENSION)ProtocolBindingContext; ! 294: Irp=RESERVED(pPacket)->Irp; ! 295: ! 296: IrpSp = IoGetCurrentIrpStackLocation(Irp); ! 297: ! 298: pMdl=RESERVED(pPacket)->pMdl; ! 299: ! 300: // ! 301: // Free the MDL that we allocated ! 302: // ! 303: IoFreeMdl(pMdl); ! 304: ! 305: // ! 306: // recylcle the packet ! 307: // ! 308: NdisReinitializePacket(pPacket); ! 309: ! 310: // ! 311: // Put the packet on the free queue ! 312: // ! 313: ExInterlockedInsertTailList( ! 314: &DeviceExtension->FreePacketList, ! 315: &RESERVED(pPacket)->ListElement, ! 316: &DeviceExtension->FreePacketListSpinLock); ! 317: ! 318: ! 319: Irp->IoStatus.Status = Status; ! 320: Irp->IoStatus.Information = BytesTransfered+ETHERNET_HEADER_LENGTH; ! 321: IoCompleteRequest(Irp, IO_NO_INCREMENT); ! 322: ! 323: ! 324: return; ! 325: ! 326: ! 327: } ! 328: ! 329: ! 330: ! 331: ! 332: ! 333: ! 334: ! 335: ! 336: ! 337: VOID ! 338: PacketReceiveComplete( ! 339: IN NDIS_HANDLE ProtocolBindingContext ! 340: ) ! 341: ! 342: { ! 343: ! 344: return; ! 345: ! 346: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.