ReactOS  0.4.13-dev-247-g0f29b3f
lan.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS TCP/IP protocol driver
4  * FILE: datalink/lan.c
5  * PURPOSE: Local Area Network media routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  * CSH 01/08-2000 Created
9  */
10 
11 #include "precomp.h"
12 
13 #include <ntifs.h>
14 #include <receive.h>
15 #include <wait.h>
16 
19 
20 #define CCS_ROOT L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"
21 #define TCPIP_GUID L"{4D36E972-E325-11CE-BFC1-08002BE10318}"
22 
23 typedef struct _LAN_WQ_ITEM {
30 
31 typedef struct _RECONFIGURE_CONTEXT {
35 
40 
42  PLAN_ADAPTER Adapter,
44  NDIS_OID OID,
45  PVOID Buffer,
46  UINT Length)
47 /*
48  * FUNCTION: Send a request to NDIS
49  * ARGUMENTS:
50  * Adapter = Pointer to a LAN_ADAPTER structure
51  * Type = Type of request (Set or Query)
52  * OID = Value to be set/queried for
53  * Buffer = Pointer to a buffer to use
54  * Length = Number of bytes in Buffer
55  * RETURNS:
56  * Status of operation
57  */
58 {
60  NDIS_STATUS NdisStatus;
61 
62  Request.RequestType = Type;
64  Request.DATA.SET_INFORMATION.Oid = OID;
65  Request.DATA.SET_INFORMATION.InformationBuffer = Buffer;
66  Request.DATA.SET_INFORMATION.InformationBufferLength = Length;
67  } else {
68  Request.DATA.QUERY_INFORMATION.Oid = OID;
69  Request.DATA.QUERY_INFORMATION.InformationBuffer = Buffer;
70  Request.DATA.QUERY_INFORMATION.InformationBufferLength = Length;
71  }
72 
73  if (Adapter->State != LAN_STATE_RESETTING) {
74  NdisRequest(&NdisStatus, Adapter->NdisHandle, &Request);
75  } else {
76  NdisStatus = NDIS_STATUS_NOT_ACCEPTED;
77  }
78 
79  /* Wait for NDIS to complete the request */
80  if (NdisStatus == NDIS_STATUS_PENDING) {
81  KeWaitForSingleObject(&Adapter->Event,
83  KernelMode,
84  FALSE,
85  NULL);
86  NdisStatus = Adapter->NdisStatus;
87  }
88 
89  return NdisStatus;
90 }
91 
92 /* Used by legacy ProtocolReceive for packet type */
95  PVOID HeaderBuffer,
96  ULONG HeaderBufferSize,
97  PULONG PacketType)
98 {
99  PETH_HEADER EthHeader = HeaderBuffer;
100 
101  if (HeaderBufferSize < Adapter->HeaderSize)
102  {
103  TI_DbgPrint(DEBUG_DATALINK, ("Runt frame (size %d).\n", HeaderBufferSize));
105  }
106 
107  switch (Adapter->Media)
108  {
109  case NdisMedium802_3:
110  /* Ethernet and IEEE 802.3 frames can be distinguished by
111  looking at the IEEE 802.3 length field. This field is
112  less than or equal to 1500 for a valid IEEE 802.3 frame
113  and larger than 1500 is it's a valid EtherType value.
114  See RFC 1122, section 2.3.3 for more information */
115 
116  *PacketType = EthHeader->EType;
117  break;
118 
119  default:
120  TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
121 
122  /* FIXME: Support other medias */
124  }
125 
126  TI_DbgPrint(DEBUG_DATALINK, ("EtherType (0x%X).\n", *PacketType));
127 
128  return NDIS_STATUS_SUCCESS;
129 }
130 
131 /* Used by ProtocolReceivePacket for packet type */
134  PNDIS_PACKET NdisPacket,
135  PULONG PacketType)
136 {
137  PVOID HeaderBuffer;
140 
141  HeaderBuffer = ExAllocatePoolWithTag(NonPagedPool,
142  Adapter->HeaderSize,
143  HEADER_TAG);
144  if (!HeaderBuffer)
145  return NDIS_STATUS_RESOURCES;
146 
147  /* Copy the media header */
148  BytesCopied = CopyPacketToBuffer(HeaderBuffer,
149  NdisPacket,
150  0,
151  Adapter->HeaderSize);
152  if (BytesCopied != Adapter->HeaderSize)
153  {
154  /* Runt frame */
155  ExFreePoolWithTag(HeaderBuffer, HEADER_TAG);
156  TI_DbgPrint(DEBUG_DATALINK, ("Runt frame (size %d).\n", BytesCopied));
158  }
159 
161  HeaderBuffer,
162  BytesCopied,
163  PacketType);
164 
165  ExFreePoolWithTag(HeaderBuffer, HEADER_TAG);
166 
167  return Status;
168 }
169 
170 
172  PLAN_ADAPTER Adapter)
173 /*
174  * FUNCTION: Frees memory for a LAN_ADAPTER structure
175  * ARGUMENTS:
176  * Adapter = Pointer to LAN_ADAPTER structure to free
177  */
178 {
180 }
181 
182 
185  NDIS_OID Oid,
186  PULONG Result ) {
187  /* Get maximum frame size */
188  if( Interface->Context ) {
189  return NDISCall((PLAN_ADAPTER)Interface->Context,
191  Oid,
192  Result,
193  sizeof(ULONG));
194  } else switch( Oid ) { /* Loopback Case */
197  return STATUS_SUCCESS;
200  return STATUS_SUCCESS;
201  default:
203  }
204 }
205 
206 
208  NDIS_HANDLE BindingContext,
211 /*
212  * FUNCTION: Called by NDIS to complete opening of an adapter
213  * ARGUMENTS:
214  * BindingContext = Pointer to a device context (LAN_ADAPTER)
215  * Status = Status of the operation
216  * OpenErrorStatus = Additional status information
217  */
218 {
219  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
220 
221  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
222 
223  Adapter->NdisStatus = Status;
224 
225  KeSetEvent(&Adapter->Event, 0, FALSE);
226 }
227 
228 
230  NDIS_HANDLE BindingContext,
232 /*
233  * FUNCTION: Called by NDIS to complete closing an adapter
234  * ARGUMENTS:
235  * BindingContext = Pointer to a device context (LAN_ADAPTER)
236  * Status = Status of the operation
237  */
238 {
239  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
240 
241  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
242 
243  Adapter->NdisStatus = Status;
244 
245  KeSetEvent(&Adapter->Event, 0, FALSE);
246 }
247 
248 
250  NDIS_HANDLE BindingContext,
252 /*
253  * FUNCTION: Called by NDIS to complete resetting an adapter
254  * ARGUMENTS:
255  * BindingContext = Pointer to a device context (LAN_ADAPTER)
256  * Status = Status of the operation
257  */
258 {
259  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
260 
261  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
262 
263  Adapter->NdisStatus = Status;
264 
265  KeSetEvent(&Adapter->Event, 0, FALSE);
266 }
267 
268 
270  NDIS_HANDLE BindingContext,
273 /*
274  * FUNCTION: Called by NDIS to complete a request
275  * ARGUMENTS:
276  * BindingContext = Pointer to a device context (LAN_ADAPTER)
277  * NdisRequest = Pointer to an object describing the request
278  * Status = Status of the operation
279  */
280 {
281  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
282 
283  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
284 
285  /* Save status of request and signal an event */
286  Adapter->NdisStatus = Status;
287 
288  KeSetEvent(&Adapter->Event, 0, FALSE);
289 }
290 
291 
293  NDIS_HANDLE BindingContext,
296 /*
297  * FUNCTION: Called by NDIS to complete sending process
298  * ARGUMENTS:
299  * BindingContext = Pointer to a device context (LAN_ADAPTER)
300  * Packet = Pointer to a packet descriptor
301  * Status = Status of the operation
302  */
303 {
305 }
306 
308  ULONG PacketType;
309  PLAN_WQ_ITEM WorkItem = (PLAN_WQ_ITEM)Context;
311  PLAN_ADAPTER Adapter;
312  UINT BytesTransferred;
313  IP_PACKET IPPacket;
314  BOOLEAN LegacyReceive;
316 
317  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
318 
319  Packet = WorkItem->Packet;
320  Adapter = WorkItem->Adapter;
321  BytesTransferred = WorkItem->BytesTransferred;
322  LegacyReceive = WorkItem->LegacyReceive;
323 
325 
326  Interface = Adapter->Context;
327 
328  IPInitializePacket(&IPPacket, 0);
329 
330  IPPacket.NdisPacket = Packet;
331  IPPacket.ReturnPacket = !LegacyReceive;
332 
333  if (LegacyReceive)
334  {
335  /* Packet type is precomputed */
336  PacketType = PC(IPPacket.NdisPacket)->PacketType;
337 
338  /* Data is at position 0 */
339  IPPacket.Position = 0;
340 
341  /* Packet size is determined by bytes transferred */
342  IPPacket.TotalSize = BytesTransferred;
343  }
344  else
345  {
346  /* Determine packet type from media header */
347  if (GetPacketTypeFromNdisPacket(Adapter,
348  IPPacket.NdisPacket,
349  &PacketType) != NDIS_STATUS_SUCCESS)
350  {
351  /* Bad packet */
352  IPPacket.Free(&IPPacket);
353  return;
354  }
355 
356  /* Data is at the end of the media header */
357  IPPacket.Position = Adapter->HeaderSize;
358 
359  /* Calculate packet size (excluding media header) */
360  NdisQueryPacketLength(IPPacket.NdisPacket, &IPPacket.TotalSize);
361  }
362 
365  ("Ether Type = %x Total = %d\n",
366  PacketType, IPPacket.TotalSize));
367 
368  /* Update interface stats */
369  Interface->Stats.InBytes += IPPacket.TotalSize + Adapter->HeaderSize;
370 
371  /* NDIS packet is freed in all of these cases */
372  switch (PacketType) {
373  case ETYPE_IPv4:
374  case ETYPE_IPv6:
375  TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
376  IPReceive(Adapter->Context, &IPPacket);
377  break;
378  case ETYPE_ARP:
379  TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
380  ARPReceive(Adapter->Context, &IPPacket);
381  break;
382  default:
383  IPPacket.Free(&IPPacket);
384  break;
385  }
386 }
387 
389  NDIS_HANDLE BindingContext,
391  UINT BytesTransferred,
392  BOOLEAN LegacyReceive) {
395  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
396 
397  TI_DbgPrint(DEBUG_DATALINK,("called\n"));
398 
399  if (!WQItem) return;
400 
401  WQItem->Packet = Packet;
402  WQItem->Adapter = Adapter;
403  WQItem->BytesTransferred = BytesTransferred;
404  WQItem->LegacyReceive = LegacyReceive;
405 
406  if (!ChewCreate( LanReceiveWorker, WQItem ))
408 }
409 
411  NDIS_HANDLE BindingContext,
414  UINT BytesTransferred)
415 /*
416  * FUNCTION: Called by NDIS to complete reception of data
417  * ARGUMENTS:
418  * BindingContext = Pointer to a device context (LAN_ADAPTER)
419  * Packet = Pointer to a packet descriptor
420  * Status = Status of the operation
421  * BytesTransferred = Number of bytes transferred
422  * NOTES:
423  * If the packet was successfully received, determine the protocol
424  * type and pass it to the correct receive handler
425  */
426 {
428 
429  TI_DbgPrint(DEBUG_DATALINK,("called\n"));
430 
433 
434  if( Status != NDIS_STATUS_SUCCESS ) return;
435 
436  LanSubmitReceiveWork(BindingContext,
437  Packet,
438  BytesTransferred,
439  TRUE);
440 }
441 
443  NDIS_HANDLE BindingContext,
444  PNDIS_PACKET NdisPacket)
445 {
446  PLAN_ADAPTER Adapter = BindingContext;
447 
448  if (Adapter->State != LAN_STATE_STARTED) {
449  TI_DbgPrint(DEBUG_DATALINK, ("Adapter is stopped.\n"));
450  return 0;
451  }
452 
453  LanSubmitReceiveWork(BindingContext,
454  NdisPacket,
455  0, /* Unused */
456  FALSE);
457 
458  /* Hold 1 reference on this packet */
459  return 1;
460 }
461 
463  NDIS_HANDLE BindingContext,
464  NDIS_HANDLE MacReceiveContext,
465  PVOID HeaderBuffer,
466  UINT HeaderBufferSize,
467  PVOID LookaheadBuffer,
468  UINT LookaheadBufferSize,
470 /*
471  * FUNCTION: Called by NDIS when a packet has been received on the physical link
472  * ARGUMENTS:
473  * BindingContext = Pointer to a device context (LAN_ADAPTER)
474  * MacReceiveContext = Handle used by underlying NIC driver
475  * HeaderBuffer = Pointer to a buffer containing the packet header
476  * HeaderBufferSize = Number of bytes in HeaderBuffer
477  * LookaheadBuffer = Pointer to a buffer containing buffered packet data
478  * LookaheadBufferSize = Size of LookaheadBuffer. May be less than asked for
479  * PacketSize = Overall size of the packet (not including header)
480  * RETURNS:
481  * Status of operation
482  */
483 {
484  ULONG PacketType;
485  UINT BytesTransferred;
486  PCHAR BufferData;
487  NDIS_STATUS NdisStatus;
488  PNDIS_PACKET NdisPacket;
489  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
490 
491  TI_DbgPrint(DEBUG_DATALINK, ("Called. (packetsize %d)\n",PacketSize));
492 
493  if (Adapter->State != LAN_STATE_STARTED) {
494  TI_DbgPrint(DEBUG_DATALINK, ("Adapter is stopped.\n"));
496  }
497 
498  if (HeaderBufferSize < Adapter->HeaderSize) {
499  TI_DbgPrint(DEBUG_DATALINK, ("Runt frame received.\n"));
501  }
502 
503  NdisStatus = GetPacketTypeFromHeaderBuffer(Adapter,
504  HeaderBuffer,
505  HeaderBufferSize,
506  &PacketType);
507  if (NdisStatus != NDIS_STATUS_SUCCESS)
509 
510  TI_DbgPrint(DEBUG_DATALINK, ("Adapter: %x (MTU %d)\n",
511  Adapter, Adapter->MTU));
512 
513  /* Get a transfer data packet */
514  NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL,
515  PacketSize );
516  if( NdisStatus != NDIS_STATUS_SUCCESS ) {
518  }
519 
520  PC(NdisPacket)->PacketType = PacketType;
521 
522  TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d\n",LookaheadBufferSize,PacketSize));
523 
524  GetDataPtr( NdisPacket, 0, &BufferData, &PacketSize );
525 
527 
528  if (LookaheadBufferSize == PacketSize)
529  {
530  /* Optimized code path for packets that are fully contained in
531  * the lookahead buffer. */
532  NdisCopyLookaheadData(BufferData,
533  LookaheadBuffer,
534  LookaheadBufferSize,
535  Adapter->MacOptions);
536  }
537  else
538  {
539  NdisTransferData(&NdisStatus, Adapter->NdisHandle,
540  MacReceiveContext, 0, PacketSize,
541  NdisPacket, &BytesTransferred);
542  }
543  TI_DbgPrint(DEBUG_DATALINK, ("Calling complete\n"));
544 
545  if (NdisStatus != NDIS_STATUS_PENDING)
546  ProtocolTransferDataComplete(BindingContext,
547  NdisPacket,
548  NdisStatus,
549  PacketSize);
550 
551  TI_DbgPrint(DEBUG_DATALINK, ("leaving\n"));
552 
553  return NDIS_STATUS_SUCCESS;
554 }
555 
556 
558  NDIS_HANDLE BindingContext)
559 /*
560  * FUNCTION: Called by NDIS when we're done receiving data
561  * ARGUMENTS:
562  * BindingContext = Pointer to a device context (LAN_ADAPTER)
563  */
564 {
565  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
566 }
567 
569 {
571  HANDLE ParameterHandle;
572  PKEY_VALUE_PARTIAL_INFORMATION KeyValueInfo;
573  ULONG KeyValueInfoLength;
574  WCHAR Buffer[150];
575  UNICODE_STRING IPAddress = RTL_CONSTANT_STRING(L"IPAddress");
576  UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask");
577  UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway");
578  UNICODE_STRING EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP");
579  UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
580  UNICODE_STRING TcpipRegistryPath;
581  UNICODE_STRING RegistryDataU;
582  ANSI_STRING RegistryDataA;
583  ULONG Unused;
585  IP_ADDRESS DefaultMask, Router;
586 
587  AddrInitIPv4(&DefaultMask, 0);
588 
589  TcpipRegistryPath.MaximumLength = sizeof(WCHAR) * 150;
590  TcpipRegistryPath.Length = 0;
591  TcpipRegistryPath.Buffer = Buffer;
592 
593  /* Build the registry path */
594  RtlAppendUnicodeStringToString(&TcpipRegistryPath, &Prefix);
595  RtlAppendUnicodeStringToString(&TcpipRegistryPath, &Interface->Name);
596 
598  &TcpipRegistryPath,
600  0,
601  NULL);
602 
603  /* Open a handle to the adapter parameters */
604  Status = ZwOpenKey(&ParameterHandle, KEY_READ, &ObjectAttributes);
605 
606  if (!NT_SUCCESS(Status))
607  {
608  return FALSE;
609  }
610  else
611  {
612  KeyValueInfoLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 16 * sizeof(WCHAR);
613  KeyValueInfo = ExAllocatePoolWithTag(PagedPool,
614  KeyValueInfoLength,
615  KEY_VALUE_TAG);
616  if (!KeyValueInfo)
617  {
618  ZwClose(ParameterHandle);
619  return FALSE;
620  }
621 
622  /* Read the EnableDHCP entry */
623  Status = ZwQueryValueKey(ParameterHandle,
624  &EnableDhcp,
626  KeyValueInfo,
627  KeyValueInfoLength,
628  &Unused);
629  if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG) && (*(PULONG)KeyValueInfo->Data) == 0)
630  {
631  RegistryDataU.MaximumLength = KeyValueInfoLength - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
632  RegistryDataU.Buffer = (PWCHAR)KeyValueInfo->Data;
633 
634  /* Read the IP address */
635  Status = ZwQueryValueKey(ParameterHandle,
636  &IPAddress,
638  KeyValueInfo,
639  KeyValueInfoLength,
640  &Unused);
641  if (NT_SUCCESS(Status))
642  {
643  RegistryDataU.Length = KeyValueInfo->DataLength;
644 
645  Status = RtlUnicodeStringToAnsiString(&RegistryDataA,
646  &RegistryDataU,
647  TRUE);
648  if (NT_SUCCESS(Status))
649  {
650  AddrInitIPv4(&Interface->Unicast,
651  inet_addr(RegistryDataA.Buffer));
652  RtlFreeAnsiString(&RegistryDataA);
653  }
654  }
655 
656  Status = ZwQueryValueKey(ParameterHandle,
657  &Netmask,
659  KeyValueInfo,
660  KeyValueInfoLength,
661  &Unused);
662  if (NT_SUCCESS(Status))
663  {
664  RegistryDataU.Length = KeyValueInfo->DataLength;
665 
666  Status = RtlUnicodeStringToAnsiString(&RegistryDataA,
667  &RegistryDataU,
668  TRUE);
669  if (NT_SUCCESS(Status))
670  {
671  AddrInitIPv4(&Interface->Netmask,
672  inet_addr(RegistryDataA.Buffer));
673  RtlFreeAnsiString(&RegistryDataA);
674  }
675  }
676 
677  /* We have to wait until both IP address and subnet mask
678  * are read to add the interface route, but we must do it
679  * before we add the default gateway */
680  if (!AddrIsUnspecified(&Interface->Unicast) &&
681  !AddrIsUnspecified(&Interface->Netmask))
683 
684  /* Read default gateway info */
685  Status = ZwQueryValueKey(ParameterHandle,
686  &Gateway,
688  KeyValueInfo,
689  KeyValueInfoLength,
690  &Unused);
691  if (NT_SUCCESS(Status))
692  {
693  RegistryDataU.Length = KeyValueInfo->DataLength;
694 
695  Status = RtlUnicodeStringToAnsiString(&RegistryDataA,
696  &RegistryDataU,
697  TRUE);
698  if (NT_SUCCESS(Status))
699  {
700  AddrInitIPv4(&Router, inet_addr(RegistryDataA.Buffer));
701 
702  if (!AddrIsUnspecified(&Router))
703  RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, Interface, 1);
704 
705  RtlFreeAnsiString(&RegistryDataA);
706  }
707  }
708  }
709 
710  ExFreePoolWithTag(KeyValueInfo, KEY_VALUE_TAG);
711  ZwClose(ParameterHandle);
712  }
713 
714  return TRUE;
715 }
716 
718 {
719  PLAN_ADAPTER Adapter = Context->Adapter;
720  PIP_INTERFACE Interface = Adapter->Context;
721  //NDIS_STATUS NdisStatus;
722  IP_ADDRESS DefaultMask;
723 
724  /* Initialize the default unspecified address (0.0.0.0) */
725  AddrInitIPv4(&DefaultMask, 0);
726  if (Context->State == LAN_STATE_STARTED &&
727  !Context->Adapter->CompletingReset)
728  {
729  /* Read the IP configuration */
731 
732  /* Compute the broadcast address */
733  Interface->Broadcast.Type = IP_ADDRESS_V4;
734  Interface->Broadcast.Address.IPv4Address = Interface->Unicast.Address.IPv4Address |
735  ~Interface->Netmask.Address.IPv4Address;
736  }
737  else if (!Context->Adapter->CompletingReset)
738  {
739  /* Clear IP configuration */
740  Interface->Unicast = DefaultMask;
741  Interface->Netmask = DefaultMask;
742  Interface->Broadcast = DefaultMask;
743 
744  /* Remove all interface routes */
746 
747  /* Destroy all cached neighbors */
749  }
750 
751  Context->Adapter->CompletingReset = FALSE;
752 
753  /* Update the IP and link status information cached in TCP */
756 
757  /* We're done here if the adapter isn't connected */
758  if (Context->State != LAN_STATE_STARTED)
759  {
760  Adapter->State = Context->State;
761  return TRUE;
762  }
763 
764  /* NDIS Bug! */
765 #if 0
766  /* Get maximum link speed */
767  NdisStatus = NDISCall(Adapter,
770  &Interface->Speed,
771  sizeof(UINT));
772 
773  if (!NT_SUCCESS(NdisStatus))
775 
776  Adapter->Speed = Interface->Speed * 100L;
777 
778  /* Get maximum frame size */
779  NdisStatus = NDISCall(Adapter,
782  &Adapter->MTU,
783  sizeof(UINT));
784  if (NdisStatus != NDIS_STATUS_SUCCESS)
785  return FALSE;
786 
787  Interface->MTU = Adapter->MTU;
788 
789  /* Get maximum packet size */
790  NdisStatus = NDISCall(Adapter,
793  &Adapter->MaxPacketSize,
794  sizeof(UINT));
795  if (NdisStatus != NDIS_STATUS_SUCCESS)
796  return FALSE;
797 #endif
798 
799  Adapter->State = Context->State;
800 
801  return TRUE;
802 }
803 
805 {
806  PRECONFIGURE_CONTEXT ReconfigureContext = Context;
807 
808  /* Complete the reconfiguration asynchronously */
809  ReconfigureAdapter(ReconfigureContext);
810 
811  /* Free the context */
812  ExFreePool(ReconfigureContext);
813 }
814 
816  NDIS_HANDLE BindingContext,
820 /*
821  * FUNCTION: Called by NDIS when the underlying driver has changed state
822  * ARGUMENTS:
823  * BindingContext = Pointer to a device context (LAN_ADAPTER)
824  * GeneralStatus = A general status code
825  * StatusBuffer = Pointer to a buffer with medium-specific data
826  * StatusBufferSize = Number of bytes in StatusBuffer
827  */
828 {
829  PLAN_ADAPTER Adapter = BindingContext;
831 
832  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
833 
834  /* Ignore the status indication if we have no context yet. We'll get another later */
835  if (!Adapter->Context)
836  return;
837 
839  if (!Context)
840  return;
841 
842  Context->Adapter = Adapter;
843 
844  switch(GeneralStatus)
845  {
847  DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n");
848 
849  if (Adapter->State == LAN_STATE_STARTED)
850  {
852  return;
853  }
854 
855  Context->State = LAN_STATE_STARTED;
856  break;
857 
859  DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n");
860 
861  if (Adapter->State == LAN_STATE_STOPPED)
862  {
864  return;
865  }
866 
867  Context->State = LAN_STATE_STOPPED;
868  break;
869 
871  Adapter->OldState = Adapter->State;
872  Adapter->State = LAN_STATE_RESETTING;
873  /* Nothing else to do here */
875  return;
876 
878  Adapter->CompletingReset = TRUE;
879  Context->State = Adapter->OldState;
880  break;
881 
882  default:
883  DbgPrint("Unhandled status: %x", GeneralStatus);
885  return;
886  }
887 
888  /* Queue the work item */
891 }
892 
894 /*
895  * FUNCTION: Called by NDIS when a status-change has occurred
896  * ARGUMENTS:
897  * BindingContext = Pointer to a device context (LAN_ADAPTER)
898  */
899 {
900  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
901 }
902 
905  NDIS_HANDLE NdisBindingContext,
906  PNET_PNP_EVENT PnPEvent)
907 {
908  switch(PnPEvent->NetEvent)
909  {
910  case NetEventSetPower:
911  DbgPrint("Device transitioned to power state %ld\n", PnPEvent->Buffer);
912  return NDIS_STATUS_SUCCESS;
913 
914  case NetEventQueryPower:
915  DbgPrint("Device wants to go into power state %ld\n", PnPEvent->Buffer);
916  return NDIS_STATUS_SUCCESS;
917 
919  DbgPrint("Device is about to be removed\n");
920  return NDIS_STATUS_SUCCESS;
921 
923  DbgPrint("Device removal cancelled\n");
924  return NDIS_STATUS_SUCCESS;
925 
926  default:
927  DbgPrint("Unhandled event type: %ld\n", PnPEvent->NetEvent);
928  return NDIS_STATUS_SUCCESS;
929  }
930 }
931 
934  IN NDIS_HANDLE BindContext,
936  IN PVOID SystemSpecific1,
938 /*
939  * FUNCTION: Called by NDIS during NdisRegisterProtocol to set up initial
940  * bindings, and periodically thereafter as new adapters come online
941  * ARGUMENTS:
942  * Status: Return value to NDIS
943  * BindContext: Handle provided by NDIS to track pending binding operations
944  * DeviceName: Name of the miniport device to bind to
945  * SystemSpecific1: Pointer to a registry path with protocol-specific configuration information
946  * SystemSpecific2: Unused & must not be touched
947  */
948 {
949  TI_DbgPrint(DEBUG_DATALINK, ("Called with registry path %wZ for %wZ\n", SystemSpecific1, DeviceName));
950  *Status = LANRegisterAdapter(DeviceName, SystemSpecific1);
951 }
952 
953 
955  PVOID Context,
956  PNDIS_PACKET NdisPacket,
957  UINT Offset,
958  PVOID LinkAddress,
959  USHORT Type)
960 /*
961  * FUNCTION: Transmits a packet
962  * ARGUMENTS:
963  * Context = Pointer to context information (LAN_ADAPTER)
964  * NdisPacket = Pointer to NDIS packet to send
965  * Offset = Offset in packet where data starts
966  * LinkAddress = Pointer to link address of destination (NULL = broadcast)
967  * Type = LAN protocol type (LAN_PROTO_*)
968  */
969 {
970  NDIS_STATUS NdisStatus;
971  PETH_HEADER EHeader;
972  PCHAR Data, OldData;
973  UINT Size, OldSize;
974  PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
975  KIRQL OldIrql;
976  PNDIS_PACKET XmitPacket;
977  PIP_INTERFACE Interface = Adapter->Context;
978 
980  ("Called( NdisPacket %x, Offset %d, Adapter %x )\n",
981  NdisPacket, Offset, Adapter));
982 
983  if (Adapter->State != LAN_STATE_STARTED) {
984  (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_NOT_ACCEPTED);
985  return;
986  }
987 
989  ("Adapter Address [%02x %02x %02x %02x %02x %02x]\n",
990  Adapter->HWAddress[0] & 0xff,
991  Adapter->HWAddress[1] & 0xff,
992  Adapter->HWAddress[2] & 0xff,
993  Adapter->HWAddress[3] & 0xff,
994  Adapter->HWAddress[4] & 0xff,
995  Adapter->HWAddress[5] & 0xff));
996 
997  GetDataPtr( NdisPacket, 0, &OldData, &OldSize );
998 
999  NdisStatus = AllocatePacketWithBuffer(&XmitPacket, NULL, OldSize + Adapter->HeaderSize);
1000  if (NdisStatus != NDIS_STATUS_SUCCESS) {
1001  (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_RESOURCES);
1002  return;
1003  }
1004 
1005  GetDataPtr(XmitPacket, 0, &Data, &Size);
1006 
1007  RtlCopyMemory(Data + Adapter->HeaderSize, OldData, OldSize);
1008 
1009  (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_SUCCESS);
1010 
1011  switch (Adapter->Media) {
1012  case NdisMedium802_3:
1013  EHeader = (PETH_HEADER)Data;
1014 
1015  if (LinkAddress) {
1016  /* Unicast address */
1017  RtlCopyMemory(EHeader->DstAddr, LinkAddress, IEEE_802_ADDR_LENGTH);
1018  } else {
1019  /* Broadcast address */
1020  RtlFillMemory(EHeader->DstAddr, IEEE_802_ADDR_LENGTH, 0xFF);
1021  }
1022 
1023  RtlCopyMemory(EHeader->SrcAddr, Adapter->HWAddress, IEEE_802_ADDR_LENGTH);
1024 
1025  switch (Type) {
1026  case LAN_PROTO_IPv4:
1027  EHeader->EType = ETYPE_IPv4;
1028  break;
1029  case LAN_PROTO_ARP:
1030  EHeader->EType = ETYPE_ARP;
1031  break;
1032  case LAN_PROTO_IPv6:
1033  EHeader->EType = ETYPE_IPv6;
1034  break;
1035  default:
1036  ASSERT(FALSE);
1037  return;
1038  }
1039  break;
1040 
1041  default:
1042  /* FIXME: Support other medias */
1043  break;
1044  }
1045 
1046  TI_DbgPrint( MID_TRACE, ("LinkAddress: %x\n", LinkAddress));
1047  if( LinkAddress ) {
1048  TI_DbgPrint
1049  ( MID_TRACE,
1050  ("Link Address [%02x %02x %02x %02x %02x %02x]\n",
1051  ((PCHAR)LinkAddress)[0] & 0xff,
1052  ((PCHAR)LinkAddress)[1] & 0xff,
1053  ((PCHAR)LinkAddress)[2] & 0xff,
1054  ((PCHAR)LinkAddress)[3] & 0xff,
1055  ((PCHAR)LinkAddress)[4] & 0xff,
1056  ((PCHAR)LinkAddress)[5] & 0xff));
1057  }
1058 
1059  if (Adapter->MTU < Size) {
1060  /* This is NOT a pointer. MSDN explicitly says so. */
1062  TcpLargeSendPacketInfo) = (PVOID)((ULONG_PTR)Adapter->MTU);
1063  }
1064 
1065  /* Update interface stats */
1066  Interface->Stats.OutBytes += Size;
1067 
1068  TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
1069  TI_DbgPrint(MID_TRACE, ("NdisSend\n"));
1070  NdisSend(&NdisStatus, Adapter->NdisHandle, XmitPacket);
1071  TI_DbgPrint(MID_TRACE, ("NdisSend %s\n",
1072  NdisStatus == NDIS_STATUS_PENDING ?
1073  "Pending" : "Complete"));
1074  TcpipReleaseSpinLock( &Adapter->Lock, OldIrql );
1075 
1076  /* I had a talk with vizzini: these really ought to be here.
1077  * we're supposed to see these completed by ndis *only* when
1078  * status_pending is returned. Note that this is different from
1079  * the situation with IRPs. */
1080  if (NdisStatus != NDIS_STATUS_PENDING)
1081  ProtocolSendComplete((NDIS_HANDLE)Context, XmitPacket, NdisStatus);
1082 }
1083 
1084 static NTSTATUS
1087  NTSTATUS Status;
1088 
1090  Status = ZwOpenKey(RegHandle, KEY_ALL_ACCESS, &Attributes);
1091  return Status;
1092 }
1093 
1095  PWCHAR RegistryValue,
1099  NTSTATUS Status;
1101  UCHAR buf[1024];
1103 
1104  RtlInitUnicodeString(&ValueName, RegistryValue);
1105  Status =
1106  ZwQueryValueKey(RegHandle,
1107  &ValueName,
1109  Information,
1110  sizeof(buf),
1111  &ResultLength);
1112 
1113  if (!NT_SUCCESS(Status))
1114  return Status;
1115  /* IP address is stored as a REG_MULTI_SZ - we only pay attention to the first one though */
1116  TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength));
1117 
1118  UnicodeString.Buffer = (PWCHAR)&Information->Data;
1119  UnicodeString.Length = Information->DataLength - sizeof(WCHAR);
1120  UnicodeString.MaximumLength = Information->DataLength;
1121 
1122  String->Buffer =
1124  UnicodeString.MaximumLength + sizeof(WCHAR), REG_STR_TAG );
1125 
1126  if( !String->Buffer ) return STATUS_NO_MEMORY;
1127 
1128  String->MaximumLength = UnicodeString.MaximumLength;
1130 
1131  return STATUS_SUCCESS;
1132 }
1133 
1134 /*
1135  * Utility to copy and append two unicode strings.
1136  *
1137  * IN OUT PUNICODE_STRING ResultFirst -> First string and result
1138  * IN PUNICODE_STRING Second -> Second string to append
1139  * IN BOOL Deallocate -> TRUE: Deallocate First string before
1140  * overwriting.
1141  *
1142  * Returns NTSTATUS.
1143  */
1144 
1147  BOOLEAN Deallocate) {
1148  NTSTATUS Status;
1149  UNICODE_STRING Ustr = *ResultFirst;
1151  (PagedPool,
1152  (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TEMP_STRING_TAG);
1153  if( !new_string ) {
1154  return STATUS_NO_MEMORY;
1155  }
1156  memcpy( new_string, ResultFirst->Buffer, ResultFirst->Length );
1157  memcpy( new_string + ResultFirst->Length / sizeof(WCHAR),
1158  Second->Buffer, Second->Length );
1159  if( Deallocate ) RtlFreeUnicodeString(ResultFirst);
1160  ResultFirst->Length = Ustr.Length + Second->Length;
1161  ResultFirst->MaximumLength = ResultFirst->Length;
1162  new_string[ResultFirst->Length / sizeof(WCHAR)] = 0;
1163  Status = RtlCreateUnicodeString(ResultFirst,new_string) ?
1166  return Status;
1167 }
1168 
1170  PUNICODE_STRING TargetKeyName,
1172  PUNICODE_STRING DeviceDesc ) {
1173  UNICODE_STRING RootDevice = { 0, 0, NULL }, LinkageKeyName = { 0, 0, NULL };
1174  UNICODE_STRING DescKeyName = { 0, 0, NULL }, Linkage = { 0, 0, NULL };
1175  UNICODE_STRING BackSlash = { 0, 0, NULL };
1176  HANDLE DescKey = NULL, LinkageKey = NULL;
1177  NTSTATUS Status;
1178 
1179  TI_DbgPrint(DEBUG_DATALINK,("EnumKeyName %wZ\n", EnumKeyName));
1180 
1182  RtlInitUnicodeString(&Linkage, L"\\Linkage");
1183 
1184  RtlInitUnicodeString(&DescKeyName, L"");
1185  AppendUnicodeString( &DescKeyName, EnumKeyName, FALSE );
1186  AppendUnicodeString( &DescKeyName, &BackSlash, TRUE );
1187  AppendUnicodeString( &DescKeyName, TargetKeyName, TRUE );
1188 
1189  RtlInitUnicodeString(&LinkageKeyName, L"");
1190  AppendUnicodeString( &LinkageKeyName, &DescKeyName, FALSE );
1191  AppendUnicodeString( &LinkageKeyName, &Linkage, TRUE );
1192 
1193  Status = OpenRegistryKey( &LinkageKeyName, &LinkageKey );
1194  if( !NT_SUCCESS(Status) ) goto cleanup;
1195 
1196  Status = ReadStringFromRegistry( LinkageKey, L"RootDevice", &RootDevice );
1197  if( !NT_SUCCESS(Status) ) goto cleanup;
1198 
1199  if( RtlCompareUnicodeString( &RootDevice, Name, TRUE ) == 0 ) {
1200  Status = OpenRegistryKey( &DescKeyName, &DescKey );
1201  if( !NT_SUCCESS(Status) ) goto cleanup;
1202 
1203  Status = ReadStringFromRegistry( DescKey, L"DriverDesc", DeviceDesc );
1204  if( !NT_SUCCESS(Status) ) goto cleanup;
1205 
1206  TI_DbgPrint(DEBUG_DATALINK,("ADAPTER DESC: %wZ\n", DeviceDesc));
1207  } else Status = STATUS_UNSUCCESSFUL;
1208 
1209 cleanup:
1210  RtlFreeUnicodeString( &RootDevice );
1211  RtlFreeUnicodeString( &LinkageKeyName );
1212  RtlFreeUnicodeString( &DescKeyName );
1213  if( LinkageKey ) ZwClose( LinkageKey );
1214  if( DescKey ) ZwClose( DescKey );
1215 
1216  TI_DbgPrint(DEBUG_DATALINK,("Returning %x\n", Status));
1217 
1218  return Status;
1219 }
1220 
1222  PUNICODE_STRING DeviceDesc ) {
1223  UNICODE_STRING EnumKeyName, TargetKeyName;
1224  HANDLE EnumKey;
1225  NTSTATUS Status;
1226  ULONG i;
1227  KEY_BASIC_INFORMATION *Kbio =
1229  ULONG KbioLength = sizeof(KEY_BASIC_INFORMATION), ResultLength;
1230 
1231  RtlInitUnicodeString( DeviceDesc, NULL );
1232 
1233  if( !Kbio ) return STATUS_INSUFFICIENT_RESOURCES;
1234 
1236  (&EnumKeyName, CCS_ROOT L"\\Control\\Class\\" TCPIP_GUID);
1237 
1238  Status = OpenRegistryKey( &EnumKeyName, &EnumKey );
1239 
1240  if( !NT_SUCCESS(Status) ) {
1241  TI_DbgPrint(DEBUG_DATALINK,("Couldn't open Enum key %wZ: %x\n",
1242  &EnumKeyName, Status));
1243  ExFreePoolWithTag( Kbio, KBIO_TAG );
1244  return Status;
1245  }
1246 
1247  for( i = 0; NT_SUCCESS(Status); i++ ) {
1248  Status = ZwEnumerateKey( EnumKey, i, KeyBasicInformation,
1249  Kbio, KbioLength, &ResultLength );
1250 
1252  ExFreePoolWithTag( Kbio, KBIO_TAG );
1253  KbioLength = ResultLength;
1254  Kbio = ExAllocatePoolWithTag( NonPagedPool, KbioLength, KBIO_TAG );
1255  if( !Kbio ) {
1256  TI_DbgPrint(DEBUG_DATALINK,("Failed to allocate memory\n"));
1257  ZwClose( EnumKey );
1258  return STATUS_NO_MEMORY;
1259  }
1260 
1261  Status = ZwEnumerateKey( EnumKey, i, KeyBasicInformation,
1262  Kbio, KbioLength, &ResultLength );
1263 
1264  if( !NT_SUCCESS(Status) ) {
1265  TI_DbgPrint(DEBUG_DATALINK,("Couldn't enum key child %d\n", i));
1266  ZwClose( EnumKey );
1267  ExFreePoolWithTag( Kbio, KBIO_TAG );
1268  return Status;
1269  }
1270  }
1271 
1272  if( NT_SUCCESS(Status) ) {
1273  TargetKeyName.Length = TargetKeyName.MaximumLength =
1274  Kbio->NameLength;
1275  TargetKeyName.Buffer = Kbio->Name;
1276 
1278  ( &EnumKeyName, &TargetKeyName, Name, DeviceDesc );
1279  if( NT_SUCCESS(Status) ) {
1280  ZwClose( EnumKey );
1281  ExFreePoolWithTag( Kbio, KBIO_TAG );
1282  return Status;
1283  } else Status = STATUS_SUCCESS;
1284  }
1285  }
1286 
1287  ZwClose( EnumKey );
1288  ExFreePoolWithTag( Kbio, KBIO_TAG );
1289  return STATUS_UNSUCCESSFUL;
1290 }
1291 
1293  PUNICODE_STRING OutName ) {
1294  PWCHAR Ptr;
1295  UNICODE_STRING PartialRegistryKey;
1296 
1297  PartialRegistryKey.Buffer =
1298  RegistryKey->Buffer + wcslen(CCS_ROOT L"\\Services\\");
1299  Ptr = PartialRegistryKey.Buffer;
1300 
1301  while( *Ptr != L'\\' &&
1302  ((PCHAR)Ptr) < ((PCHAR)RegistryKey->Buffer) + RegistryKey->Length )
1303  Ptr++;
1304 
1305  PartialRegistryKey.Length = PartialRegistryKey.MaximumLength =
1306  (Ptr - PartialRegistryKey.Buffer) * sizeof(WCHAR);
1307 
1308  RtlInitUnicodeString( OutName, L"" );
1309  AppendUnicodeString( OutName, &PartialRegistryKey, FALSE );
1310 }
1311 
1313  PLAN_ADAPTER Adapter,
1315 /*
1316  * FUNCTION: Binds a LAN adapter to IP layer
1317  * ARGUMENTS:
1318  * Adapter = Pointer to LAN_ADAPTER structure
1319  * NOTES:
1320  * We set the lookahead buffer size, set the packet filter and
1321  * bind the adapter to IP layer
1322  */
1323 {
1324  PIP_INTERFACE IF;
1325  NDIS_STATUS NdisStatus;
1326  LLIP_BIND_INFO BindInfo;
1327  ULONG Lookahead = LOOKAHEAD_SIZE;
1328  NTSTATUS Status;
1329  NDIS_MEDIA_STATE MediaState;
1330 
1331  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
1332 
1333  Adapter->State = LAN_STATE_OPENING;
1334 
1335  NdisStatus = NDISCall(Adapter,
1338  &Lookahead,
1339  sizeof(ULONG));
1340  if (NdisStatus != NDIS_STATUS_SUCCESS) {
1341  TI_DbgPrint(DEBUG_DATALINK, ("Could not set lookahead buffer size (0x%X).\n", NdisStatus));
1342  return FALSE;
1343  }
1344 
1345  /* Bind the adapter to IP layer */
1346  BindInfo.Context = Adapter;
1347  BindInfo.HeaderSize = Adapter->HeaderSize;
1348  BindInfo.MinFrameSize = Adapter->MinFrameSize;
1349  BindInfo.Address = (PUCHAR)&Adapter->HWAddress;
1350  BindInfo.AddressLength = Adapter->HWAddressLength;
1351  BindInfo.Transmit = LANTransmit;
1352 
1353  IF = IPCreateInterface(&BindInfo);
1354 
1355  if (!IF) {
1356  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
1357  return FALSE;
1358  }
1359 
1360  /*
1361  * Query per-adapter configuration from the registry
1362  * In case anyone is curious: there *is* an Ndis configuration api
1363  * for this sort of thing, but it doesn't really support things like
1364  * REG_MULTI_SZ very well, and there is a note in the DDK that says that
1365  * protocol drivers developed for win2k and above just use the native
1366  * services (ZwOpenKey, etc).
1367  */
1368 
1369  GetName( RegistryPath, &IF->Name );
1370 
1372  if (!NT_SUCCESS(Status)) {
1373  TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n"));
1374  IPDestroyInterface(IF);
1375  return FALSE;
1376  }
1377 
1378  TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
1379  &IF->Description));
1380 
1381  /* Get maximum link speed */
1382  NdisStatus = NDISCall(Adapter,
1385  &IF->Speed,
1386  sizeof(UINT));
1387 
1388  if (!NT_SUCCESS(NdisStatus))
1390 
1391  Adapter->Speed = IF->Speed * 100L;
1392 
1393  /* Get maximum frame size */
1394  NdisStatus = NDISCall(Adapter,
1397  &Adapter->MTU,
1398  sizeof(UINT));
1399  if (NdisStatus != NDIS_STATUS_SUCCESS)
1400  return FALSE;
1401 
1402  IF->MTU = Adapter->MTU;
1403 
1404  /* Get maximum packet size */
1405  NdisStatus = NDISCall(Adapter,
1408  &Adapter->MaxPacketSize,
1409  sizeof(UINT));
1410  if (NdisStatus != NDIS_STATUS_SUCCESS)
1411  return FALSE;
1412 
1413  /* Register interface with IP layer */
1414  IPRegisterInterface(IF);
1415 
1416  /* Store adapter context */
1417  Adapter->Context = IF;
1418 
1419  /* Get the media state */
1420  NdisStatus = NDISCall(Adapter,
1423  &MediaState,
1424  sizeof(MediaState));
1425  if (NdisStatus != NDIS_STATUS_SUCCESS) {
1426  TI_DbgPrint(DEBUG_DATALINK, ("Could not query media status (0x%X).\n", NdisStatus));
1428  IPDestroyInterface(IF);
1429  return FALSE;
1430  }
1431 
1432  /* Indicate the current media state */
1433  ProtocolStatus(Adapter,
1435  NULL, 0);
1436 
1437  /* Set packet filter so we can send and receive packets */
1438  NdisStatus = NDISCall(Adapter,
1441  &Adapter->PacketFilter,
1442  sizeof(UINT));
1443 
1444  if (NdisStatus != NDIS_STATUS_SUCCESS) {
1445  TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus));
1447  IPDestroyInterface(IF);
1448  return FALSE;
1449  }
1450 
1451  return TRUE;
1452 }
1453 
1454 
1456  PLAN_ADAPTER Adapter)
1457 /*
1458  * FUNCTION: Unbinds a LAN adapter from IP layer
1459  * ARGUMENTS:
1460  * Adapter = Pointer to LAN_ADAPTER structure
1461  */
1462 {
1463  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
1464 
1465  if (Adapter->State == LAN_STATE_STARTED) {
1466  PIP_INTERFACE IF = Adapter->Context;
1467 
1469 
1470  IPDestroyInterface(IF);
1471  }
1472 }
1473 
1474 
1478 /*
1479  * FUNCTION: Registers protocol with an NDIS adapter
1480  * ARGUMENTS:
1481  * AdapterName = Pointer to string with name of adapter to register
1482  * Adapter = Address of pointer to a LAN_ADAPTER structure
1483  * RETURNS:
1484  * Status of operation
1485  */
1486 {
1487  PLAN_ADAPTER IF;
1488  NDIS_STATUS NdisStatus;
1490  UINT MediaIndex;
1492  UINT AddressOID;
1493 
1494  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
1495 
1497  if (!IF) {
1498  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
1499  return NDIS_STATUS_RESOURCES;
1500  }
1501 
1502  RtlZeroMemory(IF, sizeof(LAN_ADAPTER));
1503 
1504  /* Put adapter in stopped state */
1505  IF->State = LAN_STATE_STOPPED;
1506 
1507  /* Initialize protecting spin lock */
1508  KeInitializeSpinLock(&IF->Lock);
1509 
1511 
1512  /* Initialize array with media IDs we support */
1514 
1515  TI_DbgPrint(DEBUG_DATALINK,("opening adapter %wZ\n", AdapterName));
1516  /* Open the adapter. */
1517  NdisOpenAdapter(&NdisStatus,
1518  &OpenStatus,
1519  &IF->NdisHandle,
1520  &MediaIndex,
1521  MediaArray,
1522  MAX_MEDIA,
1524  IF,
1525  AdapterName,
1526  0,
1527  NULL);
1528 
1529  /* Wait until the adapter is opened */
1530  if (NdisStatus == NDIS_STATUS_PENDING)
1532  else if (NdisStatus != NDIS_STATUS_SUCCESS) {
1533  TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName));
1535  return NdisStatus;
1536  }
1537 
1538  IF->Media = MediaArray[MediaIndex];
1539 
1540  /* Fill LAN_ADAPTER structure with some adapter specific information */
1541  switch (IF->Media) {
1542  case NdisMedium802_3:
1544  IF->BCastMask = BCAST_ETH_MASK;
1547  IF->HeaderSize = sizeof(ETH_HEADER);
1548  IF->MinFrameSize = 60;
1549  AddressOID = OID_802_3_CURRENT_ADDRESS;
1550  IF->PacketFilter =
1554  break;
1555 
1556  default:
1557  /* Unsupported media */
1558  TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
1561  }
1562 
1563  /* Get maximum number of packets we can pass to NdisSend(Packets) at one time */
1564  NdisStatus = NDISCall(IF,
1567  &IF->MaxSendPackets,
1568  sizeof(UINT));
1569  if (NdisStatus != NDIS_STATUS_SUCCESS)
1570  /* Legacy NIC drivers may not support this query, if it fails we
1571  assume it can send at least one packet per call to NdisSend(Packets) */
1572  IF->MaxSendPackets = 1;
1573 
1574  /* Get current hardware address */
1575  NdisStatus = NDISCall(IF,
1577  AddressOID,
1578  &IF->HWAddress,
1579  IF->HWAddressLength);
1580  if (NdisStatus != NDIS_STATUS_SUCCESS) {
1581  TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n"));
1583  return NdisStatus;
1584  }
1585 
1586  /* Bind adapter to IP layer */
1587  if( !BindAdapter(IF, RegistryPath) ) {
1588  TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
1590  return NDIS_STATUS_NOT_ACCEPTED;
1591  }
1592 
1593  /* Add adapter to the adapter list */
1595  &IF->ListEntry,
1596  &AdapterListLock);
1597 
1598  TI_DbgPrint(DEBUG_DATALINK, ("Leaving.\n"));
1599 
1600  return NDIS_STATUS_SUCCESS;
1601 }
1602 
1603 
1605  PLAN_ADAPTER Adapter)
1606 /*
1607  * FUNCTION: Unregisters protocol with NDIS adapter
1608  * ARGUMENTS:
1609  * Adapter = Pointer to a LAN_ADAPTER structure
1610  * RETURNS:
1611  * Status of operation
1612  */
1613 {
1614  KIRQL OldIrql;
1615  NDIS_HANDLE NdisHandle;
1616  NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
1617 
1618  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
1619 
1620  /* Unlink the adapter from the list */
1621  RemoveEntryList(&Adapter->ListEntry);
1622 
1623  /* Unbind adapter from IP layer */
1624  UnbindAdapter(Adapter);
1625 
1626  TcpipAcquireSpinLock(&Adapter->Lock, &OldIrql);
1627  NdisHandle = Adapter->NdisHandle;
1628  if (NdisHandle) {
1629  Adapter->NdisHandle = NULL;
1630  TcpipReleaseSpinLock(&Adapter->Lock, OldIrql);
1631 
1632  NdisCloseAdapter(&NdisStatus, NdisHandle);
1633  if (NdisStatus == NDIS_STATUS_PENDING) {
1634  TcpipWaitForSingleObject(&Adapter->Event,
1635  UserRequest,
1636  KernelMode,
1637  FALSE,
1638  NULL);
1639  NdisStatus = Adapter->NdisStatus;
1640  }
1641  } else
1642  TcpipReleaseSpinLock(&Adapter->Lock, OldIrql);
1643 
1644  FreeAdapter(Adapter);
1645 
1646  return NdisStatus;
1647 }
1648 
1649 VOID
1650 NTAPI
1652 /*
1653  * FUNCTION: Unregisters this protocol driver with NDIS
1654  * NOTES: Does not care wether we are already registered
1655  */
1656 {
1657  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
1658 
1659  if (ProtocolRegistered) {
1660  NDIS_STATUS NdisStatus;
1661  PLIST_ENTRY CurrentEntry;
1662  PLIST_ENTRY NextEntry;
1663  PLAN_ADAPTER Current;
1664  KIRQL OldIrql;
1665 
1667 
1668  /* Search the list and remove every adapter we find */
1669  CurrentEntry = AdapterListHead.Flink;
1670  while (CurrentEntry != &AdapterListHead) {
1671  NextEntry = CurrentEntry->Flink;
1672  Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
1673  /* Unregister it */
1674  LANUnregisterAdapter(Current);
1675  CurrentEntry = NextEntry;
1676  }
1677 
1679 
1682  }
1683 }
1684 
1685 VOID
1686 NTAPI
1690  NDIS_HANDLE UnbindContext)
1691 {
1692  /* We don't pend any unbinding so we can just ignore UnbindContext */
1694 }
1695 
1698 /*
1699  * FUNCTION: Registers this protocol driver with NDIS
1700  * ARGUMENTS:
1701  * Name = Name of this protocol driver
1702  * RETURNS:
1703  * Status of operation
1704  */
1705 {
1706  NDIS_STATUS NdisStatus;
1708 
1709  TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
1710 
1713 
1714  /* Set up protocol characteristics */
1715  RtlZeroMemory(&ProtChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
1718  ProtChars.Name.Length = Name->Length;
1719  ProtChars.Name.Buffer = Name->Buffer;
1720  ProtChars.Name.MaximumLength = Name->MaximumLength;
1728  ProtChars.ReceiveHandler = ProtocolReceive;
1730  ProtChars.StatusHandler = ProtocolStatus;
1733  ProtChars.PnPEventHandler = ProtocolPnPEvent;
1736 
1737  /* Try to register protocol */
1738  NdisRegisterProtocol(&NdisStatus,
1740  &ProtChars,
1742  if (NdisStatus != NDIS_STATUS_SUCCESS)
1743  {
1744  TI_DbgPrint(DEBUG_DATALINK, ("NdisRegisterProtocol failed, status 0x%x\n", NdisStatus));
1745  return (NTSTATUS)NdisStatus;
1746  }
1747 
1749 
1750  return STATUS_SUCCESS;
1751 }
1752 
1753 /* EOF */
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE _Out_ PUINT _In_ UINT _In_ NDIS_HANDLE _In_ NDIS_HANDLE ProtocolBindingContext
Definition: ndis.h:6013
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
BOOLEAN AddrIsUnspecified(PIP_ADDRESS Address)
Definition: address.c:113
VOID RouterRemoveRoutesForInterface(PIP_INTERFACE Interface)
Definition: router.c:341
signed char * PCHAR
Definition: retypes.h:7
PVOID Context
Definition: lan.h:64
UINT PacketFilter
Definition: lan.h:80
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
BOOLEAN LegacyReceive
Definition: lan.c:28
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
UINT AddressLength
Definition: ip.h:131
VOID IPDestroyInterface(PIP_INTERFACE IF)
Definition: ip.c:246
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1128
#define IN
Definition: typedefs.h:38
_In_opt_ NDIS_HANDLE _In_opt_ NDIS_HANDLE _Inout_ PNDIS_REQUEST NdisRequest
Definition: ndis.h:1571
#define TRUE
Definition: types.h:120
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID NTAPI ProtocolStatusComplete(NDIS_HANDLE NdisBindingContext)
Called by NDIS when a status-change has occurred.
Definition: lan.c:478
#define MID_TRACE
Definition: debug.h:15
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TEMP_STRING_TAG
Definition: tags.h:42
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_STATUS OpenErrorStatus
Definition: ndis.h:6008
#define inet_addr(cp)
Definition: inet.h:98
Type
Definition: Type.h:6
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
NDIS_STATUS LANRegisterAdapter(PNDIS_STRING AdapterName, PNDIS_STRING RegistryPath)
Registers protocol with an NDIS adapter.
Definition: lan.c:637
VOID NTAPI ProtocolResetComplete(NDIS_HANDLE BindingContext, NDIS_STATUS Status)
Called by NDIS to complete resetting an adapter.
Definition: lan.c:142
enum _NDIS_MEDIUM NDIS_MEDIUM
#define NDIS_VERSION_MAJOR
Definition: lan.h:11
#define DbgPrint
Definition: loader.c:25
VOID NTAPI ProtocolSendComplete(NDIS_HANDLE BindingContext, PNDIS_PACKET Packet, NDIS_STATUS Status)
Called by NDIS to complete sending process.
Definition: lan.c:184
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
REQUEST_COMPLETE_HANDLER RequestCompleteHandler
Definition: ndis.h:1887
UNICODE_STRING Description
Definition: ip.h:164
VOID IPUnregisterInterface(PIP_INTERFACE IF)
Definition: ip.c:353
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
VOID EXPORT NdisRegisterProtocol(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE NdisProtocolHandle, IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics, IN UINT CharacteristicsLength)
Definition: protocol.c:1113
#define KEY_READ
Definition: nt_native.h:1023
UINT MinFrameSize
Definition: ip.h:129
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ NDIS_STATUS _In_ NDIS_STATUS OpenStatus
Definition: ndis.h:6034
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
void GetDataPtr(PNDIS_PACKET Packet, UINT Offset, PCHAR *DataOut, PUINT Size)
Definition: routines.c:65
WCHAR Second[]
Definition: FormatMessage.c:12
#define DEBUG_DATALINK
Definition: debug.h:24
#define ETYPE_IPv6
Definition: lan.h:122
unsigned char * PUCHAR
Definition: retypes.h:3
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
VOID NBDestroyNeighborsForInterface(PIP_INTERFACE Interface)
Definition: neighbor.c:237
UCHAR BCastOffset
Definition: lan.h:72
enum _NDIS_MEDIA_STATE NDIS_MEDIA_STATE
PVOID Context
Definition: ip.h:127
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ProtocolCloseAdapterComplete(NDIS_HANDLE BindingContext, NDIS_STATUS Status)
Called by NDIS to complete closing an adapter.
Definition: lan.c:120
struct _KEY_BASIC_INFORMATION KEY_BASIC_INFORMATION
* PNDIS_STATUS
Definition: ndis.h:45
ULONG NDIS_OID
Definition: ntddndis.h:204
VOID FreeAdapter(PLAN_ADAPTER Adapter)
Frees memory for a LAN_ADAPTER structure.
Definition: lan.c:83
UCHAR OldState
Definition: lan.h:42
#define NDIS_STATUS_RESET_START
Definition: ndis.h:354
#define OID_GEN_CURRENT_PACKET_FILTER
Definition: ntddndis.h:220
VOID EXPORT NdisDeregisterProtocol(OUT PNDIS_STATUS Status, IN NDIS_HANDLE NdisProtocolHandle)
Definition: protocol.c:732
UINT Speed
Definition: lan.h:79
#define FreeNdisPacket(x)
Definition: memtrack.h:8
UINT HWAddressLength
Definition: lan.h:69
#define OID_GEN_HARDWARE_STATUS
Definition: ntddndis.h:208
UNBIND_HANDLER UnbindAdapterHandler
Definition: ndis.h:1898
PIP_INTERFACE IPCreateInterface(PLLIP_BIND_INFO BindInfo)
Definition: ip.c:182
static WCHAR String[]
Definition: stringtable.c:55
CLOSE_ADAPTER_COMPLETE_HANDLER CloseAdapterCompleteHandler
Definition: ndis.h:1877
_In_opt_ NDIS_HANDLE _In_ NDIS_STATUS GeneralStatus
Definition: ndis.h:1555
UNICODE_STRING Name
Definition: ip.h:163
UINT MinFrameSize
Definition: lan.h:75
uint16_t * PWCHAR
Definition: typedefs.h:54
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define LOOKAHEAD_SIZE
Definition: lan.h:117
UINT BytesTransferred
Definition: lan.c:27
#define ETYPE_ARP
Definition: lan.h:123
OBJECT_FREE_ROUTINE Free
Definition: ip.h:78
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
RECEIVE_COMPLETE_HANDLER ReceiveCompleteHandler
Definition: ndis.h:1892
VOID TcpipReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL Irql)
Definition: lock.c:26
#define LAN_STATE_STOPPED
Definition: lan.h:114
NDIS_STATUS NDISCall(PLAN_ADAPTER Adapter, NDIS_REQUEST_TYPE Type, NDIS_OID OID, PVOID Buffer, UINT Length)
Send a request to NDIS.
Definition: lan.c:29
PUCHAR Address
Definition: ip.h:130
int32_t INT
Definition: typedefs.h:56
PLAN_ADAPTER Adapter
Definition: lan.c:26
VOID TcpipAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL Irql)
Definition: lock.c:18
VOID NTAPI ProtocolBindAdapter(OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2)
Called by NDIS during NdisRegisterProtocol to set up initial bindings, and periodically thereafter as...
Definition: lan.c:497
VOID LANUnregisterProtocol(VOID)
Unregisters this protocol driver with NDIS.
Definition: lan.c:943
PNDIS_PACKET Packet
Definition: lan.c:25
LL_TRANSMIT_ROUTINE Transmit
Definition: ip.h:132
STATUS_HANDLER StatusHandler
Definition: ndis.h:1893
VOID LANTransmit(PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket, PVOID LinkAddress, USHORT Type)
Transmits a packet ARGUMENTS:
Definition: lan.c:520
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
int NDIS_STATUS
Definition: ntddndis.h:445
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define NDIS_STATUS_NOT_SUPPORTED
Definition: ndis.h:479
Definition: ip.h:23
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
#define NDIS_VERSION_MINOR
Definition: lan.h:12
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
NDIS_STATUS NTAPI ProtocolReceive(NDIS_HANDLE BindingContext, NDIS_HANDLE MacReceiveContext, PVOID HeaderBuffer, UINT HeaderBufferSize, PVOID LookaheadBuffer, UINT LookaheadBufferSize, UINT PacketSize)
Called by NDIS when a packet has been received on the physical link.
Definition: lan.c:355
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LIST_ENTRY ListEntry
Definition: lan.h:57
VOID NTAPI ProtocolStatus(NDIS_HANDLE BindingContext, NDIS_STATUS GenerelStatus, PVOID StatusBuffer, UINT StatusBufferSize)
Called by NDIS when the underlying driver has changed state.
Definition: lan.c:461
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
VOID TCPUpdateInterfaceLinkStatus(PIP_INTERFACE IF)
Definition: if.c:81
#define IP_ADDRESS_V4
Definition: ip.h:32
NDIS_STATUS LANUnregisterAdapter(PLAN_ADAPTER Adapter)
Unregisters protocol with NDIS adapter.
Definition: lan.c:847
UCHAR BCastCheck
Definition: lan.h:71
PIP_PACKET IPInitializePacket(PIP_PACKET IPPacket, ULONG Type)
Definition: ip.c:92
#define OID_GEN_MEDIA_CONNECT_STATUS
Definition: ntddndis.h:226
USHORT MTU
Definition: lan.h:74
UCHAR BCastMask
Definition: lan.h:70
NDIS_STATUS NdisStatus
Definition: lan.h:66
VOID EXPORT NdisSend(OUT PNDIS_STATUS Status, IN NDIS_HANDLE NdisBindingHandle, IN PNDIS_PACKET Packet)
Definition: protocol.c:1270
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
#define AllocatePacketWithBuffer(x, y, z)
Definition: memtrack.h:7
UNLOAD_PROTOCOL_HANDLER UnloadHandler
Definition: ndis.h:1900
unsigned char BOOLEAN
_In_ UINT _In_ UINT _In_ PNDIS_PACKET _In_ UINT _Out_ PUINT BytesCopied
Definition: ndis.h:3167
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
BIND_HANDLER BindAdapterHandler
Definition: ndis.h:1897
#define MEDIA_ETH
Definition: lan.h:26
#define LAN_PROTO_ARP
Definition: lan.h:128
BOOLEAN IPRegisterInterface(PIP_INTERFACE IF)
Definition: ip.c:293
Definition: bufpool.h:45
#define PC(Packet)
Definition: ip.h:106
_In_opt_ PETWENABLECALLBACK _In_opt_ PVOID _Out_ PREGHANDLE RegHandle
Definition: wmifuncs.h:76
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
RESET_COMPLETE_HANDLER ResetCompleteHandler
Definition: ndis.h:1886
void * PVOID
Definition: retypes.h:9
UINT MTU
Definition: ip.h:157
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
OPEN_ADAPTER_COMPLETE_HANDLER OpenAdapterCompleteHandler
Definition: ndis.h:1876
VOID ARPReceive(PVOID Context, PIP_PACKET Packet)
Definition: arp.c:175
BOOLEAN ChewCreate(VOID(*Worker)(PVOID), PVOID WorkerContext)
Definition: workqueue.c:65
NTSTATUS LANRegisterProtocol(PNDIS_STRING Name)
Registers this protocol driver with NDIS.
Definition: lan.c:893
#define LAN_STATE_RESETTING
Definition: lan.h:112
PVOID NDIS_HANDLE
Definition: ndis.h:338
#define NDIS_STATUS_MEDIA_CONNECT
Definition: ndis.h:361
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
struct LAN_ADAPTER * PLAN_ADAPTER
#define LAN_PROTO_IPv4
Definition: lan.h:126
NDIS_MEDIUM Media
Definition: lan.h:67
#define OID_GEN_MAXIMUM_FRAME_SIZE
Definition: ntddndis.h:212
#define NDIS_STATUS_NOT_ACCEPTED
Definition: ndis.h:350
TRANSFER_DATA_COMPLETE_HANDLER TransferDataCompleteHandler
Definition: ndis.h:1883
struct _ETH_HEADER ETH_HEADER
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define OID_GEN_MAXIMUM_TOTAL_SIZE
Definition: ntddndis.h:223
#define NdisCopyLookaheadData(Destination, Source, Length, MacOptions)
Definition: ndis.h:3289
#define CONTEXT_TAG
Definition: tags.h:43
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UINT HeaderSize
Definition: ip.h:128
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define IEEE_802_ADDR_LENGTH
Definition: e1000hw.h:11
#define AddrInitIPv4(IPAddress, RawAddress)
Definition: address.h:16
struct _ETH_HEADER * PETH_HEADER
KSPIN_LOCK Lock
Definition: lan.h:60
#define KEY_VALUE_TAG
Definition: tags.h:44
UINT Position
Definition: ip.h:87
#define LAN_STATE_OPENING
Definition: lan.h:111
UINT TotalSize
Definition: ip.h:86
LIST_ENTRY ListEntry
Definition: lan.c:24
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
UCHAR HeaderSize
Definition: lan.h:73
#define ETYPE_IPv4
Definition: lan.h:121
#define LAN_ADAPTER_TAG
Definition: tags.h:36
RECEIVE_PACKET_HANDLER ReceivePacketHandler
Definition: ndis.h:1896
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define NDIS_PACKET_TYPE_MULTICAST
Definition: ndis.h:664
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
UINT64 OID
Definition: marshal.c:88
UINT MacOptions
Definition: lan.h:78
STATUS_COMPLETE_HANDLER StatusCompleteHandler
Definition: ndis.h:1894
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID IPAddInterfaceRoute(PIP_INTERFACE IF)
Definition: ip.c:266
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define IP_DEFAULT_LINK_SPEED
Definition: ip.h:201
unsigned char UCHAR
Definition: xmlstorage.h:181
static void new_string(void)
Definition: ppl.yy.c:4182
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define BCAST_ETH_CHECK
Definition: lan.h:45
static const WCHAR L[]
Definition: oid.c:1250
#define BCAST_ETH_MASK
Definition: lan.h:42
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
RECEIVE_HANDLER ReceiveHandler
Definition: ndis.h:1889
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
UINT Speed
Definition: ip.h:158
_In_ PVOID _In_ PVOID SystemSpecific2
Definition: ndis.h:637
Definition: typedefs.h:117
NTSTATUS TcpipWaitForSingleObject(PVOID Object, KWAIT_REASON Reason, KPROCESSOR_MODE WaitMode, BOOLEAN Alertable, PLARGE_INTEGER Timeout)
Definition: mockwait.c:12
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
NDIS_HANDLE NdisHandle
Definition: lan.h:65
VOID BindAdapter(PLAN_ADAPTER Adapter, PNDIS_STRING RegistryPath)
Binds a LAN adapter to IP layer.
Definition: lan.c:617
PFIB_ENTRY RouterCreateRoute(PIP_ADDRESS NetworkAddress, PIP_ADDRESS Netmask, PIP_ADDRESS RouterAddress, PIP_INTERFACE Interface, UINT Metric)
Definition: router.c:421
VOID NTAPI ProtocolRequestComplete(NDIS_HANDLE BindingContext, PNDIS_REQUEST NdisRequest, NDIS_STATUS Status)
Called by NDIS to complete a request.
Definition: lan.c:159
Status
Definition: gdiplustypes.h:24
#define OID_GEN_LINK_SPEED
Definition: ntddndis.h:213
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
UCHAR HWAddress[IEEE_802_ADDR_LENGTH]
Definition: lan.h:68
KEVENT Event
Definition: lan.h:63
PVOID Buffer
Definition: netpnp.h:33
SEND_COMPLETE_HANDLER SendCompleteHandler
Definition: ndis.h:1879
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define OID_GEN_MAXIMUM_SEND_PACKETS
Definition: ntddndis.h:227
enum _NDIS_REQUEST_TYPE NDIS_REQUEST_TYPE
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_opt_ NDIS_HANDLE _In_ NDIS_STATUS _In_ PVOID _In_ UINT StatusBufferSize
Definition: ndis.h:1555
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
_In_ USHORT PacketSize
Definition: iofuncs.h:1056
#define WQ_CONTEXT_TAG
Definition: tags.h:37
unsigned short USHORT
Definition: pedump.c:61
UINT CopyPacketToBuffer(PUCHAR DstData, PNDIS_PACKET SrcPacket, UINT SrcOffset, UINT Length)
Definition: buffer.c:170
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID IPReceive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
Definition: receive.c:638
#define NDIS_STATUS_RESET_END
Definition: ndis.h:355
UCHAR State
Definition: lan.h:62
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
VOID EXPORT NdisOpenAdapter(OUT PNDIS_STATUS Status, OUT PNDIS_STATUS OpenErrorStatus, OUT PNDIS_HANDLE NdisBindingHandle, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE NdisProtocolHandle, IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_STRING AdapterName, IN UINT OpenOptions, IN PSTRING AddressingInformation OPTIONAL)
Definition: protocol.c:762
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define NdisQueryPacketLength(_Packet, _TotalPacketLength)
Definition: ndis.h:3645
#define BCAST_ETH_OFFSET
Definition: lan.h:48
BOOLEAN ReturnPacket
Definition: ip.h:82
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
PNDIS_PACKET NdisPacket
Definition: ip.h:88
_In_opt_ NDIS_HANDLE _In_ NDIS_STATUS _In_ PVOID StatusBuffer
Definition: ndis.h:1555
#define HEADER_TAG
Definition: tags.h:45
NET_PNP_EVENT_CODE NetEvent
Definition: netpnp.h:32
VOID EXPORT NdisCloseAdapter(OUT PNDIS_STATUS Status, IN NDIS_HANDLE NdisBindingHandle)
Definition: protocol.c:701
#define OUT
Definition: typedefs.h:39
BOOLEAN CompletingReset
Definition: lan.h:43
struct tagContext Context
Definition: acpixf.h:1012
UINT MaxSendPackets
Definition: lan.h:77
#define NDIS_STATUS_RESOURCES
Definition: ndis.h:466
unsigned int ULONG
Definition: retypes.h:1
#define LAN_PROTO_IPv6
Definition: lan.h:127
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define MIN_TRACE
Definition: debug.h:14
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
char * cleanup(char *str)
Definition: wpickclick.c:99
#define OID_802_3_CURRENT_ADDRESS
Definition: ntddndis.h:277
Definition: ip.h:77
VOID NTAPI ProtocolOpenAdapterComplete(NDIS_HANDLE BindingContext, NDIS_STATUS Status, NDIS_STATUS OpenErrorStatus)
Called by NDIS to complete opening of an adapter.
Definition: lan.c:99
#define LAN_STATE_STARTED
Definition: lan.h:113
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PLAN_ADAPTER Adapter
Definition: lan.c:33
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE _Out_ PUINT _In_ UINT _In_ NDIS_HANDLE _In_ NDIS_HANDLE _In_ PNDIS_STRING AdapterName
Definition: ndis.h:6013
static const WCHAR BackSlash[]
Definition: devclass.c:29
return STATUS_SUCCESS
Definition: btrfs.c:2745
VOID NTAPI ProtocolReceiveComplete(NDIS_HANDLE BindingContext)
Called by NDIS when we're done receiving data.
Definition: lan.c:444
VOID TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF)
Definition: if.c:145
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
VOID EXPORT NdisTransferData(OUT PNDIS_STATUS Status, IN NDIS_HANDLE NdisBindingHandle, IN NDIS_HANDLE MacReceiveContext, IN UINT ByteOffset, IN UINT BytesToTransfer, IN OUT PNDIS_PACKET Packet, OUT PUINT BytesTransferred)
Definition: protocol.c:1305
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define MAX_MEDIA
Definition: lan.h:28
#define NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, InfoType)
Definition: ndis.h:1351
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define NDIS_STATUS_MEDIA_DISCONNECT
Definition: ndis.h:362
#define OID_GEN_CURRENT_LOOKAHEAD
Definition: ntddndis.h:221
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI ProtocolTransferDataComplete(NDIS_HANDLE BindingContext, PNDIS_PACKET Packet, NDIS_STATUS Status, UINT BytesTransferred)
Called by NDIS to complete reception of data.
Definition: lan.c:210
static NDIS_MEDIUM MediaArray[MEDIA_ARRAY_SIZE]
Definition: miniport.c:33
PNP_EVENT_HANDLER PnPEventHandler
Definition: ndis.h:1899
Iosb Information
Definition: create.c:4377
#define NDIS_PACKET_TYPE_DIRECTED
Definition: ndis.h:663
#define REG_STR_TAG
Definition: tags.h:46
UINT MaxPacketSize
Definition: lan.h:76
#define NDIS_PACKET_TYPE_BROADCAST
Definition: ndis.h:666
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define KBIO_TAG
Definition: tags.h:41