main.c

来自「一个类似windows」· C语言 代码 · 共 919 行 · 第 1/2 页

C
919
字号

  case TDI_RECEIVE_DATAGRAM:
    Status = DispTdiReceiveDatagram(Irp);
    Complete = FALSE;
    break;

  case TDI_SEND:
    Status = DispTdiSend(Irp);
    Complete = FALSE; /* Completed in DispTdiSend */
    break;

  case TDI_SEND_DATAGRAM:
    Status = DispTdiSendDatagram(Irp);
    Complete = FALSE;
    break;

  case TDI_ACCEPT:
    Status = DispTdiAccept(Irp);
    break;

  case TDI_LISTEN:
    Status = DispTdiListen(Irp);
    Complete = FALSE;
    break;

  case TDI_CONNECT:
    Status = DispTdiConnect(Irp);
    Complete = FALSE; /* Completed by the TCP event handler */
    break;

  case TDI_DISCONNECT:
    Status = DispTdiDisconnect(Irp);
    break;

  case TDI_ASSOCIATE_ADDRESS:
    Status = DispTdiAssociateAddress(Irp);
    break;

  case TDI_DISASSOCIATE_ADDRESS:
    Status = DispTdiDisassociateAddress(Irp);
    break;

  case TDI_QUERY_INFORMATION:
    Status = DispTdiQueryInformation(DeviceObject, Irp);
    break;

  case TDI_SET_INFORMATION:
    Status = DispTdiSetInformation(Irp);
    break;

  case TDI_SET_EVENT_HANDLER:
    Status = DispTdiSetEventHandler(Irp);
    break;

  case TDI_ACTION:
    Status = STATUS_SUCCESS;
    break;

  /* An unsupported IOCTL code was submitted */
  default:
    Status = STATUS_INVALID_DEVICE_REQUEST;
  }

  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));

  if( Complete )
      IRPFinish( Irp, Status );

  return Status;
}


NTSTATUS
#ifndef _MSC_VER
STDCALL
#endif
TiDispatch(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp)
/*
 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
 * ARGUMENTS:
 *     DeviceObject = Pointer to a device object for this driver
 *     Irp          = Pointer to a I/O request packet
 * RETURNS:
 *     Status of the operation
 */
{
  NTSTATUS Status;
  PIO_STACK_LOCATION IrpSp;

  RIRP(Irp);

  IrpSp  = IoGetCurrentIrpStackLocation(Irp);

  TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));

  Irp->IoStatus.Information = 0;

#ifdef _MSC_VER
  Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
  if (NT_SUCCESS(Status)) {
    TiDispatchInternal(DeviceObject, Irp);
    Status = STATUS_PENDING;
  } else {
#else
  if (TRUE) {
#endif
    /* See if this request is TCP/IP specific */
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_TCP_QUERY_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
      Status = DispTdiQueryInformationEx(Irp, IrpSp);
      break;

    case IOCTL_TCP_SET_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
      Status = DispTdiSetInformationEx(Irp, IrpSp);
      break;

    case IOCTL_SET_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
      Status = DispTdiSetIPAddress(Irp, IrpSp);
      break;

    case IOCTL_DELETE_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
      Status = DispTdiDeleteIPAddress(Irp, IrpSp);
      break;

    default:
      TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
          IrpSp->Parameters.DeviceIoControl.IoControlCode));
      Status = STATUS_NOT_IMPLEMENTED;
      break;
    }
  }

  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));

  return IRPFinish( Irp, Status );
}


VOID STDCALL TiUnload(
  PDRIVER_OBJECT DriverObject)
/*
 * FUNCTION: Unloads the driver
 * ARGUMENTS:
 *     DriverObject = Pointer to driver object created by the system
 */
{
#ifdef DBG
  KIRQL OldIrql;

  TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
  if (!IsListEmpty(&AddressFileListHead)) {
    TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
  }
  TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
  ChewShutdown();

  /* Cancel timer */
  KeCancelTimer(&IPTimer);

  /* Unregister loopback adapter */
  LoopUnregisterAdapter(NULL);

  /* Unregister protocol with NDIS */
  LANUnregisterProtocol();

  /* Shutdown transport level protocol subsystems */
  TCPShutdown();
  UDPShutdown();
  RawIPShutdown();

  /* Shutdown network level protocol subsystem */
  IPShutdown();

  /* Shutdown the lan worker */
  LANShutdown();

  /* Free NDIS buffer descriptors */
  if (GlobalBufferPool)
    NdisFreeBufferPool(GlobalBufferPool);

  /* Free NDIS packet descriptors */
  if (GlobalPacketPool)
    NdisFreePacketPool(GlobalPacketPool);

  /* Release all device objects */

  if (TCPDeviceObject)
    IoDeleteDevice(TCPDeviceObject);

  if (UDPDeviceObject)
    IoDeleteDevice(UDPDeviceObject);

  if (RawIPDeviceObject)
    IoDeleteDevice(RawIPDeviceObject);

  if (IPDeviceObject)
    IoDeleteDevice(IPDeviceObject);

  if (EntityList)
    PoolFreeBuffer(EntityList);

  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}

VOID STDCALL IPTimeoutDpcFn(
    PKDPC Dpc,
    PVOID DeferredContext,
    PVOID SystemArgument1,
    PVOID SystemArgument2)
/*
 * FUNCTION: Timeout DPC
 * ARGUMENTS:
 *     Dpc             = Pointer to our DPC object
 *     DeferredContext = Pointer to context information (unused)
 *     SystemArgument1 = Unused
 *     SystemArgument2 = Unused
 * NOTES:
 *     This routine is dispatched once in a while to do maintainance jobs
 */
{
    if( !IpWorkItemQueued ) {
	ExQueueWorkItem( &IpWorkItem, CriticalWorkQueue );
	IpWorkItemQueued = TRUE;
    }
}

NTSTATUS
#ifndef _MSC_VER
STDCALL
#endif
DriverEntry(
  PDRIVER_OBJECT DriverObject,
  PUNICODE_STRING RegistryPath)
/*
 * FUNCTION: Main driver entry point
 * ARGUMENTS:
 *     DriverObject = Pointer to a driver object for this driver
 *     RegistryPath = Registry node for configuration parameters
 * RETURNS:
 *     Status of driver initialization
 */
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;

  TI_DbgPrint(MAX_TRACE, ("Called.\n"));

  TrackingInit();
  TrackTag(NDIS_BUFFER_TAG);
  TrackTag(NDIS_PACKET_TAG);
  TrackTag(FBSD_MALLOC);
  TrackTag(EXALLOC_TAG);

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    return Status;
  }

  ChewInit( IPDeviceObject );

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES );
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityList[0].tei_entity   = CL_NL_ENTITY;
  EntityList[0].tei_instance = 0;
  EntityList[0].context      = 0;
  EntityList[0].info_req     = InfoNetworkLayerTdiQueryEx;
  EntityList[0].info_set     = InfoNetworkLayerTdiSetEx;
  EntityList[1].tei_entity   = CL_TL_ENTITY;
  EntityList[1].tei_instance = 0;
  EntityList[1].context      = 0;
  EntityList[1].info_req     = InfoTransportLayerTdiQueryEx;
  EntityList[1].info_set     = InfoTransportLayerTdiSetEx;
  EntityCount = 2;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPool(&NdisStatus, &GlobalPacketPool, 100, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 100);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);

  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  RawIPStartup();
  UDPStartup();
  TCPStartup();

  /* Initialize the lan worker */
  LANStartup();

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
    TiUnload(DriverObject);
    return Status;
  }

  /* Open loopback adapter */
  if (!NT_SUCCESS(LoopRegisterAdapter(NULL, NULL))) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL );
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  return STATUS_SUCCESS;
}


VOID
#ifndef _MSC_VER
STDCALL
#endif
IPAddInterface(
	DWORD	Unknown0,
	DWORD	Unknown1,
	DWORD	Unknown2,
	DWORD	Unknown3,
	DWORD	Unknown4)
{
    UNIMPLEMENTED
}


VOID
#ifndef _MSC_VER
STDCALL
#endif
IPDelInterface(
	DWORD	Unknown0)
{
    UNIMPLEMENTED
}


VOID
#ifndef _MSC_VER
STDCALL
#endif
LookupRoute(
	DWORD	Unknown0,
	DWORD	Unknown1)
{
    UNIMPLEMENTED
}

/* EOF */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?