ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

main.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS TCP/IP protocol driver
00004  * FILE:        tcpip/main.c
00005  * PURPOSE:     Driver entry point
00006  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
00007  * REVISIONS:
00008  *   CSH 01/08-2000 Created
00009  */
00010 #include "precomp.h"
00011 
00012 PDEVICE_OBJECT TCPDeviceObject   = NULL;
00013 PDEVICE_OBJECT UDPDeviceObject   = NULL;
00014 PDEVICE_OBJECT IPDeviceObject    = NULL;
00015 PDEVICE_OBJECT RawIPDeviceObject = NULL;
00016 NDIS_HANDLE GlobalPacketPool     = NULL;
00017 NDIS_HANDLE GlobalBufferPool     = NULL;
00018 KSPIN_LOCK EntityListLock;
00019 TDIEntityInfo *EntityList        = NULL;
00020 ULONG EntityCount                = 0;
00021 ULONG EntityMax                  = 0;
00022 UDP_STATISTICS UDPStats;
00023 
00024 /* Network timers */
00025 KTIMER IPTimer;
00026 KDPC IPTimeoutDpc;
00027 
00028 VOID TiWriteErrorLog(
00029     PDRIVER_OBJECT DriverContext,
00030     NTSTATUS ErrorCode,
00031     ULONG UniqueErrorValue,
00032     NTSTATUS FinalStatus,
00033     PWSTR String,
00034     ULONG DumpDataCount,
00035     PULONG DumpData)
00036 /*
00037  * FUNCTION: Writes an error log entry
00038  * ARGUMENTS:
00039  *     DriverContext    = Pointer to the driver or device object
00040  *     ErrorCode        = An error code to put in the log entry
00041  *     UniqueErrorValue = UniqueErrorValue in the error log packet
00042  *     FinalStatus      = FinalStatus in the error log packet
00043  *     String           = If not NULL, a pointer to a string to put in log
00044  *                        entry
00045  *     DumpDataCount    = Number of ULONGs of dump data
00046  *     DumpData         = Pointer to dump data for the log entry
00047  */
00048 {
00049 #if 0
00050     PIO_ERROR_LOG_PACKET LogEntry;
00051     UCHAR EntrySize;
00052     ULONG StringSize;
00053     PUCHAR pString;
00054     static WCHAR DriverName[] = L"TCP/IP";
00055 
00056     EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
00057         (DumpDataCount * sizeof(ULONG)) + sizeof(DriverName);
00058 
00059     if (String) {
00060         StringSize = (wcslen(String) * sizeof(WCHAR)) + sizeof(UNICODE_NULL);
00061         EntrySize += (UCHAR)StringSize;
00062     }
00063 
00064     LogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
00065         DriverContext, EntrySize);
00066 
00067     if (LogEntry) {
00068         LogEntry->MajorFunctionCode = -1;
00069         LogEntry->RetryCount        = -1;
00070         LogEntry->DumpDataSize      = (USHORT)(DumpDataCount * sizeof(ULONG));
00071         LogEntry->NumberOfStrings   = (String == NULL) ? 1 : 2;
00072         LogEntry->StringOffset      = sizeof(IO_ERROR_LOG_PACKET) + (DumpDataCount-1) * sizeof(ULONG);
00073         LogEntry->EventCategory     = 0;
00074         LogEntry->ErrorCode         = ErrorCode;
00075         LogEntry->UniqueErrorValue  = UniqueErrorValue;
00076         LogEntry->FinalStatus       = FinalStatus;
00077         LogEntry->SequenceNumber    = -1;
00078         LogEntry->IoControlCode     = 0;
00079 
00080         if (DumpDataCount)
00081             RtlCopyMemory(LogEntry->DumpData, DumpData, DumpDataCount * sizeof(ULONG));
00082 
00083         pString = ((PUCHAR)LogEntry) + LogEntry->StringOffset;
00084         RtlCopyMemory(pString, DriverName, sizeof(DriverName));
00085         pString += sizeof(DriverName);
00086 
00087         if (String)
00088             RtlCopyMemory(pString, String, StringSize);
00089 
00090         IoWriteErrorLogEntry(LogEntry);
00091     }
00092 #endif
00093 }
00094 
00095 /*
00096  * FUNCTION: Creates a file object
00097  * ARGUMENTS:
00098  *     DeviceObject = Pointer to a device object for this driver
00099  *     Irp          = Pointer to a I/O request packet
00100  * RETURNS:
00101  *     Status of the operation
00102  */
00103 
00104 NTSTATUS TiCreateFileObject(
00105   PDEVICE_OBJECT DeviceObject,
00106   PIRP Irp)
00107 {
00108     PFILE_FULL_EA_INFORMATION EaInfo;
00109     PTRANSPORT_CONTEXT Context;
00110     PIO_STACK_LOCATION IrpSp;
00111     PTA_IP_ADDRESS Address;
00112     TDI_REQUEST Request;
00113     PVOID ClientContext;
00114     NTSTATUS Status;
00115     ULONG Protocol;
00116 
00117     TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
00118 
00119     EaInfo = Irp->AssociatedIrp.SystemBuffer;
00120 
00121     /* Parameter check */
00122     /* No EA information means that we're opening for SET/QUERY_INFORMATION
00123     * style calls. */
00124 
00125     /* Allocate resources here. We release them again if something failed */
00126     Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSPORT_CONTEXT),
00127                                     TRANS_CONTEXT_TAG);
00128     if (!Context)
00129     {
00130         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
00131         return STATUS_INSUFFICIENT_RESOURCES;
00132     }
00133 
00134     Context->CancelIrps = FALSE;
00135 
00136     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00137     IrpSp->FileObject->FsContext = Context;
00138     Request.RequestContext       = Irp;
00139 
00140     /* Branch to the right handler */
00141     if (EaInfo &&
00142         (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
00143         (RtlCompareMemory(&EaInfo->EaName, TdiTransportAddress,
00144         TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH))
00145     {
00146         /* This is a request to open an address */
00147 
00148 
00149         /* XXX This should probably be done in IoCreateFile() */
00150         /* Parameter checks */
00151 
00152         Address = (PTA_IP_ADDRESS)(EaInfo->EaName + EaInfo->EaNameLength + 1); //0-term
00153 
00154         if ((EaInfo->EaValueLength < sizeof(TA_IP_ADDRESS)) ||
00155             (Address->TAAddressCount != 1) ||
00156             (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
00157             (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP))
00158         {
00159             TI_DbgPrint(MIN_TRACE, ("Parameters are invalid:\n"));
00160             TI_DbgPrint(MIN_TRACE, ("AddressCount: %d\n", Address->TAAddressCount));
00161             if( Address->TAAddressCount == 1 )
00162             {
00163                 TI_DbgPrint(MIN_TRACE, ("AddressLength: %\n",
00164                             Address->Address[0].AddressLength));
00165                 TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
00166                             Address->Address[0].AddressType));
00167             }
00168 
00169             ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
00170             return STATUS_INVALID_PARAMETER;
00171         }
00172 
00173         /* Open address file object */
00174 
00175         /* Protocol depends on device object so find the protocol */
00176         if (DeviceObject == TCPDeviceObject)
00177             Protocol = IPPROTO_TCP;
00178         else if (DeviceObject == UDPDeviceObject)
00179             Protocol = IPPROTO_UDP;
00180         else if (DeviceObject == IPDeviceObject)
00181             Protocol = IPPROTO_RAW;
00182         else if (DeviceObject == RawIPDeviceObject)
00183         {
00184             Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
00185             if (!NT_SUCCESS(Status))
00186             {
00187                 TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
00188                 ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
00189                 return STATUS_INVALID_PARAMETER;
00190             }
00191         }
00192         else
00193         {
00194             TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
00195             ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
00196             return STATUS_INVALID_PARAMETER;
00197         }
00198 
00199         Status = FileOpenAddress(&Request, Address, Protocol, NULL);
00200         if (NT_SUCCESS(Status))
00201         {
00202             IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
00203             Context->Handle.AddressHandle = Request.Handle.AddressHandle;
00204         }
00205 
00206     }
00207     else if (EaInfo &&
00208             (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
00209             (RtlCompareMemory
00210             (&EaInfo->EaName, TdiConnectionContext,
00211             TDI_CONNECTION_CONTEXT_LENGTH) ==
00212             TDI_CONNECTION_CONTEXT_LENGTH))
00213     {
00214         /* This is a request to open a connection endpoint */
00215 
00216         /* Parameter checks */
00217 
00218         if (EaInfo->EaValueLength < sizeof(PVOID))
00219         {
00220             TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
00221             ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
00222             return STATUS_INVALID_PARAMETER;
00223         }
00224 
00225         /* Can only do connection oriented communication using TCP */
00226 
00227         if (DeviceObject != TCPDeviceObject)
00228         {
00229             TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
00230             ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
00231             return STATUS_INVALID_PARAMETER;
00232         }
00233 
00234         ClientContext = *((PVOID*)(EaInfo->EaName + EaInfo->EaNameLength));
00235 
00236         /* Open connection endpoint file object */
00237 
00238         Status = FileOpenConnection(&Request, ClientContext);
00239         if (NT_SUCCESS(Status))
00240         {
00241             IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE;
00242             Context->Handle.ConnectionContext = Request.Handle.ConnectionContext;
00243         }
00244     }
00245     else
00246     {
00247         /* This is a request to open a control connection */
00248         Status = FileOpenControlChannel(&Request);
00249         if (NT_SUCCESS(Status))
00250         {
00251             IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONTROL_CHANNEL_FILE;
00252             Context->Handle.ControlChannel = Request.Handle.ControlChannel;
00253         }
00254     }
00255 
00256     if (!NT_SUCCESS(Status))
00257         ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
00258 
00259     TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
00260 
00261     Irp->IoStatus.Status = Status;
00262     return Status;
00263 }
00264 
00265 
00266 /*
00267  * FUNCTION: Releases resources used by a file object
00268  * ARGUMENTS:
00269  *     DeviceObject = Pointer to a device object for this driver
00270  *     Irp          = Pointer to a I/O request packet
00271  * RETURNS:
00272  *     Status of the operation
00273  * NOTES:
00274  *     This function does not pend
00275  */
00276 NTSTATUS TiCloseFileObject(
00277   PDEVICE_OBJECT DeviceObject,
00278   PIRP Irp)
00279 {
00280     PIO_STACK_LOCATION IrpSp;
00281     PTRANSPORT_CONTEXT Context;
00282     TDI_REQUEST Request;
00283     NTSTATUS Status;
00284 
00285     IrpSp   = IoGetCurrentIrpStackLocation(Irp);
00286     Context = IrpSp->FileObject->FsContext;
00287     if (!Context)
00288     {
00289         TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
00290         return STATUS_INVALID_PARAMETER;
00291     }
00292 
00293     switch ((ULONG_PTR)IrpSp->FileObject->FsContext2)
00294     {
00295         case TDI_TRANSPORT_ADDRESS_FILE:
00296             Request.Handle.AddressHandle = Context->Handle.AddressHandle;
00297             Status = FileCloseAddress(&Request);
00298             break;
00299 
00300         case TDI_CONNECTION_FILE:
00301             Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
00302             Status = FileCloseConnection(&Request);
00303             break;
00304 
00305         case TDI_CONTROL_CHANNEL_FILE:
00306             Request.Handle.ControlChannel = Context->Handle.ControlChannel;
00307             Status = FileCloseControlChannel(&Request);
00308             break;
00309 
00310         default:
00311             Status = STATUS_INVALID_PARAMETER;
00312             break;
00313     }
00314 
00315     Irp->IoStatus.Status = Status;
00316 
00317     return Irp->IoStatus.Status;
00318 }
00319 
00320 
00321 NTSTATUS NTAPI
00322 TiDispatchOpenClose(
00323   IN PDEVICE_OBJECT DeviceObject,
00324   IN PIRP Irp)
00325 /*
00326  * FUNCTION: Main dispath routine
00327  * ARGUMENTS:
00328  *     DeviceObject = Pointer to a device object for this driver
00329  *     Irp          = Pointer to a I/O request packet
00330  * RETURNS:
00331  *     Status of the operation
00332  */
00333 {
00334   PIO_STACK_LOCATION IrpSp;
00335   NTSTATUS Status;
00336 
00337 //  DbgPrint("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp);
00338 
00339   IrpSp = IoGetCurrentIrpStackLocation(Irp);
00340 
00341   switch (IrpSp->MajorFunction) {
00342   /* Open an address file, connection endpoint, or control connection */
00343   case IRP_MJ_CREATE:
00344     Status = TiCreateFileObject(DeviceObject, Irp);
00345     break;
00346 
00347   /* Close an address file, connection endpoint, or control connection */
00348   case IRP_MJ_CLOSE:
00349     Status = TiCloseFileObject(DeviceObject, Irp);
00350     break;
00351 
00352   default:
00353     Status = STATUS_INVALID_DEVICE_REQUEST;
00354   }
00355 
00356   //DbgPrint("Leaving. Status is (0x%X)\n", Status);
00357 
00358   return IRPFinish( Irp, Status );
00359 }
00360 
00361 
00362 NTSTATUS NTAPI
00363 TiDispatchInternal(
00364   PDEVICE_OBJECT DeviceObject,
00365   PIRP Irp)
00366 /*
00367  * FUNCTION: Internal IOCTL dispatch routine
00368  * ARGUMENTS:
00369  *     DeviceObject = Pointer to a device object for this driver
00370  *     Irp          = Pointer to a I/O request packet
00371  * RETURNS:
00372  *     Status of the operation
00373  */
00374 {
00375   NTSTATUS Status;
00376   BOOLEAN Complete = TRUE;
00377   PIO_STACK_LOCATION IrpSp;
00378 
00379   IrpSp = IoGetCurrentIrpStackLocation(Irp);
00380 
00381   TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
00382     DeviceObject, Irp, IrpSp->MinorFunction));
00383 
00384   Irp->IoStatus.Status      = STATUS_SUCCESS;
00385   Irp->IoStatus.Information = 0;
00386 
00387   switch (IrpSp->MinorFunction) {
00388   case TDI_RECEIVE:
00389     Status = DispTdiReceive(Irp);
00390     Complete = FALSE;
00391     break;
00392 
00393   case TDI_RECEIVE_DATAGRAM:
00394     Status = DispTdiReceiveDatagram(Irp);
00395     Complete = FALSE;
00396     break;
00397 
00398   case TDI_SEND:
00399     Status = DispTdiSend(Irp);
00400     Complete = FALSE; /* Completed in DispTdiSend */
00401     break;
00402 
00403   case TDI_SEND_DATAGRAM:
00404     Status = DispTdiSendDatagram(Irp);
00405     Complete = FALSE;
00406     break;
00407 
00408   case TDI_ACCEPT:
00409     Status = DispTdiAccept(Irp);
00410     break;
00411 
00412   case TDI_LISTEN:
00413     Status = DispTdiListen(Irp);
00414     Complete = FALSE;
00415     break;
00416 
00417   case TDI_CONNECT:
00418     Status = DispTdiConnect(Irp);
00419     Complete = FALSE; /* Completed by the TCP event handler */
00420     break;
00421 
00422   case TDI_DISCONNECT:
00423     Status = DispTdiDisconnect(Irp);
00424     Complete = FALSE;
00425     break;
00426 
00427   case TDI_ASSOCIATE_ADDRESS:
00428     Status = DispTdiAssociateAddress(Irp);
00429     break;
00430 
00431   case TDI_DISASSOCIATE_ADDRESS:
00432     Status = DispTdiDisassociateAddress(Irp);
00433     break;
00434 
00435   case TDI_QUERY_INFORMATION:
00436     Status = DispTdiQueryInformation(DeviceObject, Irp);
00437     break;
00438 
00439   case TDI_SET_INFORMATION:
00440     Status = DispTdiSetInformation(Irp);
00441     break;
00442 
00443   case TDI_SET_EVENT_HANDLER:
00444     Status = DispTdiSetEventHandler(Irp);
00445     break;
00446 
00447   case TDI_ACTION:
00448     Status = STATUS_SUCCESS;
00449     break;
00450 
00451   /* An unsupported IOCTL code was submitted */
00452   default:
00453     Status = STATUS_INVALID_DEVICE_REQUEST;
00454   }
00455 
00456   TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Leaving. Status = (0x%X).\n", Status));
00457 
00458   if( Complete )
00459       IRPFinish( Irp, Status );
00460 
00461   return Status;
00462 }
00463 
00464 
00465 NTSTATUS NTAPI
00466 TiDispatch(
00467   PDEVICE_OBJECT DeviceObject,
00468   PIRP Irp)
00469 /*
00470  * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
00471  * ARGUMENTS:
00472  *     DeviceObject = Pointer to a device object for this driver
00473  *     Irp          = Pointer to a I/O request packet
00474  * RETURNS:
00475  *     Status of the operation
00476  */
00477 {
00478   NTSTATUS Status;
00479   PIO_STACK_LOCATION IrpSp;
00480 
00481   IrpSp  = IoGetCurrentIrpStackLocation(Irp);
00482 
00483   TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
00484 
00485   Irp->IoStatus.Information = 0;
00486 
00487 #if 0
00488   Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
00489   if (NT_SUCCESS(Status)) {
00490     TiDispatchInternal(DeviceObject, Irp);
00491     Status = STATUS_PENDING;
00492   } else {
00493 #else
00494   if (TRUE) {
00495 #endif
00496     /* See if this request is TCP/IP specific */
00497     switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
00498     case IOCTL_TCP_QUERY_INFORMATION_EX:
00499       TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
00500       Status = DispTdiQueryInformationEx(Irp, IrpSp);
00501       break;
00502 
00503     case IOCTL_TCP_SET_INFORMATION_EX:
00504       TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
00505       Status = DispTdiSetInformationEx(Irp, IrpSp);
00506       break;
00507 
00508     case IOCTL_SET_IP_ADDRESS:
00509       TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
00510       Status = DispTdiSetIPAddress(Irp, IrpSp);
00511       break;
00512 
00513     case IOCTL_DELETE_IP_ADDRESS:
00514       TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
00515       Status = DispTdiDeleteIPAddress(Irp, IrpSp);
00516       break;
00517 
00518     default:
00519       TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
00520           IrpSp->Parameters.DeviceIoControl.IoControlCode));
00521       Status = STATUS_NOT_IMPLEMENTED;
00522       break;
00523     }
00524   }
00525 
00526   TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));
00527 
00528   return IRPFinish( Irp, Status );
00529 }
00530 
00531 
00532 VOID NTAPI TiUnload(
00533   PDRIVER_OBJECT DriverObject)
00534 /*
00535  * FUNCTION: Unloads the driver
00536  * ARGUMENTS:
00537  *     DriverObject = Pointer to driver object created by the system
00538  */
00539 {
00540 #if DBG
00541   KIRQL OldIrql;
00542 
00543   TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
00544   if (!IsListEmpty(&AddressFileListHead)) {
00545     TI_DbgPrint(MIN_TRACE, ("[TCPIP, TiUnload] Called. Open address file objects exists.\n"));
00546   }
00547   TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
00548 #endif
00549   /* Cancel timer */
00550   KeCancelTimer(&IPTimer);
00551 
00552   /* Unregister loopback adapter */
00553   LoopUnregisterAdapter(NULL);
00554 
00555   /* Unregister protocol with NDIS */
00556   LANUnregisterProtocol();
00557 
00558   /* Shutdown transport level protocol subsystems */
00559   TCPShutdown();
00560   UDPShutdown();
00561   RawIPShutdown();
00562   ICMPShutdown();
00563 
00564   /* Shutdown network level protocol subsystem */
00565   IPShutdown();
00566 
00567   /* Free NDIS buffer descriptors */
00568   if (GlobalBufferPool)
00569     NdisFreeBufferPool(GlobalBufferPool);
00570 
00571   /* Free NDIS packet descriptors */
00572   if (GlobalPacketPool)
00573     NdisFreePacketPool(GlobalPacketPool);
00574 
00575   /* Release all device objects */
00576 
00577   if (TCPDeviceObject)
00578     IoDeleteDevice(TCPDeviceObject);
00579 
00580   if (UDPDeviceObject)
00581     IoDeleteDevice(UDPDeviceObject);
00582 
00583   if (RawIPDeviceObject)
00584     IoDeleteDevice(RawIPDeviceObject);
00585 
00586   if (IPDeviceObject) {
00587      ChewShutdown();
00588      IoDeleteDevice(IPDeviceObject);
00589   }
00590 
00591   if (EntityList)
00592     ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG);
00593 
00594   TI_DbgPrint(MAX_TRACE, ("[TCPIP, TiUnload] Leaving.\n"));
00595 }
00596 
00597 NTSTATUS NTAPI
00598 DriverEntry(
00599   PDRIVER_OBJECT DriverObject,
00600   PUNICODE_STRING RegistryPath)
00601 /*
00602  * FUNCTION: Main driver entry point
00603  * ARGUMENTS:
00604  *     DriverObject = Pointer to a driver object for this driver
00605  *     RegistryPath = Registry node for configuration parameters
00606  * RETURNS:
00607  *     Status of driver initialization
00608  */
00609 {
00610   NTSTATUS Status;
00611   UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
00612   UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
00613   UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
00614   UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
00615   UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
00616   NDIS_STATUS NdisStatus;
00617   LARGE_INTEGER DueTime;
00618 
00619   TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));
00620 
00621   /* TdiInitialize() ? */
00622 
00623   /* FIXME: Create symbolic links in Win32 namespace */
00624 
00625   /* Initialize our periodic timer and its associated DPC object. When the
00626      timer expires, the IPTimeout deferred procedure call (DPC) is queued */
00627   KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
00628   KeInitializeTimer(&IPTimer);
00629 
00630   /* Create IP device object */
00631   Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
00632     FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
00633   if (!NT_SUCCESS(Status)) {
00634     TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
00635     TiUnload(DriverObject);
00636     return Status;
00637   }
00638 
00639   ChewInit( IPDeviceObject );
00640 
00641   /* Create RawIP device object */
00642   Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
00643     FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
00644   if (!NT_SUCCESS(Status)) {
00645     TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
00646     TiUnload(DriverObject);
00647     return Status;
00648   }
00649 
00650   /* Create UDP device object */
00651   Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
00652     FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
00653   if (!NT_SUCCESS(Status)) {
00654     TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
00655     TiUnload(DriverObject);
00656     return Status;
00657   }
00658 
00659   /* Create TCP device object */
00660   Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
00661     FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
00662   if (!NT_SUCCESS(Status)) {
00663     TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
00664     TiUnload(DriverObject);
00665     return Status;
00666   }
00667 
00668   /* Setup network layer and transport layer entities */
00669   KeInitializeSpinLock(&EntityListLock);
00670   EntityList = ExAllocatePoolWithTag(NonPagedPool,
00671                                      sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
00672                                      TDI_ENTITY_TAG );
00673   if (!EntityList) {
00674     TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
00675     TiUnload(DriverObject);
00676     return STATUS_INSUFFICIENT_RESOURCES;
00677   }
00678 
00679   EntityCount = 0;
00680   EntityMax   = MAX_TDI_ENTITIES;
00681 
00682   /* Allocate NDIS packet descriptors */
00683   NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
00684   if (NdisStatus != NDIS_STATUS_SUCCESS) {
00685     TiUnload(DriverObject);
00686     return STATUS_INSUFFICIENT_RESOURCES;
00687   }
00688 
00689   /* Allocate NDIS buffer descriptors */
00690   NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
00691   if (NdisStatus != NDIS_STATUS_SUCCESS) {
00692     TiUnload(DriverObject);
00693     return STATUS_INSUFFICIENT_RESOURCES;
00694   }
00695 
00696   /* Initialize address file list and protecting spin lock */
00697   InitializeListHead(&AddressFileListHead);
00698   KeInitializeSpinLock(&AddressFileListLock);
00699 
00700   /* Initialize connection endpoint list and protecting spin lock */
00701   InitializeListHead(&ConnectionEndpointListHead);
00702   KeInitializeSpinLock(&ConnectionEndpointListLock);
00703 
00704   /* Initialize interface list and protecting spin lock */
00705   InitializeListHead(&InterfaceListHead);
00706   KeInitializeSpinLock(&InterfaceListLock);
00707 
00708   /* Initialize network level protocol subsystem */
00709   IPStartup(RegistryPath);
00710 
00711   /* Initialize transport level protocol subsystems */
00712   Status = RawIPStartup();
00713   if( !NT_SUCCESS(Status) ) {
00714       TiUnload(DriverObject);
00715       return Status;
00716   }
00717 
00718   Status = UDPStartup();
00719   if( !NT_SUCCESS(Status) ) {
00720       TiUnload(DriverObject);
00721       return Status;
00722   }
00723 
00724   Status = TCPStartup();
00725   if( !NT_SUCCESS(Status) ) {
00726       TiUnload(DriverObject);
00727       return Status;
00728   }
00729 
00730   Status = ICMPStartup();
00731   if( !NT_SUCCESS(Status) ) {
00732       TiUnload(DriverObject);
00733       return Status;
00734   }
00735 
00736   /* Use direct I/O */
00737   IPDeviceObject->Flags    |= DO_DIRECT_IO;
00738   RawIPDeviceObject->Flags |= DO_DIRECT_IO;
00739   UDPDeviceObject->Flags   |= DO_DIRECT_IO;
00740   TCPDeviceObject->Flags   |= DO_DIRECT_IO;
00741 
00742   /* Initialize the driver object with this driver's entry points */
00743   DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
00744   DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
00745   DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
00746   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;
00747 
00748   DriverObject->DriverUnload = TiUnload;
00749 
00750   /* Open loopback adapter */
00751   Status = LoopRegisterAdapter(NULL, NULL);
00752   if (!NT_SUCCESS(Status)) {
00753     TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
00754     TiUnload(DriverObject);
00755     return Status;
00756   }
00757 
00758   /* Register protocol with NDIS */
00759   /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
00760   Status = LANRegisterProtocol(&strNdisDeviceName);
00761   if (!NT_SUCCESS(Status)) {
00762       TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
00763       TiWriteErrorLog(
00764       DriverObject,
00765       EVENT_TRANSPORT_REGISTER_FAILED,
00766       TI_ERROR_DRIVERENTRY,
00767       Status,
00768       NULL,
00769       0,
00770       NULL);
00771       TiUnload(DriverObject);
00772       return Status;
00773   }
00774 
00775   /* Start the periodic timer with an initial and periodic
00776      relative expiration time of IP_TIMEOUT milliseconds */
00777   DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
00778   KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);
00779 
00780   TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));
00781 
00782 
00783   return STATUS_SUCCESS;
00784 }
00785 
00786 VOID NTAPI
00787 IPAddInterface(
00788     ULONG   Unknown0,
00789     ULONG   Unknown1,
00790     ULONG   Unknown2,
00791     ULONG   Unknown3,
00792     ULONG   Unknown4)
00793 {
00794     UNIMPLEMENTED
00795 }
00796 
00797 
00798 VOID NTAPI
00799 IPDelInterface(
00800     ULONG   Unknown0)
00801 {
00802     UNIMPLEMENTED
00803 }
00804 
00805 
00806 VOID NTAPI
00807 LookupRoute(
00808     ULONG   Unknown0,
00809     ULONG   Unknown1)
00810 {
00811     UNIMPLEMENTED
00812 }
00813 
00814 /* EOF */

Generated on Sat May 26 2012 04:15:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.