Implemented sequenced lists and lookaside lists.
Started on TCP/IP connection endpoints.
Save process window station in EPROCESS instead of PEB.
NOTICE: please do a make win32k_clean or you might experience a crash
svn path=/trunk/; revision=2036
pteb consume dump_shared_data vmtest regtest alive mstest nptest \
objdir atomtest
-#NET_APPS = ping roshttpd
+#NET_APPS = ping roshttpd telnet
NET_APPS = ping
.PHONY: all
-clean: buildno_clean $(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
- $(KERNEL_SERVICES:%=%_clean) $(SUBSYS:%=%_clean) $(SYS_APPS:%=%_clean) $(APPS:%=%_clean)
+clean: buildno_clean $(COMPONENTS:%=%_clean) $(BUS:%=%_clean) $(DLLS:%=%_clean) \
+ $(LOADERS:%=%_clean) $(KERNEL_SERVICES:%=%_clean) $(SUBSYS:%=%_clean) \
+ $(SYS_APPS:%=%_clean) $(APPS:%=%_clean) $(NET_APPS:%=%_clean)
.PHONY: clean
dist: rcopy$(EXE_POSTFIX) clean_dist_dir make_dist_dirs $(COMPONENTS:%=%_dist) \
$(BUS:%=%_dist) $(DLLS:%=%_dist) \
$(LOADERS:%=%_dist) $(KERNEL_SERVICES:%=%_dist) $(SUBSYS:%=%_dist) \
- $(SYS_APPS:%=%_dist) $(APPS:%=%_dist)
+ $(SYS_APPS:%=%_dist) $(APPS:%=%_dist) $(NET_APPS:%=%_dist)
#
# Build number generator
-# $Id: makefile,v 1.3 2001/06/22 12:28:16 ekohl Exp $
+# $Id: makefile,v 1.4 2001/07/04 20:40:21 chorns Exp $
#
#
TARGET = psaux
.phony: all
clean:
- - $(RM) $(TARGET).o
+ - $(RM) *.o
- $(RM) $(TARGET).coff
- $(RM) junk.tmp
- $(RM) base.tmp
Status = AfdDispSelect(Irp, IrpSp);
break;
+ case IOCTL_AFD_EVENTSELECT:
+ Status = AfdDispEventSelect(Irp, IrpSp);
+ break;
+
+ case IOCTL_AFD_ENUMNETWORKEVENTS:
+ Status = AfdDispEnumNetworkEvents(Irp, IrpSp);
+ break;
+
+ case IOCTL_AFD_RECV:
+ Status = AfdDispRecv(Irp, IrpSp);
+ break;
+
+ case IOCTL_AFD_SEND:
+ Status = AfdDispSend(Irp, IrpSp);
+ break;
+
+ case IOCTL_AFD_CONNECT:
+ Status = AfdDispConnect(Irp, IrpSp);
+ break;
+
default:
AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%X).\n",
IrpSp->Parameters.DeviceIoControl.IoControlCode));
*/
#include <afd.h>
+NTSTATUS AfdpDispRecv(
+ PIRP Irp,
+ PAFDFCB FCB,
+ PFILE_REQUEST_RECVFROM Request,
+ PFILE_REPLY_RECVFROM Reply)
+/*
+ * FUNCTION: Receives data
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * FCB = Pointer to file control block
+ * Request = Address of request buffer
+ * Reply = Address of reply buffer (same as request buffer)
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PAFD_READ_REQUEST ReadRequest;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+ ULONG Count;
+
+ KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
+ if (IsListEmpty(&FCB->ReceiveQueue)) {
+ KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
+
+ /* Queue a read request and return STATUS_PENDING */
+
+ AFD_DbgPrint(MAX_TRACE, ("Queueing read request.\n"));
+
+ /*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
+ &ReadRequestLookasideList);*/
+ ReadRequest = (PAFD_READ_REQUEST)ExAllocatePool(
+ NonPagedPool,
+ sizeof(AFD_READ_REQUEST));
+ if (ReadRequest) {
+ ReadRequest->Irp = Irp;
+ ReadRequest->RecvFromRequest = Request;
+ ReadRequest->RecvFromReply = Reply;
+
+ ExInterlockedInsertTailList(
+ &FCB->ReadRequestQueue,
+ &ReadRequest->ListEntry,
+ &FCB->ReadRequestQueueLock);
+ Status = STATUS_PENDING;
+ } else {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ } else {
+ AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
+
+ /* Satisfy the request at once */
+ Status = FillWSABuffers(
+ FCB,
+ Request->Buffers,
+ Request->BufferCount,
+ &Count);
+ KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
+
+ Reply->NumberOfBytesRecvd = Count;
+ Reply->Status = NO_ERROR;
+
+ AFD_DbgPrint(MAX_TRACE, ("Bytes received (0x%X).\n", Count));
+ }
+
+ return Status;
+}
+
+
NTSTATUS AfdDispBind(
PIRP Irp,
PIO_STACK_LOCATION IrpSp)
PFILE_REQUEST_BIND Request;
PFILE_REPLY_BIND Reply;
PAFDFCB FCB;
+ INT Errno;
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
- switch (Request->Name.sa_family) {
- case AF_INET:
- Status = TdiOpenAddressFileIPv4(&FCB->TdiDeviceName,
- &Request->Name,
- &FCB->TdiAddressObjectHandle,
- &FCB->TdiAddressObject);
- break;
- default:
- AFD_DbgPrint(MIN_TRACE, ("Bad address family (%d).\n", Request->Name.sa_family));
- Status = STATUS_INVALID_PARAMETER;
- }
+ Status = TdiOpenAddressFile(
+ &FCB->TdiDeviceName,
+ &Request->Name,
+ &FCB->TdiAddressObjectHandle,
+ &FCB->TdiAddressObject);
if (NT_SUCCESS(Status)) {
AfdRegisterEventHandlers(FCB);
FCB->State = SOCKET_STATE_BOUND;
+ Reply->Status = NO_ERROR;
+ } else {
+ //FIXME: WSAEADDRNOTAVAIL
+ Reply->Status = WSAEINVAL;
}
} else
Status = STATUS_INVALID_PARAMETER;
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
/* Validate parameters */
+ Status = STATUS_INVALID_PARAMETER;
if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
(OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
FCB = IrpSp->FileObject->FsContext;
Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
- } else
- Status = STATUS_INVALID_PARAMETER;
+
+ if (FCB->State == SOCKET_STATE_BOUND) {
+
+ /* We have a bound socket so go ahead and create a connection endpoint
+ and associate it with the address file object */
+
+ Status = TdiOpenConnectionEndpointFile(
+ &FCB->TdiDeviceName,
+ &FCB->TdiConnectionObjectHandle,
+ &FCB->TdiConnectionObject);
+
+ if (NT_SUCCESS(Status)) {
+ Status = TdiAssociateAddressFile(
+ FCB->TdiAddressObjectHandle,
+ FCB->TdiConnectionObject);
+ }
+
+ if (NT_SUCCESS(Status)) {
+ Reply->Status = NO_ERROR;
+ } else {
+ Reply->Status = WSAEINVAL;
+ }
+ } else if (FCB->State == SOCKET_STATE_CONNECTED) {
+ Reply->Status = WSAEISCONN;
+ } else {
+ Reply->Status = WSAEINVAL;
+ }
+ }
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
FCB = IrpSp->FileObject->FsContext;
Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
+
+ /* Since we're using bufferred I/O */
+ Request->Buffers = (LPWSABUF)(Request + 1);
BufferSize = WSABufferSize(Request->Buffers, Request->BufferCount);
UINT OutputBufferLength;
PFILE_REQUEST_RECVFROM Request;
PFILE_REPLY_RECVFROM Reply;
- PAFD_READ_REQUEST ReadRequest;
DWORD NumberOfBytesRecvd;
- KIRQL OldIrql;
PAFDFCB FCB;
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
-
- KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
- if (IsListEmpty(&FCB->ReceiveQueue)) {
- KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
-
- /* Queue a read request and return STATUS_PENDING */
-
- AFD_DbgPrint(MAX_TRACE, ("Queueing read request.\n"));
-
- /*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
- &ReadRequestLookasideList);*/
- ReadRequest = (PAFD_READ_REQUEST)ExAllocatePool(
- NonPagedPool,
- sizeof(AFD_READ_REQUEST));
- if (ReadRequest) {
- ReadRequest->Irp = Irp;
- ReadRequest->RecvFromRequest = Request;
- ReadRequest->RecvFromReply = Reply;
-
- ExInterlockedInsertTailList(
- &FCB->ReadRequestQueue,
- &ReadRequest->ListEntry,
- &FCB->ReadRequestQueueLock);
- Status = STATUS_PENDING;
- } else {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
- } else {
- AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
-
- /* Satisfy the request at once */
- Status = FillWSABuffers(
- FCB,
- Request->Buffers,
- Request->BufferCount,
- &NumberOfBytesRecvd);
- KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
- Reply->Status = NO_ERROR;
- Reply->NumberOfBytesRecvd = NumberOfBytesRecvd;
- AFD_DbgPrint(MAX_TRACE, ("NumberOfBytesRecvd (0x%X).\n",
- NumberOfBytesRecvd));
- }
+ /* Since we're using bufferred I/O */
+ Request->Buffers = (LPWSABUF)(Request + 1);
+
+ Status = AfdpDispRecv(
+ Irp,
+ FCB,
+ Request,
+ Reply);
} else {
Status = STATUS_INVALID_PARAMETER;
}
} SelectOperation;
-DWORD AfdDispSelectEx(
+DWORD AfdpDispSelectEx(
LPFD_SET FDSet,
SelectOperation Operation)
{
+ PFILE_OBJECT FileObject;
NTSTATUS Status;
PAFDFCB Current;
KIRQL OldIrql;
Count = 0;
for (i = 0; i < FDSet->fd_count; i++) {
+
+ AFD_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", FDSet->fd_array[i]));
+
Status = ObReferenceObjectByHandle(
(HANDLE)FDSet->fd_array[i],
0,
IoFileObjectType,
KernelMode,
- (PVOID*)&Current,
+ (PVOID*)&FileObject,
NULL);
if (NT_SUCCESS(Status)) {
+ AFD_DbgPrint(MAX_TRACE, ("File object is at (0x%X).\n", FileObject));
+
+ Current = FileObject->FsContext;
switch (Operation) {
case soRead:
break;
}
- ObDereferenceObject(Current);
+ ObDereferenceObject(FileObject);
}
}
PIO_STACK_LOCATION IrpSp)
/*
* FUNCTION: Checks if sockets have data in the receive buffers
+ * and/or if client can send data
* ARGUMENTS:
* Irp = Pointer to I/O request packet
* IrpSp = Pointer to current stack location of Irp
SocketCount = 0;
- if (Request->ReadFDSet) {
- AFD_DbgPrint(MAX_TRACE, ("Read.\n"));
- SocketCount += AfdDispSelectEx(Request->ReadFDSet, soRead);
- }
if (Request->WriteFDSet) {
AFD_DbgPrint(MAX_TRACE, ("Write.\n"));
- SocketCount += AfdDispSelectEx(Request->WriteFDSet, soWrite);
+ SocketCount += AfdpDispSelectEx(Request->WriteFDSet, soWrite);
+ }
+ if (Request->ReadFDSet) {
+ AFD_DbgPrint(MAX_TRACE, ("Read.\n"));
+ SocketCount += AfdpDispSelectEx(Request->ReadFDSet, soRead);
}
if (Request->ExceptFDSet) {
- SocketCount += AfdDispSelectEx(Request->ExceptFDSet, soExcept);
+ SocketCount += AfdpDispSelectEx(Request->ExceptFDSet, soExcept);
}
AFD_DbgPrint(MAX_TRACE, ("Sockets selected (0x%X).\n", SocketCount));
return Status;
}
+NTSTATUS AfdDispEventSelect(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+/*
+ * FUNCTION: Associate an event object with one or more network events
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+{
+ NTSTATUS Status;
+ UINT InputBufferLength;
+ UINT OutputBufferLength;
+ PFILE_REQUEST_EVENTSELECT Request;
+ PFILE_REPLY_EVENTSELECT Reply;
+ PAFDFCB FCB;
+ ULONG i;
+
+ InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ /* Validate parameters */
+ if ((InputBufferLength >= sizeof(FILE_REQUEST_EVENTSELECT)) &&
+ (OutputBufferLength >= sizeof(FILE_REPLY_EVENTSELECT))) {
+ FCB = IrpSp->FileObject->FsContext;
+
+ Request = (PFILE_REQUEST_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
+ Reply = (PFILE_REPLY_EVENTSELECT)Irp->AssociatedIrp.SystemBuffer;
+
+ FCB->NetworkEvents.lNetworkEvents = Request->lNetworkEvents;
+ for (i = 0; i < FD_MAX_EVENTS; i++) {
+ if ((Request->lNetworkEvents & (1 << i)) > 0) {
+ FCB->EventObjects[i] = Request->hEventObject;
+ } else {
+ /* The effect of any previous call to this function is cancelled */
+ FCB->EventObjects[i] = (WSAEVENT)0;
+ }
+ }
+
+ Reply->Status = NO_ERROR;
+ Status = STATUS_SUCCESS;
+ } else
+ Status = STATUS_INVALID_PARAMETER;
+
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+
+ return Status;
+}
+
+NTSTATUS AfdDispEnumNetworkEvents(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+/*
+ * FUNCTION: Reports network events
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+{
+ NTSTATUS Status;
+ UINT InputBufferLength;
+ UINT OutputBufferLength;
+ PFILE_REQUEST_ENUMNETWORKEVENTS Request;
+ PFILE_REPLY_ENUMNETWORKEVENTS Reply;
+ HANDLE EventObject;
+ PAFDFCB FCB;
+
+ InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ /* Validate parameters */
+ if ((InputBufferLength >= sizeof(FILE_REQUEST_ENUMNETWORKEVENTS)) &&
+ (OutputBufferLength >= sizeof(FILE_REPLY_ENUMNETWORKEVENTS))) {
+ FCB = IrpSp->FileObject->FsContext;
+
+ Request = (PFILE_REQUEST_ENUMNETWORKEVENTS)Irp->AssociatedIrp.SystemBuffer;
+ Reply = (PFILE_REPLY_ENUMNETWORKEVENTS)Irp->AssociatedIrp.SystemBuffer;
+
+ EventObject = (HANDLE)Request->hEventObject;
+
+ RtlCopyMemory(
+ &Reply->NetworkEvents,
+ &FCB->NetworkEvents,
+ sizeof(WSANETWORKEVENTS));
+
+ RtlZeroMemory(
+ &FCB->NetworkEvents,
+ sizeof(WSANETWORKEVENTS));
+
+ if (EventObject != NULL) {
+ ZwClearEvent(EventObject);
+ }
+
+ Reply->Status = NO_ERROR;
+ Status = STATUS_SUCCESS;
+ } else
+ Status = STATUS_INVALID_PARAMETER;
+
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+
+ return Status;
+}
+
+
+NTSTATUS AfdDispRecv(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+/*
+ * FUNCTION: Receives data from an address
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+{
+#if 0
+ NTSTATUS Status;
+ UINT InputBufferLength;
+ UINT OutputBufferLength;
+ PFILE_REQUEST_RECV Request;
+ PFILE_REPLY_RECV Reply;
+ DWORD NumberOfBytesRecvd;
+ PAFDFCB FCB;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ /* Validate parameters */
+ if ((InputBufferLength >= sizeof(FILE_REQUEST_RECV)) &&
+ (OutputBufferLength >= sizeof(FILE_REPLY_RECV))) {
+ FCB = IrpSp->FileObject->FsContext;
+
+ Request = (PFILE_REQUEST_RECV)Irp->AssociatedIrp.SystemBuffer;
+ Reply = (PFILE_REPLY_RECV)Irp->AssociatedIrp.SystemBuffer;
+
+ Status = AfdpDispRecv(
+ Irp,
+ FCB,
+ Request->Buffers,
+ Request->BufferCount,
+ &NumberOfBytesRecvd);
+ Reply->NumberOfBytesRecvd = NumberOfBytesRecvd;
+ Reply->Status = NO_ERROR;
+ } else {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+
+ return Status;
+#else
+ return STATUS_SUCCESS;
+#endif
+}
+
+
+NTSTATUS AfdDispSend(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+/*
+ * FUNCTION: Sends data
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+{
+ NTSTATUS Status;
+ UINT InputBufferLength;
+ UINT OutputBufferLength;
+ PFILE_REQUEST_SEND Request;
+ PFILE_REPLY_SEND Reply;
+ PAFDFCB FCB;
+
+ InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ /* Validate parameters */
+ if ((InputBufferLength >= sizeof(FILE_REQUEST_SEND)) &&
+ (OutputBufferLength >= sizeof(FILE_REPLY_SEND))) {
+ FCB = IrpSp->FileObject->FsContext;
+
+ Request = (PFILE_REQUEST_SEND)Irp->AssociatedIrp.SystemBuffer;
+ Reply = (PFILE_REPLY_SEND)Irp->AssociatedIrp.SystemBuffer;
+
+ Reply->NumberOfBytesSent = 0;
+ Reply->Status = NO_ERROR;
+ } else
+ Status = STATUS_INVALID_PARAMETER;
+
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+
+ return Status;
+}
+
+
+NTSTATUS AfdDispConnect(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+/*
+ * FUNCTION: Connect to a remote peer
+ * ARGUMENTS:
+ * Irp = Pointer to I/O request packet
+ * IrpSp = Pointer to current stack location of Irp
+ * RETURNS:
+ * Status of operation
+ */
+{
+ NTSTATUS Status;
+ UINT InputBufferLength;
+ UINT OutputBufferLength;
+ PFILE_REQUEST_CONNECT Request;
+ PFILE_REPLY_CONNECT Reply;
+ PAFDFCB FCB;
+ SOCKADDR_IN LocalAddress;
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ /* Validate parameters */
+ Status = STATUS_INVALID_PARAMETER;
+ if ((InputBufferLength >= sizeof(FILE_REQUEST_CONNECT)) &&
+ (OutputBufferLength >= sizeof(FILE_REPLY_CONNECT))) {
+ FCB = IrpSp->FileObject->FsContext;
+
+ Request = (PFILE_REQUEST_CONNECT)Irp->AssociatedIrp.SystemBuffer;
+ Reply = (PFILE_REPLY_CONNECT)Irp->AssociatedIrp.SystemBuffer;
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ if (FCB->State == SOCKET_STATE_BOUND) {
+ Reply->Status = WSAEADDRINUSE;
+ } else if (FCB->State == SOCKET_STATE_CONNECTED) {
+ Reply->Status = WSAEISCONN;
+ } else {
+ /* We have an unbound socket so go ahead and create an address
+ file object and a connection endpoint and associate the two */
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ /* FIXME: Get from client */
+ LocalAddress.sin_family = AF_INET;
+ LocalAddress.sin_port = 1700;
+ LocalAddress.sin_addr.S_un.S_addr = 0x0; /* Dynamically allocate */
+
+ Status = TdiOpenAddressFile(
+ &FCB->TdiDeviceName,
+ (LPSOCKADDR)&LocalAddress,
+ &FCB->TdiAddressObjectHandle,
+ &FCB->TdiAddressObject);
+
+ if (NT_SUCCESS(Status)) {
+ AfdRegisterEventHandlers(FCB);
+ FCB->State = SOCKET_STATE_BOUND;
+ }
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ if (NT_SUCCESS(Status)) {
+ Status = TdiOpenConnectionEndpointFile(
+ &FCB->TdiDeviceName,
+ &FCB->TdiConnectionObjectHandle,
+ &FCB->TdiConnectionObject);
+ }
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ if (NT_SUCCESS(Status)) {
+ Status = TdiAssociateAddressFile(
+ FCB->TdiAddressObjectHandle,
+ FCB->TdiConnectionObject);
+ }
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ if (NT_SUCCESS(Status)) {
+ /* Now attempt to connect to the remote peer */
+ Status = TdiConnect(
+ FCB->TdiConnectionObject,
+ Request->name);
+ }
+
+ AFD_DbgPrint(MIN_TRACE, ("\n"));
+
+ if (NT_SUCCESS(Status)) {
+ FCB->State = SOCKET_STATE_CONNECTED;
+ Reply->Status = NO_ERROR;
+ } else {
+ Reply->Status = WSAEINVAL;
+ }
+ }
+ }
+
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+
+ return Status;
+}
+
/* EOF */
{
PAFDFCB FCB = (PAFDFCB)TdiEventContext;
PAFD_READ_REQUEST ReadRequest;
+ PIO_STACK_LOCATION IrpSp;
PVOID ReceiveBuffer;
PAFD_BUFFER Buffer;
PLIST_ENTRY Entry;
NTSTATUS Status;
KIRQL OldIrql;
+ ULONG Count;
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
BytesAvailable, *(PULONG)SourceAddress));
ReceiveBuffer = ExAllocatePool(NonPagedPool, BytesAvailable);
- if (!ReceiveBuffer) {
+ if (!ReceiveBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
- }
/*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
&BufferLookasideList);*/
KeAcquireSpinLock(&FCB->ReadRequestQueueLock, &OldIrql);
if (!IsListEmpty(&FCB->ReadRequestQueue)) {
+ AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
+
Entry = RemoveHeadList(&FCB->ReceiveQueue);
ReadRequest = CONTAINING_RECORD(Entry, AFD_READ_REQUEST, ListEntry);
FCB,
ReadRequest->RecvFromRequest->Buffers,
ReadRequest->RecvFromRequest->BufferCount,
- &ReadRequest->RecvFromReply->NumberOfBytesRecvd);
+ &Count);
+ ReadRequest->RecvFromReply->NumberOfBytesRecvd = Count;
ReadRequest->RecvFromReply->Status = NO_ERROR;
ReadRequest->Irp->IoStatus.Information = 0;
ReadRequest->Irp->IoStatus.Status = Status;
+
+ AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", ReadRequest->Irp));
+
IoCompleteRequest(ReadRequest->Irp, IO_NETWORK_INCREMENT);
}
Status = STATUS_INSUFFICIENT_RESOURCES;
if (!NT_SUCCESS(Status)) {
- /* FIXME: Cleanup */
+ /* FIXME: Cleanup */
+ AFD_DbgPrint(MAX_TRACE, ("FIXME: Cleanup.\n"));
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
+ AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", Irp));
+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
return Status;
}
inline DWORD TdiAddressSizeFromName(
- LPSOCKADDR Name)
+ LPSOCKADDR Name)
/*
* FUNCTION: Returns the size of a TDI style address equivalent to a
* WinSock style name
* Size of TDI style address, 0 if Name is not valid
*/
{
- switch (Name->sa_family) {
- case AF_INET:
- return sizeof(TA_ADDRESS_IP);
- /* FIXME: More to come */
- }
- AFD_DbgPrint(MIN_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
- return 0;
+ switch (Name->sa_family) {
+ case AF_INET:
+ return sizeof(TA_ADDRESS_IP);
+ /* FIXME: More to come */
+ }
+ AFD_DbgPrint(MIN_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
+ return 0;
}
VOID TdiBuildAddressIPv4(
- PTA_ADDRESS_IP Address,
- LPSOCKADDR Name)
+ PTA_ADDRESS_IP Address,
+ LPSOCKADDR Name)
/*
* FUNCTION: Builds an IPv4 TDI style address
* ARGUMENTS:
* Name = Pointer to WinSock style IPv4 name
*/
{
- Address->TAAddressCount = 1;
- Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
- Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
- Address->Address[0].Address[0].sin_port = ((LPSOCKADDR_IN)Name)->sin_port;
- Address->Address[0].Address[0].in_addr = ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr;
+ Address->TAAddressCount = 1;
+ Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
+ Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
+ Address->Address[0].Address[0].sin_port = ((LPSOCKADDR_IN)Name)->sin_port;
+ Address->Address[0].Address[0].in_addr = ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr;
}
-VOID TdiBuildAddress(
- PTA_ADDRESS Address,
- LPSOCKADDR Name)
+NTSTATUS TdiBuildAddress(
+ PTA_ADDRESS Address,
+ LPSOCKADDR Name)
/*
* FUNCTION: Builds a TDI style address
* ARGUMENTS:
* Address = Address of buffer to place TDI style address
* Name = Pointer to WinSock style name
+ * RETURNS:
+ * Status of operation
*/
{
- switch (Name->sa_family) {
- case AF_INET:
- TdiBuildAddressIPv4((PTA_ADDRESS_IP)Address, Name);
- break;
- /* FIXME: More to come */
- default:
- AFD_DbgPrint(MIN_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
- }
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ switch (Name->sa_family) {
+ case AF_INET:
+ TdiBuildAddressIPv4((PTA_ADDRESS_IP)Address, Name);
+ break;
+ /* FIXME: More to come */
+ default:
+ AFD_DbgPrint(MID_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ return Status;
}
-VOID TdiBuildName(
- LPSOCKADDR Name,
- PTA_ADDRESS Address)
+NTSTATUS TdiBuildName(
+ LPSOCKADDR Name,
+ PTA_ADDRESS Address)
/*
* FUNCTION: Builds a WinSock style address
* ARGUMENTS:
* Name = Address of buffer to place WinSock style name
* Address = Pointer to TDI style address
+ * RETURNS:
+ * Status of operation
*/
{
- switch (Address->AddressType) {
- case TDI_ADDRESS_TYPE_IP:
- Name->sa_family = AF_INET;
- ((LPSOCKADDR_IN)Name)->sin_port =
- ((PTDI_ADDRESS_IP)&Address->Address[0])->sin_port;
- ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr =
- ((PTDI_ADDRESS_IP)&Address->Address[0])->in_addr;
- return;
- /* FIXME: More to come */
- }
- AFD_DbgPrint(MIN_TRACE, ("Unknown TDI address type (%d).\n", Address->AddressType));
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ switch (Address->AddressType) {
+ case TDI_ADDRESS_TYPE_IP:
+ Name->sa_family = AF_INET;
+ ((LPSOCKADDR_IN)Name)->sin_port =
+ ((PTDI_ADDRESS_IP)&Address->Address[0])->sin_port;
+ ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr =
+ ((PTDI_ADDRESS_IP)&Address->Address[0])->in_addr;
+ break;
+ /* FIXME: More to come */
+ default:
+ AFD_DbgPrint(MID_TRACE, ("Unknown TDI address type (%d).\n", Address->AddressType));
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ return Status;
+
+}
+
+
+NTSTATUS TdiBuildConnectionInfo(
+ PTDI_CONNECTION_INFORMATION *ConnectionInfo,
+ LPSOCKADDR Name)
+/*
+ * FUNCTION: Builds a TDI connection information structure
+ * ARGUMENTS:
+ * ConnectionInfo = Address of buffer to place connection information
+ * Name = Pointer to WinSock style name
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PTDI_CONNECTION_INFORMATION ConnInfo;
+ ULONG TdiAddressSize;
+
+ TdiAddressSize = TdiAddressSizeFromName(Name);
+
+ ConnInfo = (PTDI_CONNECTION_INFORMATION)
+ ExAllocatePool(NonPagedPool,
+ sizeof(TDI_CONNECTION_INFORMATION) +
+ TdiAddressSize);
+ if (!ConnInfo)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlZeroMemory(ConnInfo,
+ sizeof(TDI_CONNECTION_INFORMATION) +
+ TdiAddressSize);
+
+ ConnInfo->RemoteAddressLength = TdiAddressSize;
+ ConnInfo->RemoteAddress = (PVOID)
+ (ConnInfo + sizeof(TDI_CONNECTION_INFORMATION));
+
+ TdiBuildAddress(ConnInfo->RemoteAddress, Name);
+
+ *ConnectionInfo = ConnInfo;
+
+ return STATUS_SUCCESS;
}
NTSTATUS TdiCall(
PIRP Irp,
PDEVICE_OBJECT DeviceObject,
- PIO_STATUS_BLOCK IoStatusBlock,
- BOOLEAN CanCancel,
- PKEVENT StopEvent)
+ PKEVENT Event,
+ PIO_STATUS_BLOCK Iosb)
/*
* FUNCTION: Calls a transport driver device
* ARGUMENTS:
* Irp = Pointer to I/O Request Packet
* DeviceObject = Pointer to device object to call
- * IoStatusBlock = Address of buffer with I/O status block
- * CanCancel = TRUE if the IRP can be cancelled, FALSE if not
- * StopEvent = If CanCancel is TRUE, a pointer to an event handle
- * that, when signalled will cause the request to abort
+ * Event = An optional pointer to an event handle that will be
+ * waited upon
+ * Iosb = Pointer to an IO status block
* RETURNS:
* Status of operation
- * NOTES:
- * All requests are completed synchronously. A request can be cancelled
*/
{
- KEVENT Event;
- PKEVENT Events[2];
NTSTATUS Status;
- Events[0] = StopEvent;
- Events[1] = &Event;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Irp->UserEvent = &Event;
- Irp->UserIosb = IoStatusBlock;
- Status = IoCallDriver(DeviceObject, Irp);
- if (Status == STATUS_PENDING) {
- if (CanCancel) {
- Status = KeWaitForMultipleObjects(2,
- (PVOID)&Events,
- WaitAny,
- Executive,
- KernelMode,
- FALSE,
- NULL,
- NULL);
-
- if (KeReadStateEvent(StopEvent) != 0) {
- if (IoCancelIrp(Irp)) {
- AFD_DbgPrint(MAX_TRACE, ("Cancelled IRP.\n"));
- } else {
- AFD_DbgPrint(MIN_TRACE, ("Could not cancel IRP.\n"));
- }
- return STATUS_CANCELLED;
- }
- } else
- Status = KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ Status = IoCallDriver(DeviceObject, Irp);
+ if ((Status == STATUS_PENDING) && (Event != NULL)) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ KeWaitForSingleObject(
+ Event,
+ Executive,
+ UserMode,
+ FALSE,
+ NULL);
+ Status = Iosb->Status;
}
- AFD_DbgPrint(MAX_TRACE, ("Status (0x%X) Iosb.Status (0x%X).\n", Status, IoStatusBlock->Status));
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
- return IoStatusBlock->Status;
+ return Status;
}
* Status of operation
*/
{
- PFILE_FULL_EA_INFORMATION EaInfo;
- PTA_ADDRESS_IP Address;
- NTSTATUS Status;
- ULONG EaLength;
-
- AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (0x%X)\n",
- DeviceName, Name));
-
- EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
- TDI_TRANSPORT_ADDRESS_LENGTH +
- sizeof(TA_ADDRESS_IP);
- EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
- if (!EaInfo)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- RtlZeroMemory(EaInfo, EaLength);
- EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
- RtlCopyMemory(EaInfo->EaName,
- TdiTransportAddress,
- TDI_TRANSPORT_ADDRESS_LENGTH);
- EaInfo->EaValueLength = sizeof(TA_ADDRESS_IP);
- Address = (PTA_ADDRESS_IP)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH);
- TdiBuildAddressIPv4(Address, Name);
- Status = TdiOpenDevice(DeviceName,
- EaLength,
- EaInfo,
- AddressHandle,
- AddressObject);
- ExFreePool(EaInfo);
- return Status;
+ PFILE_FULL_EA_INFORMATION EaInfo;
+ PTA_ADDRESS_IP Address;
+ NTSTATUS Status;
+ ULONG EaLength;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (0x%X)\n",
+ DeviceName, Name));
+
+ EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
+ TDI_TRANSPORT_ADDRESS_LENGTH +
+ sizeof(TA_ADDRESS_IP);
+ EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
+ if (!EaInfo)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlZeroMemory(EaInfo, EaLength);
+ EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
+ RtlCopyMemory(EaInfo->EaName,
+ TdiTransportAddress,
+ TDI_TRANSPORT_ADDRESS_LENGTH);
+ EaInfo->EaValueLength = sizeof(TA_ADDRESS_IP);
+ Address = (PTA_ADDRESS_IP)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH);
+ TdiBuildAddressIPv4(Address, Name);
+ Status = TdiOpenDevice(DeviceName,
+ EaLength,
+ EaInfo,
+ AddressHandle,
+ AddressObject);
+ ExFreePool(EaInfo);
+ return Status;
}
NTSTATUS TdiOpenAddressFile(
- PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
- PHANDLE AddressHandle,
- PFILE_OBJECT *AddressObject)
+ PUNICODE_STRING DeviceName,
+ LPSOCKADDR Name,
+ PHANDLE AddressHandle,
+ PFILE_OBJECT *AddressObject)
/*
* FUNCTION: Opens an address file object
* ARGUMENTS:
* Status of operation
*/
{
- NTSTATUS Status;
+ NTSTATUS Status;
+
+ switch (Name->sa_family) {
+ case AF_INET:
+ Status = TdiOpenAddressFileIPv4(
+ DeviceName,
+ Name,
+ AddressHandle,
+ AddressObject);
+ break;
+
+ default:
+ AFD_DbgPrint(MAX_TRACE, ("Unknown socket address family (0x%X)\n",
+ Name->sa_family));
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
- switch (Name->sa_family) {
- case AF_INET:
- Status = TdiOpenAddressFileIPv4(
- DeviceName,
- Name,
- AddressHandle,
- AddressObject);
- break;
- default:
- Status = STATUS_INVALID_PARAMETER;
- }
+NTSTATUS TdiOpenConnectionEndpointFile(
+ PUNICODE_STRING DeviceName,
+ PHANDLE ConnectionHandle,
+ PFILE_OBJECT *ConnectionObject)
+/*
+ * FUNCTION: Opens a connection endpoint file object
+ * ARGUMENTS:
+ * DeviceName = Pointer to counted string with name of device
+ * ConnectionHandle = Address of buffer to place connection endpoint file handle
+ * ConnectionObject = Address of buffer to place connection endpoint file object
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PFILE_FULL_EA_INFORMATION EaInfo;
+ PVOID *ContextArea;
+ NTSTATUS Status;
+ ULONG EaLength;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ)\n", DeviceName));
+
+ EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
+ TDI_CONNECTION_CONTEXT_LENGTH +
+ sizeof(PVOID);
+
+ EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
+ if (!EaInfo)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlZeroMemory(EaInfo, EaLength);
+ EaInfo->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH;
+ RtlCopyMemory(EaInfo->EaName,
+ TdiConnectionContext,
+ TDI_CONNECTION_CONTEXT_LENGTH);
+ EaInfo->EaValueLength = sizeof(PVOID);
+ ContextArea = (PVOID*)(EaInfo->EaName + TDI_CONNECTION_CONTEXT_LENGTH);
+ /* FIXME: Allocate context area */
+ *ContextArea = NULL;
+ Status = TdiOpenDevice(DeviceName,
+ EaLength,
+ EaInfo,
+ ConnectionHandle,
+ ConnectionObject);
+ ExFreePool(EaInfo);
+ return Status;
+}
+
+
+NTSTATUS TdiConnect(
+ PFILE_OBJECT ConnectionObject,
+ LPSOCKADDR RemoteAddress)
+/*
+ * FUNCTION: Connect a connection endpoint to a remote peer
+ * ARGUMENTS:
+ * ConnectionObject = Pointer to connection endpoint file object
+ * RemoteAddress = Pointer to remote address
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PTDI_CONNECTION_INFORMATION RequestConnectionInfo;
+ PTDI_CONNECTION_INFORMATION ReturnConnectionInfo;
+ PDEVICE_OBJECT DeviceObject;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ KEVENT Event;
+ PIRP Irp;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+
+ assert(ConnectionObject);
+
+ DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
+
+ Status = TdiBuildConnectionInfo(&RequestConnectionInfo, RemoteAddress);
+ if (!NT_SUCCESS(Status))
return Status;
+
+ /* Use same TDI address type for return connection information */
+ Status = TdiBuildConnectionInfo(&ReturnConnectionInfo, RemoteAddress);
+ if (!NT_SUCCESS(Status)) {
+ ExFreePool(RequestConnectionInfo);
+ return Status;
+ }
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, /* Sub function */
+ DeviceObject, /* Device object */
+ ConnectionObject, /* File object */
+ &Event, /* Event */
+ &Iosb); /* Status */
+ if (!Irp) {
+ ExFreePool(RequestConnectionInfo);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ TdiBuildConnect(Irp, /* IRP */
+ DeviceObject, /* Device object */
+ ConnectionObject, /* File object */
+ NULL, /* Completion routine */
+ NULL, /* Completion routine context */
+ NULL, /* Time */
+ RequestConnectionInfo, /* Request connection information */
+ ReturnConnectionInfo); /* Return connection information */
+
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
+
+ ExFreePool(RequestConnectionInfo);
+ ExFreePool(ReturnConnectionInfo);
+
+ return Status;
+}
+
+
+NTSTATUS TdiAssociateAddressFile(
+ HANDLE AddressHandle,
+ PFILE_OBJECT ConnectionObject)
+/*
+ * FUNCTION: Associates a connection endpoint to an address file object
+ * ARGUMENTS:
+ * AddressHandle = Handle to address file object
+ * ConnectionObject = Connection endpoint file object
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PDEVICE_OBJECT DeviceObject;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ KEVENT Event;
+ PIRP Irp;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (0x%X) ConnectionObject (0x%X)\n",
+ AddressHandle, ConnectionObject));
+
+ assert(ConnectionObject);
+
+ DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS, /* Sub function */
+ DeviceObject, /* Device object */
+ ConnectionObject, /* File object */
+ &Event, /* Event */
+ &Iosb); /* Status */
+ if (!Irp)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ TdiBuildAssociateAddress(Irp,
+ DeviceObject,
+ ConnectionObject,
+ NULL,
+ NULL,
+ AddressHandle);
+
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
+
+ return Status;
}
* Specify NULL for Handler to stop calling event handler
*/
{
- PDEVICE_OBJECT DeviceObject;
- IO_STATUS_BLOCK Iosb;
- NTSTATUS Status;
- PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ KEVENT Event;
+ PIRP Irp;
- AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+ AFD_DbgPrint(MAX_TRACE, ("Called\n"));
- assert(FileObject);
+ assert(FileObject);
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
- Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */
- DeviceObject, /* Device object */
- FileObject, /* File object */
- NULL, /* Event */
- NULL); /* Status */
- if (!Irp) {
- AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
- TdiBuildSetEventHandler(Irp,
- DeviceObject,
- FileObject,
- NULL,
- NULL,
- EventType,
- Handler,
- Context);
+ Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */
+ DeviceObject, /* Device object */
+ FileObject, /* File object */
+ &Event, /* Event */
+ &Iosb); /* Status */
+ if (!Irp)
+ return STATUS_INSUFFICIENT_RESOURCES;
- Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
- return Status;
+
+ TdiBuildSetEventHandler(Irp,
+ DeviceObject,
+ FileObject,
+ NULL,
+ NULL,
+ EventType,
+ Handler,
+ Context);
+
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
+
+ return Status;
}
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
+ KEVENT Event;
PIRP Irp;
DeviceObject = IoGetRelatedDeviceObject(FileObject);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
DeviceObject,
InputBuffer,
OutputBuffer,
OutputBufferLength,
FALSE,
- NULL,
- NULL);
- if (!Irp) {
- AFD_DbgPrint(MIN_TRACE, ("IoBuildDeviceIoControlRequest() failed.\n"));
+ &Event,
+ &Iosb);
+ if (!Irp)
return STATUS_INSUFFICIENT_RESOURCES;
- }
+
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
- Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
if (Return)
*Return = Iosb.Information;
DWORD TdiAddressSize;
PVOID BaseAddress;
NTSTATUS Status;
+ KEVENT Event;
PIRP Irp;
PMDL Mdl;
TdiBuildAddress(ConnectInfo->RemoteAddress, Address);
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
- NULL, /* Event */
- NULL); /* Return buffer */
+ &Event, /* Event */
+ &Iosb); /* Status */
if (!Irp) {
AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
ExFreePool(ConnectInfo);
BufferSize, /* Size of data to send */
ConnectInfo); /* Connection information */
- Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
MmUnmapLockedPages(BaseAddress, Mdl);
IO_STATUS_BLOCK Iosb;
DWORD TdiAddressSize;
NTSTATUS Status;
+ KEVENT Event;
PIRP Irp;
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
TdiBuildAddress(ConnectInfo->RemoteAddress, Address);
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
- NULL, /* Event */
- NULL); /* Return buffer */
+ &Event, /* Event */
+ &Iosb); /* Status */
if (!Irp) {
AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
ExFreePool(ConnectInfo);
BufferSize, /* Size of data to send */
ConnectInfo); /* Connection information */
- Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
#if 0
MmUnlockPages(Mdl);
IO_STATUS_BLOCK Iosb;
DWORD TdiAddressSize;
NTSTATUS Status;
+ KEVENT Event;
PIRP Irp;
PMDL Mdl;
ReturnInfo->RemoteAddress = (PVOID)
(ReturnInfo + sizeof(TDI_CONNECTION_INFORMATION));
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
- NULL, /* Event */
- NULL); /* Return buffer */
+ &Event, /* Event */
+ &Iosb); /* Status */
if (!Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
ExFreePool(ReceiveInfo);
ReceiveInfo, /* Connection information */
ReturnInfo, /* Connection information */
TDI_RECEIVE_NORMAL); /* Flags */
- Status = TdiCall(Irp, DeviceObject, &Iosb, TRUE, NULL);
+ Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
if (NT_SUCCESS(Status)) {
*BufferSize = Iosb.Information;
TdiBuildName(Address, ReturnInfo->RemoteAddress);
KSPIN_LOCK ReceiveQueueLock;
LIST_ENTRY ReadRequestQueue;
KSPIN_LOCK ReadRequestQueueLock;
+ /* For WSAEventSelect() */
+ WSANETWORKEVENTS NetworkEvents;
+ WSAEVENT EventObjects[FD_MAX_EVENTS];
} AFDFCB, *PAFDFCB;
/* Socket states */
#define SOCKET_STATE_CREATED 0
#define SOCKET_STATE_BOUND 1
#define SOCKET_STATE_LISTENING 2
+#define SOCKET_STATE_CONNECTED 3
typedef struct _AFD_BUFFER {
LIST_ENTRY ListEntry;
PIRP Irp,
PIO_STACK_LOCATION IrpSp);
+NTSTATUS AfdDispEventSelect(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+NTSTATUS AfdDispEnumNetworkEvents(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+NTSTATUS AfdDispRecv(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+NTSTATUS AfdDispSend(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
+NTSTATUS AfdDispConnect(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
/* Prototypes from event.c */
NTSTATUS AfdRegisterEventHandlers(
/* Prototypes from tdi.c */
NTSTATUS TdiCloseDevice(
- HANDLE Handle,
- PFILE_OBJECT FileObject);
+ HANDLE Handle,
+ PFILE_OBJECT FileObject);
NTSTATUS TdiOpenAddressFileIPv4(
- PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
- PHANDLE AddressHandle,
- PFILE_OBJECT *AddressObject);
+ PUNICODE_STRING DeviceName,
+ LPSOCKADDR Name,
+ PHANDLE AddressHandle,
+ PFILE_OBJECT *AddressObject);
NTSTATUS TdiOpenAddressFile(
- PUNICODE_STRING DeviceName,
- LPSOCKADDR Name,
- PHANDLE AddressHandle,
- PFILE_OBJECT *AddressObject);
+ PUNICODE_STRING DeviceName,
+ LPSOCKADDR Name,
+ PHANDLE AddressHandle,
+ PFILE_OBJECT *AddressObject);
+
+NTSTATUS TdiOpenConnectionEndpointFile(
+ PUNICODE_STRING DeviceName,
+ PHANDLE ConnectionHandle,
+ PFILE_OBJECT *ConnectionObject);
+
+NTSTATUS TdiConnect(
+ PFILE_OBJECT ConnectionObject,
+ LPSOCKADDR RemoteAddress);
+
+NTSTATUS TdiAssociateAddressFile(
+ HANDLE AddressHandle,
+ PFILE_OBJECT ConnectionObject);
NTSTATUS TdiSetEventHandler(
- PFILE_OBJECT FileObject,
- LONG EventType,
- PVOID Handler,
- PVOID Context);
+ PFILE_OBJECT FileObject,
+ LONG EventType,
+ PVOID Handler,
+ PVOID Context);
NTSTATUS TdiQueryDeviceControl(
- PFILE_OBJECT FileObject,
- ULONG IoControlCode,
- PVOID InputBuffer,
- ULONG InputBufferLength,
- PVOID OutputBuffer,
- ULONG OutputBufferLength,
- PULONG Return);
+ PFILE_OBJECT FileObject,
+ ULONG IoControlCode,
+ PVOID InputBuffer,
+ ULONG InputBufferLength,
+ PVOID OutputBuffer,
+ ULONG OutputBufferLength,
+ PULONG Return);
NTSTATUS TdiQueryInformationEx(
- PFILE_OBJECT FileObject,
- ULONG Entity,
- ULONG Instance,
- ULONG Class,
- ULONG Type,
- ULONG Id,
- PVOID OutputBuffer,
- PULONG OutputLength);
+ PFILE_OBJECT FileObject,
+ ULONG Entity,
+ ULONG Instance,
+ ULONG Class,
+ ULONG Type,
+ ULONG Id,
+ PVOID OutputBuffer,
+ PULONG OutputLength);
NTSTATUS TdiQueryAddress(
- PFILE_OBJECT FileObject,
- PULONG Address);
+ PFILE_OBJECT FileObject,
+ PULONG Address);
NTSTATUS TdiSend(
- PFILE_OBJECT TransportObject,
- PVOID Buffer,
- ULONG BufferSize);
+ PFILE_OBJECT TransportObject,
+ PVOID Buffer,
+ ULONG BufferSize);
NTSTATUS TdiSendDatagram(
- PFILE_OBJECT TransportObject,
- LPSOCKADDR Address,
- PMDL Mdl,
- ULONG BufferSize);
+ PFILE_OBJECT TransportObject,
+ LPSOCKADDR Address,
+ PMDL Mdl,
+ ULONG BufferSize);
#endif /*__AFD_H */
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
-
KeAcquireSpinLockAtDpcLevel(&LoopLock);
for (;;) {
if (!NdisPacket)
break;
- LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
+ TI_DbgPrint(MAX_TRACE, ("NdisPacket (0x%X)\n", NdisPacket));
+ LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
KeReleaseSpinLockFromDpcLevel(&LoopLock);
-
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
-
IPReceive(Context, &IPPacket);
-
AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
-
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
-
/* Lower IRQL for a moment to prevent starvation */
KeLowerIrql(OldIrql);
-
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
-
KeAcquireSpinLockAtDpcLevel(&LoopLock);
}
-
LoopBusy = FALSE;
-
KeReleaseSpinLockFromDpcLevel(&LoopLock);
-
KeLowerIrql(OldIrql);
}
/* If LoopTransmit is not running (or scheduled), schedule it to run */
if (!LoopBusy) {
- ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
LoopBusy = TRUE;
+ ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
}
KeReleaseSpinLock(&LoopLock, OldIrql);
#ifndef __ADDRESS_H
#define __ADDRESS_H
-
/*
* Initialize an IPv4 style address
* VOID AddrInitIPv4(
*/
#define AddrInitIPv4(IPAddress, RawAddress) \
{ \
+ INIT_TAG((IPAddress), TAG('I','P','V','4')); \
(IPAddress)->RefCount = 1; \
(IPAddress)->Type = IP_ADDRESS_V4; \
(IPAddress)->Address.IPv4Address = (RawAddress); \
+ (IPAddress)->Free = IPAddressFree; \
}
#ifdef DBG
#endif /* DBG */
+VOID IPAddressFree(
+ PVOID Object);
+
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address);
PUSHORT Port,
PIP_ADDRESS *Cache);
+NTSTATUS AddrBuildAddress(
+ PTA_ADDRESS TdiAddress,
+ PIP_ADDRESS *Address,
+ PUSHORT Port);
+
BOOLEAN AddrIsEqual(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2);
VOID DGSend(
- PVOID Context,
- PDATAGRAM_SEND_REQUEST SendRequest);
+ PVOID Context,
+ PDATAGRAM_SEND_REQUEST SendRequest);
VOID DGDeliverData(
- PADDRESS_FILE AddrFile,
- PIP_ADDRESS Address,
- PIP_PACKET IPPacket,
- UINT DataSize);
+ PADDRESS_FILE AddrFile,
+ PIP_ADDRESS Address,
+ PIP_PACKET IPPacket,
+ UINT DataSize);
VOID DGCancelSendRequest(
- PADDRESS_FILE AddrFile,
- PVOID Context);
+ PADDRESS_FILE AddrFile,
+ PVOID Context);
VOID DGCancelReceiveRequest(
- PADDRESS_FILE AddrFile,
- PVOID Context);
+ PADDRESS_FILE AddrFile,
+ PVOID Context);
+
+NTSTATUS DGTransmit(
+ PADDRESS_FILE AddressFile,
+ PDATAGRAM_SEND_REQUEST SendRequest);
NTSTATUS DGSendDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG DataSize,
- DATAGRAM_BUILD_ROUTINE Build);
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG DataSize,
+ DATAGRAM_BUILD_ROUTINE Build);
NTSTATUS DGReceiveDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG ReceiveLength,
- ULONG ReceiveFlags,
- PTDI_CONNECTION_INFORMATION ReturnInfo,
- PULONG BytesReceived);
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG ReceiveLength,
+ ULONG ReceiveFlags,
+ PTDI_CONNECTION_INFORMATION ReturnInfo,
+ PULONG BytesReceived);
NTSTATUS DGStartup(
- VOID);
+ VOID);
NTSTATUS DGShutdown(
- VOID);
+ VOID);
#endif /* __DATAGRAM_H */
#define DEBUG_ROUTER 0x00040000
#define DEBUG_RCACHE 0x00080000
#define DEBUG_NCACHE 0x00100000
+#define DEBUG_CPOINT 0x00200000
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
+extern LIST_ENTRY ConnectionEndpointListHead;
+extern KSPIN_LOCK ConnectionEndpointListLock;
NTSTATUS FileOpenAddress(
- PTDI_REQUEST Request,
- PTA_ADDRESS_IP AddrList,
- USHORT Protocol,
- PVOID Options);
+ PTDI_REQUEST Request,
+ PTA_ADDRESS_IP AddrList,
+ USHORT Protocol,
+ PVOID Options);
NTSTATUS FileCloseAddress(
- PTDI_REQUEST Request);
+ PTDI_REQUEST Request);
+
+NTSTATUS FileOpenConnection(
+ PTDI_REQUEST Request,
+ PVOID ClientContext);
NTSTATUS FileCloseConnection(
- PTDI_REQUEST Request);
+ PTDI_REQUEST Request);
+
+NTSTATUS FileOpenControlChannel(
+ PTDI_REQUEST Request);
NTSTATUS FileCloseControlChannel(
- PTDI_REQUEST Request);
+ PTDI_REQUEST Request);
#endif /* __FILEOBJS_H */
#ifndef __IP_H
#define __IP_H
+typedef VOID (*OBJECT_FREE_ROUTINE)(PVOID Object);
+
+
/* Raw IPv4 style address */
typedef ULONG IPv4_RAW_ADDRESS;
typedef IPv4_RAW_ADDRESS *PIPv4_RAW_ADDRESS;
/* IP style address */
typedef struct IP_ADDRESS {
+ DEFINE_TAG
ULONG RefCount; /* Number of references to this address */
UCHAR Type; /* Type of IP address */
union {
IPv4_RAW_ADDRESS IPv4Address; /* IPv4 address (in network byte order) */
PIPv6_RAW_ADDRESS IPv6Address; /* IPv6 address (in network byte order) */
} Address;
+ OBJECT_FREE_ROUTINE Free; /* The free routine */
} IP_ADDRESS, *PIP_ADDRESS;
/* IP type constants */
/* Structure for an IP packet */
typedef struct IP_PACKET {
+ DEFINE_TAG
ULONG RefCount; /* Reference count for this object */
+ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */
UCHAR Flags; /* Flags for packet (see IP_PACKET_FLAG_xx below)*/
PVOID Header; /* Pointer to IP header for this packet */
/* Address information a.k.a ADE */
typedef struct _ADDRESS_ENTRY {
+ DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
+ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
struct _NET_TABLE_ENTRY *NTE; /* NTE associated with this address */
UCHAR Type; /* Address type */
PIP_ADDRESS Address; /* Pointer to address identifying this entry */
/* There is one NTE for each source (unicast) address assigned to an interface */
typedef struct _NET_TABLE_ENTRY {
+ DEFINE_TAG
LIST_ENTRY IFListEntry; /* Entry on interface list */
LIST_ENTRY NTListEntry; /* Entry on net table list */
struct _IP_INTERFACE *Interface; /* Pointer to interface on this net */
struct _PREFIX_LIST_ENTRY *PLE; /* Pointer to prefix list entry for this net */
ULONG RefCount; /* Reference count */
+ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
PIP_ADDRESS Address; /* Pointer to unicast address for this net */
} NET_TABLE_ENTRY, *PNET_TABLE_ENTRY;
/* Information about an IP interface */
typedef struct _IP_INTERFACE {
+ DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
+ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources used by the object */
KSPIN_LOCK Lock; /* Spin lock for this object */
LIST_ENTRY NTEListHead; /* List of NTEs on this interface */
LIST_ENTRY ADEListHead; /* List of ADEs on this interface */
/* Prefix List Entry */
typedef struct _PREFIX_LIST_ENTRY {
+ DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
PIP_INTERFACE Interface; /* Pointer to interface */
extern UINT MaxLLHeaderSize;
extern UINT MinLLFrameSize;
+PIP_PACKET IPCreatePacket(
+ ULONG Type);
PNET_TABLE_ENTRY IPCreateNTE(
PIP_INTERFACE IF,
/* Information about a neighbor */
typedef struct NEIGHBOR_CACHE_ENTRY {
+ DEFINE_TAG
struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */
struct NEIGHBOR_CACHE_TABLE *Table; /* Pointer to table */
ULONG RefCount; /* Number of references */
+ OBJECT_FREE_ROUTINE Free; /* Routine to free resources for the object */
UCHAR State; /* State of NCE */
UINT EventTimer; /* Ticks since last event */
UINT EventCount; /* Number of events */
extern LIST_ENTRY ReassemblyListHead;
extern KSPIN_LOCK ReassemblyListLock;
+extern NPAGED_LOOKASIDE_LIST IPDRList;
+extern NPAGED_LOOKASIDE_LIST IPFragmentList;
+extern NPAGED_LOOKASIDE_LIST IPHoleList;
VOID IPFreeReassemblyList(
struct ROUTE_CACHE_NODE *Left; /* Pointer to left child */
struct ROUTE_CACHE_NODE *Right; /* Pointer to right child */
/* Memebers above this line must not be moved */
+ DEFINE_TAG
ULONG RefCount; /* Reference count */
+ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
UCHAR State; /* RCN state (RCN_STATE_*) */
IP_ADDRESS Destination; /* Destination address */
PNET_TABLE_ENTRY NTE; /* Preferred NTE */
#define RCN_STATE_COMPUTED 0x01 /* RCN is computed */
+extern NPAGED_LOOKASIDE_LIST IPRCNList;
+
+
#define IsExternalRCN(RCN) \
(RCN == ExternalRCN)
typedef struct _FIB_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
+ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
PIP_ADDRESS NetworkAddress; /* Address of network */
PIP_ADDRESS Netmask; /* Netmask of network */
PNET_TABLE_ENTRY NTE; /* Pointer to NTE to use */
#define __ROUTINES_H
+inline NTSTATUS BuildDatagramSendRequest(
+ PDATAGRAM_SEND_REQUEST *SendRequest,
+ PIP_ADDRESS RemoteAddress,
+ USHORT RemotePort,
+ PNDIS_BUFFER Buffer,
+ DWORD BufferSize,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ DATAGRAM_BUILD_ROUTINE Build,
+ ULONG Flags);
+
+inline NTSTATUS BuildTCPSendRequest(
+ PTCP_SEND_REQUEST *SendRequest,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ PVOID ProtocolContext);
+
UINT Random(
VOID);
#ifndef __TCP_H
#define __TCP_H
+
+/* TCPv4 header structure */
+typedef struct TCP_HEADER {
+ USHORT SourcePort; /* Source port */
+ USHORT DestPort; /* Destination port */
+ USHORT SeqNum; /* Sequence number */
+ USHORT AckNum; /* Acknowledgment number */
+ UCHAR DataOfs; /* Data offset (leftmost 4 bits) */
+ UCHAR Flags; /* Control bits (rightmost 6 bits) */
+ USHORT Window; /* Maximum acceptable receive window */
+ USHORT Checksum; /* Checksum of segment */
+ USHORT Urgent; /* Pointer to urgent data */
+} __attribute__((packed)) TCP_HEADER, *PTCP_HEADER;
+
+/* TCPv4 header flags */
+#define TCP_URG 0x04
+#define TCP_ACK 0x08
+#define TCP_PSH 0x10
+#define TCP_RST 0x20
+#define TCP_SYN 0x40
+#define TCP_FIN 0x80
+
+
+#define TCPOPT_END_OF_LIST 0x0
+#define TCPOPT_NO_OPERATION 0x1
+#define TCPOPT_MAX_SEG_SIZE 0x2
+
+#define TCPOPTLEN_MAX_SEG_SIZE 0x4
+
+
+/* TCPv4 pseudo header */
+typedef struct TCP_PSEUDO_HEADER {
+ ULONG SourceAddress; /* Source address */
+ ULONG DestAddress; /* Destination address */
+ UCHAR Zero; /* Reserved */
+ UCHAR Protocol; /* Protocol */
+ USHORT TCPLength; /* Size of TCP segment */
+} __attribute__((packed)) TCP_PSEUDO_HEADER, *PTCP_PSEUDO_HEADER;
+
+
+/* Retransmission timeout constants */
+
+/* Lower bound for retransmission timeout in TCP timer ticks */
+#define TCP_MIN_RETRANSMISSION_TIMEOUT 1*1000 /* 1 tick */
+
+/* Upper bound for retransmission timeout in TCP timer ticks */
+#define TCP_MAX_RETRANSMISSION_TIMEOUT 1*60*1000 /* 1 tick */
+
+/* Smoothing factor */
+#define TCP_ALPHA_RETRANSMISSION_TIMEOUT(x)(((x)*8)/10) /* 0.8 */
+
+/* Delay variance factor */
+#define TCP_BETA_RETRANSMISSION_TIMEOUT(x)(((x)*16)/10) /* 1.6 */
+
+
+/* Datagram/segment send request flags */
+
+#define SRF_URG TCP_URG
+#define SRF_ACK TCP_ACK
+#define SRF_PSH TCP_PSH
+#define SRF_RST TCP_RST
+#define SRF_SYN TCP_SYN
+#define SRF_FIN TCP_FIN
+
+
+inline NTSTATUS TCPBuildSendRequest(
+ PTCP_SEND_REQUEST *SendRequest,
+ PDATAGRAM_SEND_REQUEST *DGSendRequest,
+ PCONNECTION_ENDPOINT Connection,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ PNDIS_BUFFER Buffer,
+ DWORD BufferSize,
+ ULONG Flags);
+
+inline NTSTATUS TCPBuildAndTransmitSendRequest(
+ PCONNECTION_ENDPOINT Connection,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ PNDIS_BUFFER Buffer,
+ DWORD BufferSize,
+ ULONG Flags);
+
+NTSTATUS TCPConnect(
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PTDI_CONNECTION_INFORMATION ReturnInfo);
+
+NTSTATUS TCPSendDatagram(
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG DataSize);
+
NTSTATUS TCPStartup(
- VOID);
+ VOID);
NTSTATUS TCPShutdown(
- VOID);
+ VOID);
#endif /* __TCP_H */
#ifndef __TITYPES_H
#define __TITYPES_H
-#include <ip.h>
-
#ifdef DBG
-#define DEBUG_REFCHECK(Object) { \
- if ((Object)->RefCount <= 0) { \
- TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \
- (Object), (Object)->RefCount)); \
- } \
+#define DEFINE_TAG ULONG Tag;
+#define INIT_TAG(_Object, _Tag) \
+ ((_Object)->Tag = (_Tag))
+
+#define DEBUG_REFCHECK(Object) { \
+ if ((Object)->RefCount <= 0) { \
+ TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \
+ (Object), (Object)->RefCount)); \
+ } \
}
-#else
+/*
+ * VOID ReferenceObject(
+ * PVOID Object)
+ */
+#define ReferenceObject(Object) \
+{ \
+ CHAR c1, c2, c3, c4; \
+ \
+ c1 = ((Object)->Tag >> 24) & 0xFF; \
+ c2 = ((Object)->Tag >> 16) & 0xFF; \
+ c3 = ((Object)->Tag >> 8) & 0xFF; \
+ c4 = ((Object)->Tag & 0xFF); \
+ \
+ DEBUG_REFCHECK(Object); \
+ TI_DbgPrint(DEBUG_REFCOUNT, ("Referencing object of type (%c%c%c%c) at (0x%X). RefCount (%d).\n", \
+ c4, c3, c2, c1, (Object), (Object)->RefCount)); \
+ \
+ InterlockedIncrement(&((Object)->RefCount)); \
+}
-#define DEBUG_REFCHECK(Object)
+ /*
+ * VOID DereferenceObject(
+ * PVOID Object)
+ */
+#define DereferenceObject(Object) \
+{ \
+ CHAR c1, c2, c3, c4; \
+ \
+ c1 = ((Object)->Tag >> 24) & 0xFF; \
+ c2 = ((Object)->Tag >> 16) & 0xFF; \
+ c3 = ((Object)->Tag >> 8) & 0xFF; \
+ c4 = ((Object)->Tag & 0xFF); \
+ \
+ DEBUG_REFCHECK(Object); \
+ TI_DbgPrint(DEBUG_REFCOUNT, ("Dereferencing object of type (%c%c%c%c) at (0x%X). RefCount (%d).\n", \
+ c4, c3, c2, c1, (Object), (Object)->RefCount)); \
+ \
+ if (InterlockedDecrement(&((Object)->RefCount)) == 0) \
+ (((Object)->Free)(Object)); \
+}
-#endif
+#else /* DBG */
+#define DEFINE_TAG
+#define INIT_TAG (Object, Tag)
/*
* VOID ReferenceObject(
*/
#define ReferenceObject(Object) \
{ \
- DEBUG_REFCHECK(Object); \
- TI_DbgPrint(DEBUG_REFCOUNT, ("Referencing object at (0x%X). RefCount (%d).\n", \
- (Object), (Object)->RefCount)); \
- \
InterlockedIncrement(&((Object)->RefCount)); \
}
*/
#define DereferenceObject(Object) \
{ \
- DEBUG_REFCHECK(Object); \
- TI_DbgPrint(DEBUG_REFCOUNT, ("Dereferencing object at (0x%X). RefCount (%d).\n", \
- (Object), (Object)->RefCount)); \
- \
if (InterlockedDecrement(&((Object)->RefCount)) == 0) \
- PoolFreeBuffer(Object); \
+ (((Object)->Free)(Object)); \
}
+#endif /* DBG */
+
+
+#include <ip.h>
+
+
+/***************************************************
+* Connection-less communication support structures *
+***************************************************/
typedef NTSTATUS (*DATAGRAM_SEND_ROUTINE)(
PTDI_REQUEST Request,
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
DATAGRAM_BUILD_ROUTINE Build; /* Datagram build routine */
+ ULONG Flags; /* Protocol specific flags */
} DATAGRAM_SEND_REQUEST, *PDATAGRAM_SEND_REQUEST;
-
-/* Transport (TCP/UDP) endpoint context structure. The FileObject->FsContext
+#define InitializeDatagramSendRequest( \
+ _SendRequest, \
+ _RemoteAddress, \
+ _RemotePort, \
+ _Buffer, \
+ _BufferSize, \
+ _Complete, \
+ _Context, \
+ _Build, \
+ _Flags) { \
+ (_SendRequest)->RemoteAddress = (_RemoteAddress); \
+ (_SendRequest)->RemotePort = (_RemotePort); \
+ (_SendRequest)->Buffer = (_Buffer); \
+ (_SendRequest)->BufferSize = (_BufferSize); \
+ (_SendRequest)->Complete = (_Complete); \
+ (_SendRequest)->Context = (_Context); \
+ (_SendRequest)->Build = (_Build); \
+ (_SendRequest)->Flags = (_Flags); \
+ }
+
+/* Transport address file context structure. The FileObject->FsContext2
field holds a pointer to this structure */
-typedef struct _TRANSPORT_CONTEXT {
- union {
- HANDLE AddressHandle;
- CONNECTION_CONTEXT ConnectionContext;
- HANDLE ControlChannel;
- } Handle;
- ULONG RefCount;
- BOOL CancelIrps;
- KEVENT CleanupEvent;
-} TRANSPORT_CONTEXT, *PTRANSPORT_CONTEXT;
-
-
typedef struct _ADDRESS_FILE {
+ DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
ULONG RefCount; /* Number of references to this object */
+ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */
USHORT Flags; /* Flags for address file (see below) */
PADDRESS_ENTRY ADE; /* Associated address entry */
USHORT Protocol; /* Protocol number */
DATAGRAM_SEND_ROUTINE Send; /* Routine to send a datagram */
LIST_ENTRY ReceiveQueue; /* List of outstanding receive requests */
LIST_ENTRY TransmitQueue; /* List of outstanding transmit requests */
+ LIST_ENTRY Connections; /* List of associated connections */
PIP_ADDRESS AddrCache; /* One entry address cache (destination
address of last packet transmitted) */
/* The following members are used to control event notification */
/* Connection indication handler */
- PTDI_IND_CONNECT ConnectionHandler;
- PVOID ConnectionHandlerContext;
- BOOL RegisteredConnectionHandler;
+ PTDI_IND_CONNECT ConnectHandler;
+ PVOID ConnectHandlerContext;
+ BOOL RegisteredConnectHandler;
/* Disconnect indication handler */
PTDI_IND_DISCONNECT DisconnectHandler;
PVOID DisconnectHandlerContext;
BOOL RegisteredDisconnectHandler;
+ /* Error indication handler */
+ PTDI_IND_ERROR ErrorHandler;
+ PVOID ErrorHandlerContext;
+ PVOID ErrorHandlerOwner;
+ BOOL RegisteredErrorHandler;
/* Receive indication handler */
PTDI_IND_RECEIVE ReceiveHandler;
PVOID ReceiveHandlerContext;
BOOL RegisteredReceiveHandler;
- /* Expedited receive indication handler */
- PTDI_IND_RECEIVE_EXPEDITED ExpeditedReceiveHandler;
- PVOID ExpeditedReceiveHandlerContext;
- BOOL RegisteredExpeditedReceiveHandler;
/* Receive datagram indication handler */
PTDI_IND_RECEIVE_DATAGRAM ReceiveDatagramHandler;
PVOID ReceiveDatagramHandlerContext;
BOOL RegisteredReceiveDatagramHandler;
- /* Error indication handler */
- PTDI_IND_ERROR ErrorHandler;
- PVOID ErrorHandlerContext;
- PVOID ErrorHandlerOwner;
- BOOL RegisteredErrorHandler;
+ /* Expedited receive indication handler */
+ PTDI_IND_RECEIVE_EXPEDITED ExpeditedReceiveHandler;
+ PVOID ExpeditedReceiveHandlerContext;
+ BOOL RegisteredExpeditedReceiveHandler;
+ /* Chained receive indication handler */
+ PTDI_IND_CHAINED_RECEIVE ChainedReceiveHandler;
+ PVOID ChainedReceiveHandlerContext;
+ BOOL RegisteredChainedReceiveHandler;
+ /* Chained receive datagram indication handler */
+ PTDI_IND_CHAINED_RECEIVE_DATAGRAM ChainedReceiveDatagramHandler;
+ PVOID ChainedReceiveDatagramHandlerContext;
+ BOOL RegisteredChainedReceiveDatagramHandler;
+ /* Chained expedited receive indication handler */
+ PTDI_IND_CHAINED_RECEIVE_EXPEDITED ChainedReceiveExpeditedHandler;
+ PVOID ChainedReceiveExpeditedHandlerContext;
+ BOOL RegisteredChainedReceiveExpeditedHandler;
} ADDRESS_FILE, *PADDRESS_FILE;
/* Address File Flag constants */
USHORT Protocol; /* Protocol number */
} AF_SEARCH, *PAF_SEARCH;
-/* Transport connection context structure. The FileObject->FsContext2
- field holds a pointer to this structure */
+
+
+/*******************************************************
+* Connection-oriented communication support structures *
+*******************************************************/
+
+typedef struct _TCP_SEND_REQUEST {
+ LIST_ENTRY ListEntry; /* Entry on list */
+ DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
+ PVOID Context; /* Pointer to context information */
+ PVOID ProtocolContext; /* Protocol specific context */
+ ULONG Flags; /* Protocol specific flags */
+} TCP_SEND_REQUEST, *PTCP_SEND_REQUEST;
+
+#define InitializeTCPSendRequest( \
+ _SendRequest, \
+ _Complete, \
+ _Context, \
+ _ProtocolContext) { \
+ (_SendRequest)->Complete = (_Complete); \
+ (_SendRequest)->Context = (_Context); \
+ (_SendRequest)->ProtocolContext = (_ProtocolContext); \
+ }
+
+
+/* Connection states */
+typedef enum {
+ ctListen = 0, /* Waiting for incoming connection requests */
+ ctSynSent, /* Waiting for matching connection request */
+ ctSynReceived, /* Waiting for connection request acknowledgment */
+ ctEstablished, /* Connection is open for data transfer */
+ ctFinWait1, /* Waiting for termination request or ack. for same */
+ ctFinWait2, /* Waiting for termination request from remote TCP */
+ ctCloseWait, /* Waiting for termination request from local user */
+ ctClosing, /* Waiting for termination ack. from remote TCP */
+ ctLastAck, /* Waiting for termination request ack. from remote TCP */
+ ctTimeWait, /* Waiting for enough time to pass to be sure the remote TCP
+ received the ack. of its connection termination request */
+ ctClosed /* Represents a closed connection */
+} CONNECTION_STATE, *PCONNECTION_STATE;
+
+
+/* Transport connection context structure A.K.A. Transmission Control Block
+ (TCB) in TCP terminology. The FileObject->FsContext2 field holds a pointer
+ to this structure */
typedef struct _CONNECTION_ENDPOINT {
- LIST_ENTRY ListEntry; /* Entry on list */
- KSPIN_LOCK Lock; /* Spin lock to protect this structure */
- ULONG RefCount; /* Number of references to this object */
+ LIST_ENTRY ListEntry; /* Entry on list */
+ LIST_ENTRY AddrFileEntry; /* Entry on address file list */
+ KSPIN_LOCK Lock; /* Spin lock to protect this structure */
+ ULONG RefCount; /* Number of references to this object */
+ PVOID ClientContext; /* Pointer to client context information */
+ PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */
+
+ CONNECTION_STATE State; /* Connection state */
+
+ PIP_ADDRESS LocalAddress; /* Pointer to local IP address */
+ USHORT LocalPort; /* Local port number */
+
+ PIP_ADDRESS RemoteAddress; /* Pointer to remote IP address */
+ USHORT RemotePort; /* Remote port number */
+
+ /* Send sequence variables */
+ ULONG SendUnacknowledged; /* Highest sequence number that is acknowledged */
+ ULONG SendNext; /* Sequence number of last data block sent */
+ ULONG SendWindow; /* Maximum allowed number of octets in a segment */
+ ULONG SendUrgentPointer; /* Sequence number of start of urgent data */
+ ULONG SendWL1; /* Sequence number used for last window update */
+ ULONG SendWL2; /* Acknowledgment number used for last window update */
+ ULONG SendISS; /* Initial send sequence number */
+
+ /* Receive sequence variables */
+ ULONG RecvNext; /* Sequence number of last data block received */
+ ULONG RecvWindow; /* Maximum allowed number of octets in a segment */
+ ULONG RecvUrgentPointer; /* Sequence number of start of urgent data */
+ ULONG RecvIRS; /* Initial receive sequence number */
+
+ /* Statistics for computing the retransmission timeout */
+ ULONG TimestampSend; /* Timestamp when sending a segment */
+ ULONG TimestampAck; /* Timestamp when receiving acknowledgment */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
+
+
+/*************************
+* TDI support structures *
+*************************/
+
/* Transport control channel context structure. The FileObject->FsContext2
field holds a pointer to this structure */
typedef struct _CONTROL_CHANNEL {
ULONG RefCount; /* Number of references to this object */
} CONTROL_CHANNEL, *PCONTROL_CHANNEL;
+/* Transport (TCP/UDP) endpoint context structure. The FileObject->FsContext
+ field holds a pointer to this structure */
+typedef struct _TRANSPORT_CONTEXT {
+ union {
+ HANDLE AddressHandle;
+ CONNECTION_CONTEXT ConnectionContext;
+ HANDLE ControlChannel;
+ } Handle;
+ ULONG RefCount;
+ BOOL CancelIrps;
+ KEVENT CleanupEvent;
+} TRANSPORT_CONTEXT, *PTRANSPORT_CONTEXT;
+
typedef struct _TI_QUERY_CONTEXT {
PIRP Irp;
PMDL InputMdl;
/* UDPv4 header structure */
typedef struct UDP_HEADER {
- USHORT SourcePort; /* Source port */
- USHORT DestPort; /* Destination port */
- USHORT Length; /* Size of header and data */
- USHORT Checksum; /* Checksum of datagram */
-} UDP_HEADER, *PUDP_HEADER;
+ USHORT SourcePort; /* Source port */
+ USHORT DestPort; /* Destination port */
+ USHORT Length; /* Size of header and data */
+ USHORT Checksum; /* Checksum of datagram */
+} __attribute__((packed)) UDP_HEADER, *PUDP_HEADER;
/* UDPv4 pseudo header */
typedef struct UDP_PSEUDO_HEADER {
- ULONG SourceAddress; /* Source address */
- ULONG DestAddress; /* Destination address */
- UCHAR Zero; /* Reserved */
- UCHAR Protocol; /* Protocol */
- USHORT UDPLength; /* Size of UDP datagram */
-} UDP_PSEUDO_HEADER, *PUDP_PSEUDO_HEADER;
+ ULONG SourceAddress; /* Source address */
+ ULONG DestAddress; /* Destination address */
+ UCHAR Zero; /* Reserved */
+ UCHAR Protocol; /* Protocol */
+ USHORT UDPLength; /* Size of UDP datagram */
+} __attribute__((packed)) UDP_PSEUDO_HEADER, *PUDP_PSEUDO_HEADER;
typedef struct UDP_STATISTICS {
- ULONG InputDatagrams;
- ULONG NumPorts;
- ULONG InputErrors;
- ULONG OutputDatagrams;
- ULONG NumAddresses;
+ ULONG InputDatagrams;
+ ULONG NumPorts;
+ ULONG InputErrors;
+ ULONG OutputDatagrams;
+ ULONG NumAddresses;
} UDP_STATISTICS, *PUDP_STATISTICS;
VOID UDPSend(
- PVOID Context,
- PDATAGRAM_SEND_REQUEST SendRequest);
+ PVOID Context,
+ PDATAGRAM_SEND_REQUEST SendRequest);
NTSTATUS UDPSendDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG DataSize);
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG DataSize);
NTSTATUS UDPReceiveDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG ReceiveLength,
- ULONG ReceiveFlags,
- PTDI_CONNECTION_INFORMATION ReturnInfo,
- PULONG BytesReceived);
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG ReceiveLength,
+ ULONG ReceiveFlags,
+ PTDI_CONNECTION_INFORMATION ReturnInfo,
+ PULONG BytesReceived);
VOID UDPReceive(
- PNET_TABLE_ENTRY NTE,
- PIP_PACKET IPPacket);
+ PNET_TABLE_ENTRY NTE,
+ PIP_PACKET IPPacket);
NTSTATUS UDPStartup(
- VOID);
+ VOID);
NTSTATUS UDPShutdown(
- VOID);
+ VOID);
#endif /* __UDP_H */
TI_DbgPrint(DEBUG_ICMP, ("Freeing IP packet at %X.\n", IPPacket));
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
}
TI_DbgPrint(DEBUG_ICMP, ("Called. DataSize (%d).\n", DataSize));
/* Prepare ICMP packet */
- IPPacket = PoolAllocateBuffer(sizeof(IP_PACKET));
+
+ /* FIXME: Assumes IPv4*/
+ IPPacket = IPCreatePacket(IP_ADDRESS_V4);
if (!IPPacket)
return NULL;
- TI_DbgPrint(DEBUG_ICMP, ("IPPacket at (0x%X).\n", IPPacket));
-
/* No special flags */
IPPacket->Flags = 0;
sizeof(ICMP_HEADER) + DataSize;
DataBuffer = ExAllocatePool(NonPagedPool, Size);
if (!DataBuffer) {
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
return NULL;
}
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
ExFreePool(DataBuffer);
return NULL;
}
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
DataBuffer, Size);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
NdisFreePacket(NdisPacket);
ExFreePool(DataBuffer);
return NULL;
/* Send the packet */
if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS) {
FreeNdisPacket(IPPacket->NdisPacket);
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
}
/* We're done with the RCN */
DereferenceObject(RCN);
IPPacket->DstAddr.Address.IPv4Address));
/* Discard packet */
FreeNdisPacket(IPPacket->NdisPacket);
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
}
}
DataSize = 576;
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
- if (!NewPacket) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ if (!NewPacket)
return;
- }
RtlCopyMemory((PVOID)((ULONG_PTR)NewPacket->Data + sizeof(ICMP_HEADER)),
IPPacket->Header, DataSize);
*/
#include <tcpip.h>
#include <ip.h>
+#include <tcp.h>
#include <loopback.h>
#include <neighbor.h>
#include <receive.h>
UINT MaxLLHeaderSize; /* Largest maximum header size */
UINT MinLLFrameSize; /* Largest minimum frame size */
BOOLEAN IPInitialized = FALSE;
+NPAGED_LOOKASIDE_LIST IPPacketList;
IP_PROTOCOL_HANDLER ProtocolTable[IP_PROTOCOL_TABLE_SIZE];
+VOID FreePacket(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an IP packet object
+ * ARGUMENTS:
+ * Object = Pointer to an IP packet structure
+ */
+{
+ ExFreeToNPagedLookasideList(&IPPacketList, Object);
+}
+
+
+VOID FreeADE(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an address entry object
+ * ARGUMENTS:
+ * Object = Pointer to an address entry structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
+VOID FreeNTE(
+ PVOID Object)
+/*
+ * FUNCTION: Frees a net table entry object
+ * ARGUMENTS:
+ * Object = Pointer to an net table entry structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
+VOID FreeIF(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an interface object
+ * ARGUMENTS:
+ * Object = Pointer to an interface structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
PADDRESS_ENTRY CreateADE(
- PIP_INTERFACE IF,
- PIP_ADDRESS Address,
+ PIP_INTERFACE IF, PIP_ADDRESS Address,
UCHAR Type,
PNET_TABLE_ENTRY NTE)
/*
A2S(Address), A2S(NTE->Address)));
/* Allocate space for an ADE and set it up */
- ADE = PoolAllocateBuffer(sizeof(ADDRESS_ENTRY));
+ ADE = ExAllocatePool(NonPagedPool, sizeof(ADDRESS_ENTRY));
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(ADE, TAG('A','D','E',' '));
+ ADE->Free = FreeADE;
ADE->RefCount = 1;
ADE->NTE = NTE;
ADE->Type = Type;
#endif
/* And free the ADE */
- PoolFreeBuffer(ADE);
- TI_DbgPrint(MIN_TRACE, ("Check.\n"));
+ FreeADE(ADE);
}
CurrentEntry = IF->ADEListHead.Flink;
while (CurrentEntry != &IF->ADEListHead) {
NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
/* Destroy the ADE */
DestroyADE(IF, Current);
CurrentEntry = NextEntry;
}
+PIP_PACKET IPCreatePacket(
+ ULONG Type)
+/*
+ * FUNCTION: Creates an IP packet object
+ * ARGUMENTS:
+ * Type = Type of IP packet
+ * RETURNS:
+ * Pointer to the created IP packet. NULL if there was not enough free resources.
+ */
+{
+ PIP_PACKET IPPacket;
+
+ IPPacket = ExAllocateFromNPagedLookasideList(&IPPacketList);
+ if (!IPPacket)
+ return NULL;
+
+ /* FIXME: Is this needed? */
+ RtlZeroMemory(IPPacket, sizeof(IP_PACKET));
+
+ INIT_TAG(IPPacket, TAG('I','P','K','T'));
+
+ IPPacket->Free = FreePacket;
+ IPPacket->RefCount = 1;
+ IPPacket->Type = Type;
+
+ return IPPacket;
+}
+
+
PPREFIX_LIST_ENTRY CreatePLE(
PIP_INTERFACE IF,
PIP_ADDRESS Prefix,
TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix)));
/* Allocate space for an PLE and set it up */
- PLE = PoolAllocateBuffer(sizeof(PREFIX_LIST_ENTRY));
+ PLE = ExAllocatePool(NonPagedPool, sizeof(PREFIX_LIST_ENTRY));
if (!PLE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(PLE, TAG('P','L','E',' '));
PLE->RefCount = 1;
PLE->Interface = IF;
PLE->Prefix = Prefix;
#endif
/* And free the PLE */
- PoolFreeBuffer(PLE);
+ ExFreePool(PLE);
}
CurrentEntry = PrefixListHead.Flink;
while (CurrentEntry != &PrefixListHead) {
NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
/* Destroy the PLE */
DestroyPLE(Current);
CurrentEntry = NextEntry;
TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
/* Allocate room for an NTE */
- NTE = PoolAllocateBuffer(sizeof(NET_TABLE_ENTRY));
+ NTE = ExAllocatePool(NonPagedPool, sizeof(NET_TABLE_ENTRY));
if (!NTE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(NTE, TAG('N','T','E',' '));
+
+ NTE->Free = FreeNTE;
+
NTE->Interface = IF;
/* One reference is for beeing alive and one reference is for the ADE */
ADE = CreateADE(IF, NTE->Address, ADE_UNICAST, NTE);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- PoolFreeBuffer(NTE);
+ ExFreePool(NTE);
return NULL;
}
NTE->PLE = CreatePLE(IF, NTE->Address, PrefixLength);
if (!NTE->PLE) {
DestroyADE(IF, ADE);
- PoolFreeBuffer(NTE);
+ ExFreePool(NTE);
return NULL;
}
}
#endif
/* And free the NTE */
- PoolFreeBuffer(NTE);
+ ExFreePool(NTE);
}
CurrentEntry = IF->NTEListHead.Flink;
while (CurrentEntry != &IF->NTEListHead) {
NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
/* Destroy the NTE */
DestroyNTE(IF, Current);
CurrentEntry = NextEntry;
/* Search the list and return the NTE if found */
CurrentEntry = IF->ADEListHead.Flink;
while (CurrentEntry != &IF->ADEListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
if (AddrIsEqual(Address, Current->Address)) {
ReferenceObject(Current->NTE);
*AddressType = Current->Type;
/* Search the list and return the NTE if found */
CurrentEntry = NetTableListHead.Flink;
while (CurrentEntry != &NetTableListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, NTListEntry);
+ Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, NTListEntry);
NTE = IPLocateNTEOnInterface(Current->Interface, Address, AddressType);
if (NTE) {
ReferenceObject(NTE);
/* Search the interface list */
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
- CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+ CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
/* Search the address entry list and return the ADE if found */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
/* Search the interface list */
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
- CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+ CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
if (CurrentIF != Loopback) {
/* Search the address entry list and return the first appropriate ADE found */
/* Clean possible outdated cached neighbor addresses */
NBTimeout();
+
+ /* Call upper layer timeout routines */
+ TCPTimeout();
}
}
#endif
- IF = PoolAllocateBuffer(sizeof(IP_INTERFACE));
+ IF = ExAllocatePool(NonPagedPool, sizeof(IP_INTERFACE));
if (!IF) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(IF, TAG('F','A','C','E'));
+
+ IF->Free = FreeIF;
IF->RefCount = 1;
IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize;
- if (IF->HeaderSize > MaxLLHeaderSize)
- MaxLLHeaderSize = IF->HeaderSize;
+ if (IF->HeaderSize > MaxLLHeaderSize)
+ MaxLLHeaderSize = IF->HeaderSize;
IF->MinFrameSize = BindInfo->MinFrameSize;
- if (IF->MinFrameSize > MinLLFrameSize)
- MinLLFrameSize = IF->MinFrameSize;
+ if (IF->MinFrameSize > MinLLFrameSize)
+ MinLLFrameSize = IF->MinFrameSize;
IF->MTU = BindInfo->MTU;
IF->Address = BindInfo->Address;
TI_DbgPrint(MIN_TRACE, ("Interface at (0x%X) has (%d) references (should be 0).\n", IF, IF->RefCount));
}
#endif
- PoolFreeBuffer(IF);
+ ExFreePool(IF);
}
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- MaxLLHeaderSize = 0;
+ MaxLLHeaderSize = 0;
MinLLFrameSize = 0;
+ /* Initialize lookaside lists */
+ ExInitializeNPagedLookasideList(
+ &IPDRList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IPDATAGRAM_REASSEMBLY), /* Size of each entry */
+ TAG('I','P','D','R'), /* Tag */
+ 0); /* Depth */
+
+ ExInitializeNPagedLookasideList(
+ &IPPacketList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IP_PACKET), /* Size of each entry */
+ TAG('I','P','P','K'), /* Tag */
+ 0); /* Depth */
+
+ ExInitializeNPagedLookasideList(
+ &IPFragmentList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IP_FRAGMENT), /* Size of each entry */
+ TAG('I','P','F','G'), /* Tag */
+ 0); /* Depth */
+
+ ExInitializeNPagedLookasideList(
+ &IPHoleList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(IPDATAGRAM_HOLE), /* Size of each entry */
+ TAG('I','P','H','L'), /* Tag */
+ 0); /* Depth */
+
/* Start routing subsystem */
RouterStartup();
/* Clear prefix list */
DestroyPLEs();
+ /* Destroy lookaside lists */
+ ExDeleteNPagedLookasideList(&IPHoleList);
+ ExDeleteNPagedLookasideList(&IPDRList);
+ ExDeleteNPagedLookasideList(&IPPacketList);
+ ExDeleteNPagedLookasideList(&IPFragmentList);
+
IPInitialized = FALSE;
return STATUS_SUCCESS;
NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
+VOID FreeNCE(
+ PVOID Object)
+{
+ ExFreePool(Object);
+}
+
+
VOID NCETimeout(
PNEIGHBOR_CACHE_ENTRY NCE)
/*
"LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n",
Interface, Address, LinkAddress, LinkAddressLength, State));
- NCE = PoolAllocateBuffer(sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength);
+ NCE = ExAllocatePool(NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength);
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ INIT_TAG(NCE, TAG('N','C','E',' '));
+
+ /* Initialize NCE free routine */
+ NCE->Free = FreeNCE;
+
/* Reference once for beeing alive and once for the caller */
NCE->RefCount = 2;
NCE->Interface = Interface;
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
- HashValue = *(PULONG)(&NCE->Address->Address);
+ HashValue = *(PULONG)(&NCE->Address->Address);
HashValue ^= HashValue >> 16;
- HashValue ^= HashValue >> 8;
- HashValue ^= HashValue >> 4;
- HashValue &= NB_HASHMASK;
+ HashValue ^= HashValue >> 8;
+ HashValue ^= HashValue >> 4;
+ HashValue &= NB_HASHMASK;
KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 0).\n", CurNCE, CurNCE->RefCount));
}
#endif
- PoolFreeBuffer(CurNCE);
-
+ ExFreePool(CurNCE);
+
KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
return;
LIST_ENTRY ReassemblyListHead;
KSPIN_LOCK ReassemblyListLock;
+NPAGED_LOOKASIDE_LIST IPDRList;
+NPAGED_LOOKASIDE_LIST IPFragmentList;
+NPAGED_LOOKASIDE_LIST IPHoleList;
PIPDATAGRAM_HOLE CreateHoleDescriptor(
- ULONG First,
- ULONG Last)
+ ULONG First,
+ ULONG Last)
/*
* FUNCTION: Returns a pointer to a IP datagram hole descriptor
* ARGUMENTS:
* resources
*/
{
- PIPDATAGRAM_HOLE Hole;
+ PIPDATAGRAM_HOLE Hole;
- TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last));
+ TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last));
- Hole = PoolAllocateBuffer(sizeof(IPDATAGRAM_HOLE));
- if (!Hole) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return NULL;
- }
+ Hole = ExAllocateFromNPagedLookasideList(&IPHoleList);
+ if (!Hole) {
+ TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ return NULL;
+ }
- Hole->First = First;
- Hole->Last = Last;
+ Hole->First = First;
+ Hole->Last = Last;
- TI_DbgPrint(DEBUG_IP, ("Returning hole descriptor at (0x%X).\n", Hole));
+ TI_DbgPrint(DEBUG_IP, ("Returning hole descriptor at (0x%X).\n", Hole));
- return Hole;
+ return Hole;
}
VOID FreeIPDR(
- PIPDATAGRAM_REASSEMBLY IPDR)
+ PIPDATAGRAM_REASSEMBLY IPDR)
/*
* FUNCTION: Frees an IP datagram reassembly structure
* ARGUMENTS:
* IPDR = Pointer to IP datagram reassembly structure
*/
{
- PLIST_ENTRY CurrentEntry;
- PLIST_ENTRY NextEntry;
- PIPDATAGRAM_HOLE CurrentH;
- PIP_FRAGMENT CurrentF;
+ PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY NextEntry;
+ PIPDATAGRAM_HOLE CurrentH;
+ PIP_FRAGMENT CurrentF;
- TI_DbgPrint(DEBUG_IP, ("Freeing IP datagram reassembly descriptor (0x%X).\n", IPDR));
+ TI_DbgPrint(DEBUG_IP, ("Freeing IP datagram reassembly descriptor (0x%X).\n", IPDR));
- /* Free all descriptors */
- CurrentEntry = IPDR->HoleListHead.Flink;
- while (CurrentEntry != &IPDR->HoleListHead) {
- NextEntry = CurrentEntry->Flink;
- CurrentH = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
- /* Unlink it from the list */
- RemoveEntryList(CurrentEntry);
-
- TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH));
-
- /* And free the hole descriptor */
- PoolFreeBuffer(CurrentH);
-
- CurrentEntry = NextEntry;
- }
+ /* Free all descriptors */
+ CurrentEntry = IPDR->HoleListHead.Flink;
+ while (CurrentEntry != &IPDR->HoleListHead) {
+ NextEntry = CurrentEntry->Flink;
+ CurrentH = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
+ /* Unlink it from the list */
+ RemoveEntryList(CurrentEntry);
- /* Free all fragments */
- CurrentEntry = IPDR->FragmentListHead.Flink;
- while (CurrentEntry != &IPDR->FragmentListHead) {
- NextEntry = CurrentEntry->Flink;
- CurrentF = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
- /* Unlink it from the list */
- RemoveEntryList(CurrentEntry);
+ TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH));
- TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data));
+ /* And free the hole descriptor */
+ ExFreeToNPagedLookasideList(&IPHoleList, CurrentH);
- /* Free the fragment data buffer */
- ExFreePool(CurrentF->Data);
+ CurrentEntry = NextEntry;
+ }
- TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
+ /* Free all fragments */
+ CurrentEntry = IPDR->FragmentListHead.Flink;
+ while (CurrentEntry != &IPDR->FragmentListHead) {
+ NextEntry = CurrentEntry->Flink;
+ CurrentF = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
+ /* Unlink it from the list */
+ RemoveEntryList(CurrentEntry);
- /* And free the fragment descriptor */
- PoolFreeBuffer(CurrentF);
- CurrentEntry = NextEntry;
- }
+ TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data));
- /* Free resources for the header, if it exists */
- if (IPDR->IPv4Header) {
- TI_DbgPrint(DEBUG_IP, ("Freeing IPv4 header data at (0x%X).\n", IPDR->IPv4Header));
- ExFreePool(IPDR->IPv4Header);
- }
+ /* Free the fragment data buffer */
+ ExFreePool(CurrentF->Data);
- TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR));
+ TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
- PoolFreeBuffer(IPDR);
+ /* And free the fragment descriptor */
+ ExFreeToNPagedLookasideList(&IPFragmentList, CurrentF);
+ CurrentEntry = NextEntry;
+ }
+
+ /* Free resources for the header, if it exists */
+ if (IPDR->IPv4Header) {
+ TI_DbgPrint(DEBUG_IP, ("Freeing IPv4 header data at (0x%X).\n", IPDR->IPv4Header));
+ ExFreePool(IPDR->IPv4Header);
+ }
+
+ TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR));
+
+ ExFreeToNPagedLookasideList(&IPDRList, IPDR);
}
VOID RemoveIPDR(
- PIPDATAGRAM_REASSEMBLY IPDR)
+ PIPDATAGRAM_REASSEMBLY IPDR)
/*
* FUNCTION: Removes an IP datagram reassembly structure from the global list
* ARGUMENTS:
* IPDR = Pointer to IP datagram reassembly structure
*/
{
- KIRQL OldIrql;
+ KIRQL OldIrql;
- TI_DbgPrint(DEBUG_IP, ("Removing IPDR at (0x%X).\n", IPDR));
+ TI_DbgPrint(DEBUG_IP, ("Removing IPDR at (0x%X).\n", IPDR));
- KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
- RemoveEntryList(&IPDR->ListEntry);
- KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
+ KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
+ RemoveEntryList(&IPDR->ListEntry);
+ KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
}
PIPDATAGRAM_REASSEMBLY GetReassemblyInfo(
- PIP_PACKET IPPacket)
+ PIP_PACKET IPPacket)
/*
* FUNCTION: Returns a pointer to an IP datagram reassembly structure
* ARGUMENTS:
* identification number
*/
{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PIPDATAGRAM_REASSEMBLY Current;
- PIPv4_HEADER Header = (PIPv4_HEADER)IPPacket->Header;
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PIPDATAGRAM_REASSEMBLY Current;
+ PIPv4_HEADER Header = (PIPv4_HEADER)IPPacket->Header;
- TI_DbgPrint(DEBUG_IP, ("Searching for IPDR for IP packet at (0x%X).\n", IPPacket));
+ TI_DbgPrint(DEBUG_IP, ("Searching for IPDR for IP packet at (0x%X).\n", IPPacket));
- KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
+ KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
- /* FIXME: Assume IPv4 */
+ /* FIXME: Assume IPv4 */
- CurrentEntry = ReassemblyListHead.Flink;
- while (CurrentEntry != &ReassemblyListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
- if (AddrIsEqual(&IPPacket->SrcAddr, &Current->SrcAddr) &&
- (Header->Id == Current->Id) &&
- (Header->Protocol == Current->Protocol) &&
- (AddrIsEqual(&IPPacket->DstAddr, &Current->DstAddr))) {
- KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
+ CurrentEntry = ReassemblyListHead.Flink;
+ while (CurrentEntry != &ReassemblyListHead) {
+ Current = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
+ if (AddrIsEqual(&IPPacket->SrcAddr, &Current->SrcAddr) &&
+ (Header->Id == Current->Id) &&
+ (Header->Protocol == Current->Protocol) &&
+ (AddrIsEqual(&IPPacket->DstAddr, &Current->DstAddr))) {
+ KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
- return Current;
- }
- CurrentEntry = CurrentEntry->Flink;
+ return Current;
}
+ CurrentEntry = CurrentEntry->Flink;
+ }
- KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
+ KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
- return NULL;
+ return NULL;
}
PIP_PACKET ReassembleDatagram(
- PIPDATAGRAM_REASSEMBLY IPDR)
+ PIPDATAGRAM_REASSEMBLY IPDR)
/*
* FUNCTION: Reassembles an IP datagram
* ARGUMENTS:
* Pointer to IP packet, NULL if there was not enough free resources
*/
{
- PIP_PACKET IPPacket;
- PLIST_ENTRY CurrentEntry;
- PIP_FRAGMENT Current;
- PVOID Data;
+ PIP_PACKET IPPacket;
+ PLIST_ENTRY CurrentEntry;
+ PIP_FRAGMENT Current;
+ PVOID Data;
- TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR));
+ TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR));
- IPPacket = PoolAllocateBuffer(sizeof(IP_PACKET));
- if (!IPPacket) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return NULL;
- }
-
- /* FIXME: Assume IPv4 */
-
- IPPacket->Type = IP_ADDRESS_V4;
- IPPacket->RefCount = 1;
- IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize;
- IPPacket->ContigSize = IPPacket->TotalSize;
- IPPacket->HeaderSize = IPDR->HeaderSize;
- IPPacket->Position = IPDR->HeaderSize;
-
- RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS));
- RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
-
- /* Allocate space for full IP datagram */
- IPPacket->Header = ExAllocatePool(NonPagedPool, IPPacket->TotalSize);
- if (!IPPacket->Header) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- PoolFreeBuffer(IPPacket);
- return NULL;
- }
-
- /* Copy the header into the buffer */
- RtlCopyMemory(IPPacket->Header, IPDR->IPv4Header, IPDR->HeaderSize);
-
- Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPDR->HeaderSize);
- IPPacket->Data = Data;
-
- /* Copy data from all fragments into buffer */
- CurrentEntry = IPDR->FragmentListHead.Flink;
- while (CurrentEntry != &IPDR->FragmentListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
+ /* FIXME: Assume IPv4 */
+ IPPacket = IPCreatePacket(IP_ADDRESS_V4);
+ if (!IPPacket)
+ return NULL;
- TI_DbgPrint(DEBUG_IP, ("Copying (%d) bytes of fragment data from (0x%X) to offset (%d).\n",
- Current->Size, Data, Current->Offset));
- /* Copy fragment data to the destination buffer at the correct offset */
- RtlCopyMemory((PVOID)((ULONG_PTR)Data + Current->Offset),
- Current->Data,
- Current->Size);
+ IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize;
+ IPPacket->ContigSize = IPPacket->TotalSize;
+ IPPacket->HeaderSize = IPDR->HeaderSize;
+ IPPacket->Position = IPDR->HeaderSize;
- CurrentEntry = CurrentEntry->Flink;
- }
+ RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS));
+ RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
- return IPPacket;
+ /* Allocate space for full IP datagram */
+ IPPacket->Header = ExAllocatePool(NonPagedPool, IPPacket->TotalSize);
+ if (!IPPacket->Header) {
+ TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ (*IPPacket->Free)(IPPacket);
+ return NULL;
+ }
+
+ /* Copy the header into the buffer */
+ RtlCopyMemory(IPPacket->Header, IPDR->IPv4Header, IPDR->HeaderSize);
+
+ Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPDR->HeaderSize);
+ IPPacket->Data = Data;
+
+ /* Copy data from all fragments into buffer */
+ CurrentEntry = IPDR->FragmentListHead.Flink;
+ while (CurrentEntry != &IPDR->FragmentListHead) {
+ Current = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
+
+ TI_DbgPrint(DEBUG_IP, ("Copying (%d) bytes of fragment data from (0x%X) to offset (%d).\n",
+ Current->Size, Data, Current->Offset));
+ /* Copy fragment data to the destination buffer at the correct offset */
+ RtlCopyMemory(
+ (PVOID)((ULONG_PTR)Data + Current->Offset),
+ Current->Data,
+ Current->Size);
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ return IPPacket;
}
__inline VOID Cleanup(
- PKSPIN_LOCK Lock,
- KIRQL OldIrql,
- PIPDATAGRAM_REASSEMBLY IPDR,
- PVOID Buffer OPTIONAL)
+ PKSPIN_LOCK Lock,
+ KIRQL OldIrql,
+ PIPDATAGRAM_REASSEMBLY IPDR,
+ PVOID Buffer OPTIONAL)
/*
* FUNCTION: Performs cleaning operations on errors
* ARGUMENTS:
* Buffer = Optional pointer to a buffer to free
*/
{
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- KeReleaseSpinLock(Lock, OldIrql);
- RemoveIPDR(IPDR);
- FreeIPDR(IPDR);
- if (Buffer)
- PoolFreeBuffer(Buffer);
+ KeReleaseSpinLock(Lock, OldIrql);
+ RemoveIPDR(IPDR);
+ FreeIPDR(IPDR);
+ if (Buffer)
+ ExFreePool(Buffer);
}
VOID ProcessFragment(
- PIP_INTERFACE IF,
- PIP_PACKET IPPacket,
- PNET_TABLE_ENTRY NTE)
+ PIP_INTERFACE IF,
+ PIP_PACKET IPPacket,
+ PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Processes an IP datagram or fragment
* ARGUMENTS:
* be assembled, passes the datagram on to the IP protocol dispatcher
*/
{
- KIRQL OldIrql;
- PIPDATAGRAM_REASSEMBLY IPDR;
- PLIST_ENTRY CurrentEntry;
- PIPDATAGRAM_HOLE Hole, NewHole;
- USHORT FragFirst;
- USHORT FragLast;
- BOOLEAN MoreFragments;
- PIPv4_HEADER IPv4Header;
- PIP_PACKET Datagram;
- PIP_FRAGMENT Fragment;
-
- /* FIXME: Assume IPv4 */
-
- IPv4Header = (PIPv4_HEADER)IPPacket->Header;
-
- /* Check if we already have an reassembly structure for this datagram */
- IPDR = GetReassemblyInfo(IPPacket);
- if (IPDR) {
- TI_DbgPrint(DEBUG_IP, ("Continueing assembly.\n"));
- /* We have a reassembly structure */
- KeAcquireSpinLock(&IPDR->Lock, &OldIrql);
- CurrentEntry = IPDR->HoleListHead.Flink;
- Hole = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
- } else {
- TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n"));
-
- /* We don't have a reassembly structure, create one */
- IPDR = PoolAllocateBuffer(sizeof(IPDATAGRAM_REASSEMBLY));
- if (!IPDR) {
- /* We don't have the resources to process this packet, discard it */
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return;
- }
-
- /* Create a descriptor spanning from zero to infinity.
- Actually, we use a value slightly greater than the
- maximum number of octets an IP datagram can contain */
- Hole = CreateHoleDescriptor(0, 65536);
- if (!Hole) {
- /* We don't have the resources to process this packet, discard it */
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- PoolFreeBuffer(IPDR);
- return;
- }
- AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr);
- AddrInitIPv4(&IPDR->DstAddr, IPv4Header->DstAddr);
- IPDR->Id = IPv4Header->Id;
- IPDR->Protocol = IPv4Header->Protocol;
- IPDR->IPv4Header = NULL;
- InitializeListHead(&IPDR->FragmentListHead);
- InitializeListHead(&IPDR->HoleListHead);
- InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
- CurrentEntry = IPDR->HoleListHead.Flink;
-
- KeInitializeSpinLock(&IPDR->Lock);
-
- KeAcquireSpinLock(&IPDR->Lock, &OldIrql);
-
- /* Update the reassembly list */
- ExInterlockedInsertTailList(&ReassemblyListHead,
- &IPDR->ListEntry,
- &ReassemblyListLock);
+ KIRQL OldIrql;
+ PIPDATAGRAM_REASSEMBLY IPDR;
+ PLIST_ENTRY CurrentEntry;
+ PIPDATAGRAM_HOLE Hole, NewHole;
+ USHORT FragFirst;
+ USHORT FragLast;
+ BOOLEAN MoreFragments;
+ PIPv4_HEADER IPv4Header;
+ PIP_PACKET Datagram;
+ PIP_FRAGMENT Fragment;
+
+ /* FIXME: Assume IPv4 */
+
+ IPv4Header = (PIPv4_HEADER)IPPacket->Header;
+
+ /* Check if we already have an reassembly structure for this datagram */
+ IPDR = GetReassemblyInfo(IPPacket);
+ if (IPDR) {
+ TI_DbgPrint(DEBUG_IP, ("Continueing assembly.\n"));
+ /* We have a reassembly structure */
+ KeAcquireSpinLock(&IPDR->Lock, &OldIrql);
+ CurrentEntry = IPDR->HoleListHead.Flink;
+ Hole = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
+ } else {
+ TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n"));
+
+ /* We don't have a reassembly structure, create one */
+ IPDR = ExAllocateFromNPagedLookasideList(&IPDRList);
+ if (!IPDR)
+ /* We don't have the resources to process this packet, discard it */
+ return;
+
+ /* Create a descriptor spanning from zero to infinity.
+ Actually, we use a value slightly greater than the
+ maximum number of octets an IP datagram can contain */
+ Hole = CreateHoleDescriptor(0, 65536);
+ if (!Hole) {
+ /* We don't have the resources to process this packet, discard it */
+ ExFreeToNPagedLookasideList(&IPDRList, IPDR);
+ return;
}
+ AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr);
+ AddrInitIPv4(&IPDR->DstAddr, IPv4Header->DstAddr);
+ IPDR->Id = IPv4Header->Id;
+ IPDR->Protocol = IPv4Header->Protocol;
+ IPDR->IPv4Header = NULL;
+ InitializeListHead(&IPDR->FragmentListHead);
+ InitializeListHead(&IPDR->HoleListHead);
+ InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
+ CurrentEntry = IPDR->HoleListHead.Flink;
- FragFirst = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_FRAGOFS_MASK) << 3;
- FragLast = FragFirst + WN2H(IPv4Header->TotalLength);
- MoreFragments = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_MF_MASK) > 0;
-
- for (;;) {
- if (CurrentEntry == &IPDR->HoleListHead)
- /* No more entries */
- break;
-
- TI_DbgPrint(DEBUG_IP, ("Comparing Fragment (%d,%d) to Hole (%d,%d).\n",
- FragFirst, FragLast, Hole->First, Hole->Last));
-
- if ((FragFirst > Hole->Last) || (FragLast < Hole->First)) {
- TI_DbgPrint(MID_TRACE, ("No overlap.\n"));
- /* The fragment does not overlap with the hole, try next
- descriptor in the list */
-
- CurrentEntry = CurrentEntry->Flink;
- if (CurrentEntry != &IPDR->HoleListHead)
- Hole = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
- continue;
- }
-
- /* The fragment overlap with the hole, unlink the descriptor */
- RemoveEntryList(CurrentEntry);
-
- if (FragFirst > Hole->First) {
- NewHole = CreateHoleDescriptor(Hole->First, FragLast - 1);
- if (!NewHole) {
- /* We don't have the resources to process this packet, discard it */
- Cleanup(&IPDR->Lock, OldIrql, IPDR, Hole);
- return;
- }
-
- /* Put the new descriptor in the list */
- InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry);
- }
-
- if ((FragLast < Hole->Last) && (MoreFragments)) {
- /* We can reuse the descriptor for the new hole */
- Hole->First = FragLast + 1;
-
- /* Put the new hole descriptor in the list */
- InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
- } else
- PoolFreeBuffer(Hole);
-
- /* If this is the first fragment, save the IP header */
- if (FragFirst == 0) {
- IPDR->IPv4Header = ExAllocatePool(NonPagedPool, IPPacket->HeaderSize);
- if (!IPDR->IPv4Header) {
- /* We don't have the resources to process this packet, discard it */
- Cleanup(&IPDR->Lock, OldIrql, IPDR, NULL);
- return;
- }
-
- TI_DbgPrint(DEBUG_IP, ("First fragment found. Header buffer is at (0x%X). "
- "Header size is (%d).\n", IPDR->IPv4Header, IPPacket->HeaderSize));
-
- RtlCopyMemory(IPDR->IPv4Header, IPPacket->Header, IPPacket->HeaderSize);
- IPDR->HeaderSize = IPPacket->HeaderSize;
- }
-
- /* Create a buffer, copy the data into it and put it
- in the fragment list */
-
- Fragment = PoolAllocateBuffer(sizeof(IP_FRAGMENT));
- if (!Fragment) {
- /* We don't have the resources to process this packet, discard it */
- Cleanup(&IPDR->Lock, OldIrql, IPDR, NULL);
- return;
- }
-
- TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment));
-
- Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize;
- Fragment->Data = ExAllocatePool(NonPagedPool, Fragment->Size);
- if (!Fragment->Data) {
- /* We don't have the resources to process this packet, discard it */
- Cleanup(&IPDR->Lock, OldIrql, IPDR, Fragment);
- return;
- }
-
- TI_DbgPrint(DEBUG_IP, ("Fragment data buffer allocated at (0x%X) Size (%d).\n",
- Fragment->Data, Fragment->Size));
-
- /* Copy datagram data into fragment buffer */
- CopyPacketToBuffer(Fragment->Data,
- IPPacket->NdisPacket,
- IPPacket->Position,
- Fragment->Size);
- Fragment->Offset = FragFirst;
-
- /* If this is the last fragment, compute and save the datagram data size */
- if (!MoreFragments)
- IPDR->DataSize = FragFirst + Fragment->Size;
-
- /* Put the fragment in the list */
- InsertTailList(&IPDR->FragmentListHead, &Fragment->ListEntry);
- break;
- }
+ KeInitializeSpinLock(&IPDR->Lock);
- TI_DbgPrint(DEBUG_IP, ("Done searching for hole descriptor.\n"));
+ KeAcquireSpinLock(&IPDR->Lock, &OldIrql);
- if (IsListEmpty(&IPDR->HoleListHead)) {
- /* Hole list is empty which means a complete datagram can be assembled.
- Assemble the datagram and pass it to an upper layer protocol */
+ /* Update the reassembly list */
+ ExInterlockedInsertTailList(
+ &ReassemblyListHead,
+ &IPDR->ListEntry,
+ &ReassemblyListLock);
+ }
- TI_DbgPrint(DEBUG_IP, ("Complete datagram received.\n"));
+ FragFirst = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_FRAGOFS_MASK) << 3;
+ FragLast = FragFirst + WN2H(IPv4Header->TotalLength);
+ MoreFragments = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_MF_MASK) > 0;
- Datagram = ReassembleDatagram(IPDR);
- KeReleaseSpinLock(&IPDR->Lock, OldIrql);
+ for (;;) {
+ if (CurrentEntry == &IPDR->HoleListHead)
+ /* No more entries */
+ break;
- RemoveIPDR(IPDR);
- FreeIPDR(IPDR);
+ TI_DbgPrint(DEBUG_IP, ("Comparing Fragment (%d,%d) to Hole (%d,%d).\n",
+ FragFirst, FragLast, Hole->First, Hole->Last));
- if (!Datagram) {
- /* Not enough free resources, discard the packet */
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return;
- }
+ if ((FragFirst > Hole->Last) || (FragLast < Hole->First)) {
+ TI_DbgPrint(MID_TRACE, ("No overlap.\n"));
+ /* The fragment does not overlap with the hole, try next
+ descriptor in the list */
- DISPLAY_IP_PACKET(Datagram);
+ CurrentEntry = CurrentEntry->Flink;
+ if (CurrentEntry != &IPDR->HoleListHead)
+ Hole = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
+ continue;
+ }
+
+ /* The fragment overlap with the hole, unlink the descriptor */
+ RemoveEntryList(CurrentEntry);
+
+ if (FragFirst > Hole->First) {
+ NewHole = CreateHoleDescriptor(Hole->First, FragLast - 1);
+ if (!NewHole) {
+ /* We don't have the resources to process this packet, discard it */
+ Cleanup(&IPDR->Lock, OldIrql, IPDR, Hole);
+ return;
+ }
+
+ /* Put the new descriptor in the list */
+ InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry);
+ }
- /* Give the packet to the protocol dispatcher */
- IPDispatchProtocol(NTE, Datagram);
+ if ((FragLast < Hole->Last) && (MoreFragments)) {
+ /* We can reuse the descriptor for the new hole */
+ Hole->First = FragLast + 1;
- /* We're done with this datagram */
- ExFreePool(Datagram->Header);
- PoolFreeBuffer(Datagram);
+ /* Put the new hole descriptor in the list */
+ InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
} else
- KeReleaseSpinLock(&IPDR->Lock, OldIrql);
+ ExFreeToNPagedLookasideList(&IPHoleList, Hole);
+
+ /* If this is the first fragment, save the IP header */
+ if (FragFirst == 0) {
+ IPDR->IPv4Header = ExAllocatePool(NonPagedPool, IPPacket->HeaderSize);
+ if (!IPDR->IPv4Header) {
+ /* We don't have the resources to process this packet, discard it */
+ Cleanup(&IPDR->Lock, OldIrql, IPDR, NULL);
+ return;
+ }
+
+ TI_DbgPrint(DEBUG_IP, ("First fragment found. Header buffer is at (0x%X). "
+ "Header size is (%d).\n", IPDR->IPv4Header, IPPacket->HeaderSize));
+
+ RtlCopyMemory(IPDR->IPv4Header, IPPacket->Header, IPPacket->HeaderSize);
+ IPDR->HeaderSize = IPPacket->HeaderSize;
+ }
+
+ /* Create a buffer, copy the data into it and put it
+ in the fragment list */
+
+ Fragment = ExAllocateFromNPagedLookasideList(&IPFragmentList);
+ if (!Fragment) {
+ /* We don't have the resources to process this packet, discard it */
+ Cleanup(&IPDR->Lock, OldIrql, IPDR, NULL);
+ return;
+ }
+
+ TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment));
+
+ Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize;
+ Fragment->Data = ExAllocatePool(NonPagedPool, Fragment->Size);
+ if (!Fragment->Data) {
+ /* We don't have the resources to process this packet, discard it */
+ Cleanup(&IPDR->Lock, OldIrql, IPDR, Fragment);
+ return;
+ }
+
+ TI_DbgPrint(DEBUG_IP, ("Fragment data buffer allocated at (0x%X) Size (%d).\n",
+ Fragment->Data, Fragment->Size));
+
+ /* Copy datagram data into fragment buffer */
+ CopyPacketToBuffer(
+ Fragment->Data,
+ IPPacket->NdisPacket,
+ IPPacket->Position,
+ Fragment->Size);
+ Fragment->Offset = FragFirst;
+
+ /* If this is the last fragment, compute and save the datagram data size */
+ if (!MoreFragments)
+ IPDR->DataSize = FragFirst + Fragment->Size;
+
+ /* Put the fragment in the list */
+ InsertTailList(&IPDR->FragmentListHead, &Fragment->ListEntry);
+ break;
+ }
+
+ TI_DbgPrint(DEBUG_IP, ("Done searching for hole descriptor.\n"));
+
+ if (IsListEmpty(&IPDR->HoleListHead)) {
+ /* Hole list is empty which means a complete datagram can be assembled.
+ Assemble the datagram and pass it to an upper layer protocol */
+
+ TI_DbgPrint(DEBUG_IP, ("Complete datagram received.\n"));
+
+ Datagram = ReassembleDatagram(IPDR);
+
+ KeReleaseSpinLock(&IPDR->Lock, OldIrql);
+
+ RemoveIPDR(IPDR);
+ FreeIPDR(IPDR);
+
+ if (!Datagram)
+ /* Not enough free resources, discard the packet */
+ return;
+
+ DISPLAY_IP_PACKET(Datagram);
+
+ /* Give the packet to the protocol dispatcher */
+ IPDispatchProtocol(NTE, Datagram);
+
+ /* We're done with this datagram */
+ ExFreePool(Datagram->Header);
+ TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram));
+ (*Datagram->Free)(Datagram);
+ } else
+ KeReleaseSpinLock(&IPDR->Lock, OldIrql);
}
VOID IPFreeReassemblyList(
- VOID)
+ VOID)
/*
* FUNCTION: Frees all IP datagram reassembly structures in the list
*/
{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PIPDATAGRAM_REASSEMBLY Current;
-
- KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
-
- CurrentEntry = ReassemblyListHead.Flink;
- while (CurrentEntry != &ReassemblyListHead) {
- Current = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
- /* Unlink it from the list */
- RemoveEntryList(CurrentEntry);
-
- /* And free the descriptor */
- FreeIPDR(Current);
-
- CurrentEntry = CurrentEntry->Flink;
- }
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PIPDATAGRAM_REASSEMBLY Current;
+
+ KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
+
+ CurrentEntry = ReassemblyListHead.Flink;
+ while (CurrentEntry != &ReassemblyListHead) {
+ Current = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
+ /* Unlink it from the list */
+ RemoveEntryList(CurrentEntry);
- KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
+ /* And free the descriptor */
+ FreeIPDR(Current);
+
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
}
VOID IPDatagramReassemblyTimeout(
- VOID)
+ VOID)
/*
* FUNCTION: IP datagram reassembly timeout handler
* NOTES:
* This routine is called by IPTimeout to free any resources used
- * to hold IP fragments that are being reassembled to form a
- * complete IP datagram
+ * to hold IP fragments that have taken too long to reassemble
*/
{
}
VOID IPv4Receive(
- PVOID Context,
- PIP_PACKET IPPacket)
+ PVOID Context,
+ PIP_PACKET IPPacket)
/*
* FUNCTION: Receives an IPv4 datagram (or fragment)
* ARGUMENTS:
* IPPacket = Pointer to IP packet
*/
{
-// PNEIGHBOR_CACHE_ENTRY NCE;
- PNET_TABLE_ENTRY NTE;
- UINT AddressType;
+//PNEIGHBOR_CACHE_ENTRY NCE;
+ PNET_TABLE_ENTRY NTE;
+ UINT AddressType;
- TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
+ TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
- IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
+ IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
- if (IPPacket->HeaderSize > IPv4_MAX_HEADER_SIZE) {
- TI_DbgPrint(MIN_TRACE, ("Datagram received with incorrect header size (%d).\n",
- IPPacket->HeaderSize));
- /* Discard packet */
- return;
- }
+ if (IPPacket->HeaderSize > IPv4_MAX_HEADER_SIZE) {
+ TI_DbgPrint(MIN_TRACE, ("Datagram received with incorrect header size (%d).\n",
+ IPPacket->HeaderSize));
+ /* Discard packet */
+ return;
+ }
- /* Checksum IPv4 header */
- if (!CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
- TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n",
- WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
- /* Discard packet */
- return;
- }
+ /* Checksum IPv4 header */
+ if (!CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
+ TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n",
+ WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
+ /* Discard packet */
+ return;
+ }
// TI_DbgPrint(DEBUG_IP, ("TotalSize (datalink) is (%d).\n", IPPacket->TotalSize));
- IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength);
+ IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength);
// TI_DbgPrint(DEBUG_IP, ("TotalSize (IPv4) is (%d).\n", IPPacket->TotalSize));
AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
- IPPacket->Position = IPPacket->HeaderSize;
- IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize);
+ IPPacket->Position = IPPacket->HeaderSize;
+ IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize);
- /* FIXME: Possibly forward packets with multicast addresses */
+ /* FIXME: Possibly forward packets with multicast addresses */
- /* FIXME: Should we allow packets to be received on the wrong interface? */
+ /* FIXME: Should we allow packets to be received on the wrong interface? */
#if 0
- NTE = IPLocateNTE(&IPPacket->DstAddr, &AddressType);
+ NTE = IPLocateNTE(&IPPacket->DstAddr, &AddressType);
#else
- NTE = IPLocateNTEOnInterface((PIP_INTERFACE)Context, &IPPacket->DstAddr, &AddressType);
+ NTE = IPLocateNTEOnInterface((PIP_INTERFACE)Context, &IPPacket->DstAddr, &AddressType);
#endif
- if (NTE) {
- /* This packet is destined for us */
- ProcessFragment((PIP_INTERFACE)Context, IPPacket, NTE);
- /* Done with this NTE */
- DereferenceObject(NTE);
- } else {
- /* This packet is not destined for us. If we are a router,
- try to find a route and forward the packet */
+ if (NTE) {
+ /* This packet is destined for us */
+ ProcessFragment((PIP_INTERFACE)Context, IPPacket, NTE);
+
+ /* Done with this NTE */
+ DereferenceObject(NTE);
+ } else {
+ /* This packet is not destined for us. If we are a router,
+ try to find a route and forward the packet */
- /* FIXME: Check if acting as a router */
+ /* FIXME: Check if acting as a router */
#if 0
- NCE = RouteFindRouter(&IPPacket->DstAddr, NULL);
- if (NCE) {
- /* FIXME: Possibly fragment datagram */
- /* Forward the packet */
- IPSendFragment(IPPacket, NCE);
- } else {
- TI_DbgPrint(MIN_TRACE, ("No route to destination (0x%X).\n",
- IPPacket->DstAddr.Address.IPv4Address));
-
- /* FIXME: Send ICMP error code */
- }
-#endif
+ NCE = RouteFindRouter(&IPPacket->DstAddr, NULL);
+ if (NCE) {
+ /* FIXME: Possibly fragment datagram */
+ /* Forward the packet */
+ IPSendFragment(IPPacket, NCE);
+ } else {
+ TI_DbgPrint(MIN_TRACE, ("No route to destination (0x%X).\n",
+ IPPacket->DstAddr.Address.IPv4Address));
+
+ /* FIXME: Send ICMP error code */
}
+#endif
+ }
}
VOID IPReceive(
- PVOID Context,
- PIP_PACKET IPPacket)
+ PVOID Context,
+ PIP_PACKET IPPacket)
/*
* FUNCTION: Receives an IP datagram (or fragment)
* ARGUMENTS:
* IPPacket = Pointer to IP packet
*/
{
- UINT Version;
-
- /* Check that IP header has a supported version */
- Version = (((PIPv4_HEADER)IPPacket->Header)->VerIHL >> 4);
-
- switch (Version) {
- case 4:
- IPPacket->Type = IP_ADDRESS_V4;
- IPv4Receive(Context, IPPacket);
- break;
- case 6:
- IPPacket->Type = IP_ADDRESS_V6;
- TI_DbgPrint(MAX_TRACE, ("Datagram of type IPv6 discarded.\n"));
- return;
- default:
- TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version));
- return;
- }
+ UINT Version;
+
+ /* Check that IP header has a supported version */
+ Version = (((PIPv4_HEADER)IPPacket->Header)->VerIHL >> 4);
+
+ switch (Version) {
+ case 4:
+ IPPacket->Type = IP_ADDRESS_V4;
+ IPv4Receive(Context, IPPacket);
+ break;
+ case 6:
+ IPPacket->Type = IP_ADDRESS_V6;
+ TI_DbgPrint(MAX_TRACE, ("Datagram of type IPv6 discarded.\n"));
+ return;
+ default:
+ TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version));
+ return;
+ }
}
/* EOF */
PROUTE_CACHE_NODE ExternalRCN;
PROUTE_CACHE_NODE RouteCache;
KSPIN_LOCK RouteCacheLock;
+NPAGED_LOOKASIDE_LIST IPRCNList;
#if DBG
#endif
+VOID FreeRCN(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an route cache node object
+ * ARGUMENTS:
+ * Object = Pointer to an route cache node structure
+ */
+{
+ ExFreeToNPagedLookasideList(&IPRCNList, Object);
+}
+
+
VOID RemoveAboveExternal(VOID)
/*
* FUNCTION: Removes the parent node of the selected external node from the route cache tree
TI_DbgPrint(DEBUG_RCACHE, ("Called.\n"));
- RCN = PoolAllocateBuffer(sizeof(ROUTE_CACHE_NODE));
+ RCN = ExAllocateFromNPagedLookasideList(&IPRCNList);
if (!RCN) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ RCN->Free = FreeRCN;
+
if (ExternalRCN->Left)
/* Register RCN as a child with it's parent */
*(PROUTE_CACHE_NODE*)ExternalRCN->Left = RCN;
{
TI_DbgPrint(DEBUG_RCACHE, ("Called.\n"));
+ ExInitializeNPagedLookasideList(
+ &IPRCNList, /* Lookaside list */
+ NULL, /* Allocate routine */
+ NULL, /* Free routine */
+ 0, /* Flags */
+ sizeof(ROUTE_CACHE_NODE), /* Size of each entry */
+ TAG('I','P','R','C'), /* Tag */
+ 0); /* Depth */
+
/* Initialize the pseudo external route cache node */
- ExternalRCN = PoolAllocateBuffer(sizeof(ROUTE_CACHE_NODE));
+ ExternalRCN = ExAllocateFromNPagedLookasideList(&IPRCNList);
if (!ExternalRCN) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
+ INIT_TAG(ExternalRCN, TAG('R','C','N',' '));
+
+ ExternalRCN->Free = FreeRCN;
ExternalRCN->Parent = NULL;
ExternalRCN->Left = NULL;
ExternalRCN->Right = NULL;
/* Clear route cache */
RemoveSubtree(RouteCache);
- PoolFreeBuffer(ExternalRCN);
+ FreeRCN(ExternalRCN);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
+ ExDeleteNPagedLookasideList(&IPRCNList);
+
return STATUS_SUCCESS;
}
/* Initialize the newly created internal node */
+ INIT_TAG(RCN, TAG('R','C','N',' '));
+
/* Reference once for beeing alive */
RCN->RefCount = 1;
RCN->State = RCN_STATE_PERMANENT;
KSPIN_LOCK FIBLock;
+VOID FreeFIB(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an forward information base object
+ * ARGUMENTS:
+ * Object = Pointer to an forward information base structure
+ */
+{
+ ExFreePool(Object);
+}
+
+
VOID DestroyFIBE(
PFIB_ENTRY FIBE)
/*
#endif
/* And free the FIB entry */
- PoolFreeBuffer(FIBE);
+ FreeFIB(FIBE);
}
TI_DbgPrint(DEBUG_ROUTER, ("NetworkAddress (%s) Netmask (%s) NTE (%s) Router (%s).\n",
A2S(NetworkAddress), A2S(Netmask), A2S(NTE->Address), A2S(Router->Address)));
- FIBE = PoolAllocateBuffer(sizeof(FIB_ENTRY));
+ FIBE = ExAllocatePool(NonPagedPool, sizeof(FIB_ENTRY));
if (!FIBE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
+ FIBE->Free = FreeFIB;
FIBE->NetworkAddress = NetworkAddress;
FIBE->Netmask = Netmask;
FIBE->NTE = NTE;
PFIB_ENTRY FIBE;
pNetworkAddress = AddrBuildIPv4(NetworkAddress);
- if (!NetworkAddress) {
+ if (!pNetworkAddress) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
pNetmask = AddrBuildIPv4(Netmask);
- if (!Netmask) {
+ if (!pNetmask) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
DereferenceObject(pNetworkAddress);
return NULL;
}
pRouterAddress = AddrBuildIPv4(RouterAddress);
- if (!RouterAddress) {
+ if (!pRouterAddress) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
DereferenceObject(pNetworkAddress);
DereferenceObject(pNetmask);
if (!FIBE) {
/* Not enough free resources */
NBRemoveNeighbor(NCE);
- PoolFreeBuffer(pNetworkAddress);
- PoolFreeBuffer(pNetmask);
- PoolFreeBuffer(pRouterAddress);
+ DereferenceObject(pNetworkAddress);
+ DereferenceObject(pNetmask);
+ DereferenceObject(pRouterAddress);
+
+ (pNetworkAddress->Free)(pNetworkAddress);
+ (pNetmask->Free)(pNetmask);
+ (pRouterAddress->Free)(pRouterAddress);
}
return FIBE;
TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X) PathMTU (%d).\n",
IPPacket, NCE, PathMTU));
- IFC = PoolAllocateBuffer(sizeof(IPFRAGMENT_CONTEXT));
+ IFC = ExAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
if (!IFC)
return STATUS_INSUFFICIENT_RESOURCES;
it for all fragments */
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
if (!IFC->Header) {
- PoolFreeBuffer(IFC);
+ ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(Data);
- PoolFreeBuffer(IFC);
+ ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(IFC->NdisPacket);
ExFreePool(Data);
- PoolFreeBuffer(IFC);
+ ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* There are no more fragments to transmit, so call completion handler */
NdisPacket = IFC->Datagram;
FreeNdisPacket(IFC->NdisPacket);
- PoolFreeBuffer(IFC);
+ ExFreePool(IFC);
(*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
}
}
#endif /* DBG */
+
+VOID IPAddressFree(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an IP_ADDRESS object
+ * ARGUMENTS:
+ * Object = Pointer to an IP address structure
+ * RETURNS:
+ * Nothing
+ */
+{
+ ExFreePool(Object);
+}
+
+
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address)
/*
*Port = ValidAddr->sin_port;
- if (*Cache) {
+ if ((Cache) && (*Cache)) {
if (((*Cache)->Type == IP_ADDRESS_V4) &&
((*Cache)->Address.IPv4Address == ValidAddr->in_addr)) {
*Address = *Cache;
}
}
- IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
+ IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
if (IPAddress) {
AddrInitIPv4(IPAddress, ValidAddr->in_addr);
*Address = IPAddress;
/* Update address cache */
- *Cache = IPAddress;
- ReferenceObject(*Cache);
+ if (Cache) {
+ *Cache = IPAddress;
+ ReferenceObject(*Cache);
+ }
return STATUS_SUCCESS;
} else
return STATUS_INSUFFICIENT_RESOURCES;
}
+/*
+ * FUNCTION: Extract IP address from TDI address structure
+ * ARGUMENTS:
+ * TdiAddress = Pointer to transport address list to extract from
+ * Address = Address of a pointer to where an IP address is stored
+ * Port = Pointer to where port number is stored
+ * RETURNS:
+ * Status of operation
+ */
+NTSTATUS AddrBuildAddress(
+ PTA_ADDRESS TdiAddress,
+ PIP_ADDRESS *Address,
+ PUSHORT Port)
+{
+ PTDI_ADDRESS_IP ValidAddr;
+ PIP_ADDRESS IPAddress;
+
+ if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP)
+ return STATUS_INVALID_ADDRESS;
+
+ if (TdiAddress->AddressLength >= TDI_ADDRESS_LENGTH_IP)
+ return STATUS_INVALID_ADDRESS;
+
+ ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address;
+
+ IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
+ if (!IPAddress)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ AddrInitIPv4(IPAddress, ValidAddr->in_addr);
+ *Address = IPAddress;
+ *Port = ValidAddr->sin_port;
+
+ return STATUS_SUCCESS;
+}
+
+
/*
* FUNCTION: Returns wether two addresses are equal
* ARGUMENTS:
{
PIP_ADDRESS IPAddress;
- IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
+ IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
if (IPAddress) {
IPAddress->RefCount = 1;
IPAddress->Type = IP_ADDRESS_V4;
IPAddress->Address.IPv4Address = Address;
+ IPAddress->Free = IPAddressFree;
}
return IPAddress;
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 01/08-2000 Created
+ * TODO: Validate device object in all dispatch routines
*/
#include <tcpip.h>
#include <dispatch.h>
NTSTATUS DispTdiAccept(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_ACCEPT handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
-
- return STATUS_NOT_IMPLEMENTED;
+ PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
+ PTRANSPORT_CONTEXT TranContext;
+ PIO_STACK_LOCATION IrpSp;
+ PCONNECTION_ENDPOINT Connection;
+ PFILE_OBJECT FileObject;
+ PADDRESS_FILE AddrFile;
+ NTSTATUS Status;
+
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Get associated connection endpoint file object. Quit if none exists */
+
+ TranContext = IrpSp->FileObject->FsContext;
+ if (!TranContext) {
+ TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+ if (!Connection) {
+ TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (Connection->AddressFile) {
+ TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
+
+ Status = ObReferenceObjectByHandle(
+ Parameters->AddressHandle,
+ 0,
+ IoFileObjectType,
+ KernelMode,
+ (PVOID*)&FileObject,
+ NULL);
+ if (!NT_SUCCESS(Status)) {
+ TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X).\n",
+ Parameters->AddressHandle));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
+ ObDereferenceObject(FileObject);
+ TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
+ FileObject->FsContext2));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Get associated address file object. Quit if none exists */
+
+ TranContext = FileObject->FsContext;
+ if (!TranContext) {
+ ObDereferenceObject(FileObject);
+ TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
+ if (!AddrFile) {
+ ObDereferenceObject(FileObject);
+ TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* The connection endpoint references the address file object */
+ ReferenceObject(AddrFile);
+ Connection->AddressFile = AddrFile;
+
+ /* Add connection endpoint to connection list on the address file */
+ ExInterlockedInsertTailList(
+ &AddrFile->Connections,
+ &Connection->AddrFileEntry,
+ &AddrFile->Lock);
+
+ /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
+ ObDereferenceObject(FileObject);
+
+ return STATUS_SUCCESS;
}
NTSTATUS DispTdiConnect(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_CONNECT handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ PCONNECTION_ENDPOINT Connection;
+ PTDI_REQUEST_KERNEL Parameters;
+ PTRANSPORT_CONTEXT TranContext;
+ PIO_STACK_LOCATION IrpSp;
+ TDI_REQUEST Request;
+ NTSTATUS Status;
- return STATUS_NOT_IMPLEMENTED;
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Get associated connection endpoint file object. Quit if none exists */
+
+ TranContext = IrpSp->FileObject->FsContext;
+ if (!TranContext) {
+ TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+ return STATUS_INVALID_CONNECTION;
+ }
+
+ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+ if (!Connection) {
+ TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
+ return STATUS_INVALID_CONNECTION;
+ }
+
+ Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
+
+ /* Initialize a connect request */
+ Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
+ Request.RequestNotifyObject = DispDataRequestComplete;
+ Request.RequestContext = Irp;
+
+ Status = TCPConnect(
+ &Request,
+ Parameters->RequestConnectionInformation,
+ Parameters->ReturnConnectionInformation);
+
+ return Status;
}
NTSTATUS DispTdiDisassociateAddress(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_DISASSOCIATE_ADDRESS handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ PCONNECTION_ENDPOINT Connection;
+ PTRANSPORT_CONTEXT TranContext;
+ PIO_STACK_LOCATION IrpSp;
+ KIRQL OldIrql;
- return STATUS_NOT_IMPLEMENTED;
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Get associated connection endpoint file object. Quit if none exists */
+
+ TranContext = IrpSp->FileObject->FsContext;
+ if (!TranContext) {
+ TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+ if (!Connection) {
+ TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (!Connection->AddressFile) {
+ TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+ RemoveEntryList(&Connection->AddrFileEntry);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+ /* Remove the reference put on the address file object */
+ DereferenceObject(Connection->AddressFile);
+
+ return STATUS_SUCCESS;
}
NTSTATUS DispTdiDisconnect(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_DISCONNECT handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS DispTdiListen(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_LISTEN handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS DispTdiQueryInformation(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
/*
* FUNCTION: TDI_QUERY_INFORMATION handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS DispTdiReceive(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_RECEIVE handler
* ARGUMENTS:
* Status of operation
*/
{
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
* Status of operation
*/
{
- PIO_STACK_LOCATION IrpSp;
- PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo;
- PTRANSPORT_CONTEXT TranContext;
- TDI_REQUEST Request;
- NTSTATUS Status;
- ULONG BytesReceived;
-
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
-
- TranContext = IrpSp->FileObject->FsContext;
- /* Initialize a receive request */
- Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
- Request.RequestNotifyObject = DispDataRequestComplete;
- Request.RequestContext = Irp;
- Status = DispPrepareIrpForCancel(IrpSp->FileObject->FsContext, Irp, (PDRIVER_CANCEL)DispCancelRequest);
- if (NT_SUCCESS(Status)) {
- Status = UDPReceiveDatagram(&Request,
- DgramInfo->ReceiveDatagramInformation,
- (PNDIS_BUFFER)Irp->MdlAddress,
- DgramInfo->ReceiveLength,
- DgramInfo->ReceiveFlags,
- DgramInfo->ReturnDatagramInformation,
- &BytesReceived);
- if (Status != STATUS_PENDING) {
- DispDataRequestComplete(Irp, Status, BytesReceived);
- /* Return STATUS_PENDING because DispPrepareIrpForCancel marks Irp as pending */
- Status = STATUS_PENDING;
- }
+ PIO_STACK_LOCATION IrpSp;
+ PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo;
+ PTRANSPORT_CONTEXT TranContext;
+ TDI_REQUEST Request;
+ NTSTATUS Status;
+ ULONG BytesReceived;
+
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
+
+ TranContext = IrpSp->FileObject->FsContext;
+ /* Initialize a receive request */
+ Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
+ Request.RequestNotifyObject = DispDataRequestComplete;
+ Request.RequestContext = Irp;
+ Status = DispPrepareIrpForCancel(
+ IrpSp->FileObject->FsContext,
+ Irp,
+ (PDRIVER_CANCEL)DispCancelRequest);
+ if (NT_SUCCESS(Status)) {
+ Status = UDPReceiveDatagram(
+ &Request,
+ DgramInfo->ReceiveDatagramInformation,
+ (PNDIS_BUFFER)Irp->MdlAddress,
+ DgramInfo->ReceiveLength,
+ DgramInfo->ReceiveFlags,
+ DgramInfo->ReturnDatagramInformation,
+ &BytesReceived);
+ if (Status != STATUS_PENDING) {
+ DispDataRequestComplete(Irp, Status, BytesReceived);
+ /* Return STATUS_PENDING because DispPrepareIrpForCancel marks
+ the Irp as pending */
+ Status = STATUS_PENDING;
}
+ }
- TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+ TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
- return Status;
+ return Status;
}
NTSTATUS DispTdiSetEventHandler(
- PIRP Irp)
+ PIRP Irp)
/*
* FUNCTION: TDI_SET_EVENT_HANDER handler
* ARGUMENTS:
* Status of operation
*/
{
- PTDI_REQUEST_KERNEL_SET_EVENT Parameters;
- PTRANSPORT_CONTEXT TranContext;
- PIO_STACK_LOCATION IrpSp;
- PADDRESS_FILE AddrFile;
- NTSTATUS Status;
- KIRQL OldIrql;
-
- TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- /* Get associated address file object. Quit if none exists */
- TranContext = IrpSp->FileObject->FsContext;
- if (!TranContext) {
- TI_DbgPrint(MIN_TRACE, ("Bad transport context.\n"));
- return STATUS_INVALID_PARAMETER;
+ PTDI_REQUEST_KERNEL_SET_EVENT Parameters;
+ PTRANSPORT_CONTEXT TranContext;
+ PIO_STACK_LOCATION IrpSp;
+ PADDRESS_FILE AddrFile;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Get associated address file object. Quit if none exists */
+
+ TranContext = IrpSp->FileObject->FsContext;
+ if (!TranContext) {
+ TI_DbgPrint(MIN_TRACE, ("Bad transport context.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
+ if (!AddrFile) {
+ TI_DbgPrint(MIN_TRACE, ("No address file object.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
+ Status = STATUS_SUCCESS;
+
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ /* Set the event handler. if an event handler is associated with
+ a specific event, it's flag (RegisteredXxxHandler) is TRUE.
+ If an event handler is not used it's flag is FALSE */
+ switch (Parameters->EventType) {
+ case TDI_EVENT_CONNECT:
+ if (!Parameters->EventHandler) {
+ AddrFile->ConnectHandlerContext = NULL;
+ AddrFile->RegisteredConnectHandler = FALSE;
+ } else {
+ AddrFile->ConnectHandler =
+ (PTDI_IND_CONNECT)Parameters->EventHandler;
+ AddrFile->ConnectHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredConnectHandler = TRUE;
}
-
- AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
- if (!AddrFile) {
- TI_DbgPrint(MIN_TRACE, ("No address file object.\n"));
- return STATUS_INVALID_PARAMETER;
+ break;
+
+ case TDI_EVENT_DISCONNECT:
+ if (!Parameters->EventHandler) {
+ AddrFile->DisconnectHandlerContext = NULL;
+ AddrFile->RegisteredDisconnectHandler = FALSE;
+ } else {
+ AddrFile->DisconnectHandler =
+ (PTDI_IND_DISCONNECT)Parameters->EventHandler;
+ AddrFile->DisconnectHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredDisconnectHandler = TRUE;
}
-
- Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
- Status = STATUS_SUCCESS;
-
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
- /* Set the event handler. if an event handler is associated with
- a specific event, it's flag (RegisteredXxxHandler) is TRUE.
- If an event handler is not used it's flag is FALSE */
- switch (Parameters->EventType) {
- case TDI_EVENT_CONNECT:
- if (!Parameters->EventHandler) {
-// AddrFile->ConnectionHandler =
-// (PTDI_IND_CONNECT)TdiDefaultConnectHandler;
- AddrFile->ConnectionHandlerContext = NULL;
- AddrFile->RegisteredConnectionHandler = FALSE;
- } else {
- AddrFile->ConnectionHandler =
- (PTDI_IND_CONNECT)Parameters->EventHandler;
- AddrFile->ConnectionHandlerContext = Parameters->EventContext;
- AddrFile->RegisteredConnectionHandler = TRUE;
- }
- break;
-
- case TDI_EVENT_DISCONNECT:
- if (!Parameters->EventHandler) {
-// AddrFile->DisconnectHandler =
-// (PTDI_IND_DISCONNECT)TdiDefaultDisconnectHandler;
- AddrFile->DisconnectHandlerContext = NULL;
- AddrFile->RegisteredDisconnectHandler = FALSE;
- } else {
- AddrFile->DisconnectHandler =
- (PTDI_IND_DISCONNECT)Parameters->EventHandler;
- AddrFile->DisconnectHandlerContext = Parameters->EventContext;
- AddrFile->RegisteredDisconnectHandler = TRUE;
- }
- break;
-
- case TDI_EVENT_RECEIVE:
- if (Parameters->EventHandler == NULL) {
-// AddrFile->ReceiveHandler =
-// (PTDI_IND_RECEIVE)TdiDefaultReceiveHandler;
- AddrFile->ReceiveHandlerContext = NULL;
- AddrFile->RegisteredReceiveHandler = FALSE;
- } else {
- AddrFile->ReceiveHandler =
- (PTDI_IND_RECEIVE)Parameters->EventHandler;
- AddrFile->ReceiveHandlerContext = Parameters->EventContext;
- AddrFile->RegisteredReceiveHandler = TRUE;
- }
- break;
-
- case TDI_EVENT_RECEIVE_EXPEDITED:
- if (Parameters->EventHandler == NULL) {
-// AddrFile->ExpeditedReceiveHandler =
-// (PTDI_IND_RECEIVE_EXPEDITED)TdiDefaultRcvExpeditedHandler;
- AddrFile->ExpeditedReceiveHandlerContext = NULL;
- AddrFile->RegisteredExpeditedReceiveHandler = FALSE;
- } else {
- AddrFile->ExpeditedReceiveHandler =
- (PTDI_IND_RECEIVE_EXPEDITED)Parameters->EventHandler;
- AddrFile->ExpeditedReceiveHandlerContext = Parameters->EventContext;
- AddrFile->RegisteredExpeditedReceiveHandler = TRUE;
- }
- break;
-
- case TDI_EVENT_RECEIVE_DATAGRAM:
- if (Parameters->EventHandler == NULL) {
-// AddrFile->ReceiveDatagramHandler =
-// (PTDI_IND_RECEIVE_DATAGRAM)TdiDefaultRcvDatagramHandler;
- AddrFile->ReceiveDatagramHandlerContext = NULL;
- AddrFile->RegisteredReceiveDatagramHandler = FALSE;
- } else {
- AddrFile->ReceiveDatagramHandler =
- (PTDI_IND_RECEIVE_DATAGRAM)Parameters->EventHandler;
- AddrFile->ReceiveDatagramHandlerContext = Parameters->EventContext;
- AddrFile->RegisteredReceiveDatagramHandler = TRUE;
- }
- break;
+ break;
case TDI_EVENT_ERROR:
- if (Parameters->EventHandler == NULL) {
-// AddrFile->ErrorHandler =
-// (PTDI_IND_ERROR)TdiDefaultErrorHandler;
- AddrFile->ErrorHandlerContext = NULL;
- AddrFile->RegisteredErrorHandler = FALSE;
- } else {
- AddrFile->ErrorHandler =
- (PTDI_IND_ERROR)Parameters->EventHandler;
- AddrFile->ErrorHandlerContext = Parameters->EventContext;
- AddrFile->RegisteredErrorHandler = TRUE;
- }
- break;
-
- default:
- Status = STATUS_INVALID_PARAMETER;
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ErrorHandlerContext = NULL;
+ AddrFile->RegisteredErrorHandler = FALSE;
+ } else {
+ AddrFile->ErrorHandler =
+ (PTDI_IND_ERROR)Parameters->EventHandler;
+ AddrFile->ErrorHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredErrorHandler = TRUE;
+ }
+ break;
+
+ case TDI_EVENT_RECEIVE:
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ReceiveHandlerContext = NULL;
+ AddrFile->RegisteredReceiveHandler = FALSE;
+ } else {
+ AddrFile->ReceiveHandler =
+ (PTDI_IND_RECEIVE)Parameters->EventHandler;
+ AddrFile->ReceiveHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredReceiveHandler = TRUE;
+ }
+ break;
+
+ case TDI_EVENT_RECEIVE_DATAGRAM:
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ReceiveDatagramHandlerContext = NULL;
+ AddrFile->RegisteredReceiveDatagramHandler = FALSE;
+ } else {
+ AddrFile->ReceiveDatagramHandler =
+ (PTDI_IND_RECEIVE_DATAGRAM)Parameters->EventHandler;
+ AddrFile->ReceiveDatagramHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredReceiveDatagramHandler = TRUE;
+ }
+ break;
+
+ case TDI_EVENT_RECEIVE_EXPEDITED:
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ExpeditedReceiveHandlerContext = NULL;
+ AddrFile->RegisteredExpeditedReceiveHandler = FALSE;
+ } else {
+ AddrFile->ExpeditedReceiveHandler =
+ (PTDI_IND_RECEIVE_EXPEDITED)Parameters->EventHandler;
+ AddrFile->ExpeditedReceiveHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredExpeditedReceiveHandler = TRUE;
+ }
+ break;
+
+ case TDI_EVENT_CHAINED_RECEIVE:
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ChainedReceiveHandlerContext = NULL;
+ AddrFile->RegisteredChainedReceiveHandler = FALSE;
+ } else {
+ AddrFile->ChainedReceiveHandler =
+ (PTDI_IND_CHAINED_RECEIVE)Parameters->EventHandler;
+ AddrFile->ChainedReceiveHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredChainedReceiveHandler = TRUE;
}
+ break;
+
+ case TDI_EVENT_CHAINED_RECEIVE_DATAGRAM:
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ChainedReceiveDatagramHandlerContext = NULL;
+ AddrFile->RegisteredChainedReceiveDatagramHandler = FALSE;
+ } else {
+ AddrFile->ChainedReceiveDatagramHandler =
+ (PTDI_IND_CHAINED_RECEIVE_DATAGRAM)Parameters->EventHandler;
+ AddrFile->ChainedReceiveDatagramHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredChainedReceiveDatagramHandler = TRUE;
+ }
+ break;
+
+ case TDI_EVENT_CHAINED_RECEIVE_EXPEDITED:
+ if (Parameters->EventHandler == NULL) {
+ AddrFile->ChainedReceiveExpeditedHandlerContext = NULL;
+ AddrFile->RegisteredChainedReceiveExpeditedHandler = FALSE;
+ } else {
+ AddrFile->ChainedReceiveExpeditedHandler =
+ (PTDI_IND_CHAINED_RECEIVE_EXPEDITED)Parameters->EventHandler;
+ AddrFile->ChainedReceiveExpeditedHandlerContext = Parameters->EventContext;
+ AddrFile->RegisteredChainedReceiveExpeditedHandler = TRUE;
+ }
+ break;
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ default:
+ TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n",
+ Parameters->EventType));
- return Status;
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ return Status;
}
#include <address.h>
#include <pool.h>
#include <rawip.h>
+#include <tcp.h>
#include <udp.h>
#include <ip.h>
#include <fileobjs.h>
+/* List of all address file objects managed by this driver */
LIST_ENTRY AddressFileListHead;
KSPIN_LOCK AddressFileListLock;
+/* List of all connection endpoint file objects managed by this driver */
+LIST_ENTRY ConnectionEndpointListHead;
+KSPIN_LOCK ConnectionEndpointListLock;
+
+VOID AddrFileFree(
+ PVOID Object)
+/*
+ * FUNCTION: Frees an address file object
+ * ARGUMENTS:
+ * Object = Pointer to address file object to free
+ */
+{
+ ExFreePool(Object);
+}
+
+
+VOID DeleteAddress(
+ PADDRESS_FILE AddrFile)
/*
* FUNCTION: Deletes an address file object
* ARGUMENTS:
* AddrFile = Pointer to address file object to delete
*/
-VOID DeleteAddress(
- PADDRESS_FILE AddrFile)
{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PLIST_ENTRY NextEntry;
- PDATAGRAM_SEND_REQUEST SendRequest;
- PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY NextEntry;
+ PDATAGRAM_SEND_REQUEST SendRequest;
+ PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
- TI_DbgPrint(MID_TRACE, ("Called.\n"));
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
- /* Remove address file from the global list */
- KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
- RemoveEntryList(&AddrFile->ListEntry);
- KeReleaseSpinLock(&AddressFileListLock, OldIrql);
+ /* Remove address file from the global list */
+ KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
+ RemoveEntryList(&AddrFile->ListEntry);
+ KeReleaseSpinLock(&AddressFileListLock, OldIrql);
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- /* FIXME: Kill TCP connections on this address file object */
+ /* FIXME: Kill TCP connections on this address file object */
- /* Return pending requests with error */
+ /* Return pending requests with error */
- TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
+ TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
- /* Go through pending receive request list and cancel them all */
- CurrentEntry = AddrFile->ReceiveQueue.Flink;
- while (CurrentEntry != &AddrFile->ReceiveQueue) {
- NextEntry = CurrentEntry->Flink;
- ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
- /* Abort the request and free its resources */
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
- PoolFreeBuffer(ReceiveRequest);
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- CurrentEntry = NextEntry;
- }
-
- TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
-
- /* Go through pending send request list and cancel them all */
- CurrentEntry = AddrFile->TransmitQueue.Flink;
- while (CurrentEntry != &AddrFile->TransmitQueue) {
- NextEntry = CurrentEntry->Flink;
- SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
- /* Abort the request and free its resources */
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- (*SendRequest->Complete)(SendRequest->Context, STATUS_ADDRESS_CLOSED, 0);
- PoolFreeBuffer(SendRequest);
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- CurrentEntry = NextEntry;
- }
+ /* Go through pending receive request list and cancel them all */
+ CurrentEntry = AddrFile->ReceiveQueue.Flink;
+ while (CurrentEntry != &AddrFile->ReceiveQueue) {
+ NextEntry = CurrentEntry->Flink;
+ ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
+ /* Abort the request and free its resources */
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
+ ExFreePool(ReceiveRequest);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ CurrentEntry = NextEntry;
+ }
+
+ TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
+ /* Go through pending send request list and cancel them all */
+ CurrentEntry = AddrFile->TransmitQueue.Flink;
+ while (CurrentEntry != &AddrFile->TransmitQueue) {
+ NextEntry = CurrentEntry->Flink;
+ SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+ /* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ (*SendRequest->Complete)(SendRequest->Context, STATUS_ADDRESS_CLOSED, 0);
+ ExFreePool(SendRequest);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ CurrentEntry = NextEntry;
+ }
+
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ /* Dereference address entry */
+ DereferenceObject(AddrFile->ADE);
+
+ /* Dereference address cache */
+ if (AddrFile->AddrCache)
+ DereferenceObject(AddrFile->AddrCache);
+
+#ifdef DBG
+ /* Remove reference provided at creation time */
+ AddrFile->RefCount--;
+
+ if (AddrFile->RefCount != 0)
+ TI_DbgPrint(DEBUG_REFCOUNT, ("AddrFile->RefCount is (%d) (should be 0).\n", AddrFile->RefCount));
+#endif
+
+ (*AddrFile->Free)(AddrFile);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+}
+
+
+/*
+ * FUNCTION: Deletes a connection endpoint file object
+ * ARGUMENTS:
+ * Connection = Pointer to connection endpoint to delete
+ */
+VOID DeleteConnectionEndpoint(
+ PCONNECTION_ENDPOINT Connection)
+{
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY NextEntry;
- /* Dereference address entry */
- DereferenceObject(AddrFile->ADE);
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
- /* Dereference address cache */
- if (AddrFile->AddrCache)
- DereferenceObject(AddrFile->AddrCache);
+ /* Remove connection endpoint from the global list */
+ KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+ RemoveEntryList(&Connection->ListEntry);
+ KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+ /* Dereference and remove the address file if it exists */
+ if (Connection->AddressFile) {
+ RemoveEntryList(&Connection->AddrFileEntry);
+ DereferenceObject(Connection->AddressFile);
+ }
+
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
#ifdef DBG
- /* Remove reference provided at creation time */
- AddrFile->RefCount--;
+ /* Remove reference provided at creation time */
+ Connection->RefCount--;
- if (AddrFile->RefCount != 0)
- TI_DbgPrint(DEBUG_REFCOUNT, ("AddrFile->RefCount is (%d) (should be 0).\n", AddrFile->RefCount));
+ if (Connection->RefCount != 0)
+ TI_DbgPrint(DEBUG_REFCOUNT, ("Connection->RefCount is (%d) (should be 0).\n",
+ Connection->RefCount));
#endif
-
- PoolFreeBuffer(AddrFile);
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ ExFreePool(Connection);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID RequestWorker(
- PVOID Context)
+ PVOID Context)
/*
* FUNCTION: Worker routine for processing address file object requests
* ARGUMENTS:
* Context = Pointer to context information (ADDRESS_FILE)
*/
{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PADDRESS_FILE AddrFile = Context;
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PADDRESS_FILE AddrFile = Context;
- TI_DbgPrint(MID_TRACE, ("Called.\n"));
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- /* Check it the address file should be deleted */
- if (AF_IS_PENDING(AddrFile, AFF_DELETE)) {
- DATAGRAM_COMPLETION_ROUTINE RtnComplete;
- PVOID RtnContext;
+ /* Check it the address file should be deleted */
+ if (AF_IS_PENDING(AddrFile, AFF_DELETE)) {
+ DATAGRAM_COMPLETION_ROUTINE RtnComplete;
+ PVOID RtnContext;
- RtnComplete = AddrFile->Complete;
- RtnContext = AddrFile->Context;
+ RtnComplete = AddrFile->Complete;
+ RtnContext = AddrFile->Context;
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- DeleteAddress(AddrFile);
+ DeleteAddress(AddrFile);
- (*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
+ (*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
- TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
- return;
- }
+ return;
+ }
- /* Check if there is a pending send request */
- if (AF_IS_PENDING(AddrFile, AFF_SEND)) {
- if (!IsListEmpty(&AddrFile->TransmitQueue)) {
- PDATAGRAM_SEND_REQUEST SendRequest;
+ /* Check if there is a pending send request */
+ if (AF_IS_PENDING(AddrFile, AFF_SEND)) {
+ if (!IsListEmpty(&AddrFile->TransmitQueue)) {
+ PDATAGRAM_SEND_REQUEST SendRequest;
- CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
- SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+ CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
+ SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
- AF_CLR_BUSY(AddrFile);
+ AF_CLR_BUSY(AddrFile);
- ReferenceObject(AddrFile);
+ ReferenceObject(AddrFile);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- /* The send routine processes the send requests in
- the transmit queue on the address file. When the
- queue is empty the pending send flag is cleared.
- The routine may return with the pending send flag
- set. This can happen if there was not enough free
- resources available to complete all send requests */
- DGSend(AddrFile, SendRequest);
+ /* The send routine processes the send requests in
+ the transmit queue on the address file. When the
+ queue is empty the pending send flag is cleared.
+ The routine may return with the pending send flag
+ set. This can happen if there was not enough free
+ resources available to complete all send requests */
+ DGSend(AddrFile, SendRequest);
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- DereferenceObject(AddrFile);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ DereferenceObject(AddrFile);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving (send request).\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving (send request).\n"));
- return;
- } else
- /* There was a pending send, but no send request.
- Print a debug message and continue */
- TI_DbgPrint(MIN_TRACE, ("Pending send, but no send request.\n"));
- }
+ return;
+ } else
+ /* There was a pending send, but no send request.
+ Print a debug message and continue */
+ TI_DbgPrint(MIN_TRACE, ("Pending send, but no send request.\n"));
+ }
- AF_CLR_BUSY(AddrFile);
+ AF_CLR_BUSY(AddrFile);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
* Status of operation
*/
NTSTATUS FileOpenAddress(
- PTDI_REQUEST Request,
- PTA_ADDRESS_IP Address,
- USHORT Protocol,
- PVOID Options)
+ PTDI_REQUEST Request,
+ PTA_ADDRESS_IP Address,
+ USHORT Protocol,
+ PVOID Options)
{
- PADDRESS_FILE AddrFile;
- IPv4_RAW_ADDRESS IPv4Address;
-
- TI_DbgPrint(MID_TRACE, ("Called.\n"));
-
- AddrFile = PoolAllocateBuffer(sizeof(ADDRESS_FILE));
- if (!AddrFile) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- TI_DbgPrint(DEBUG_ADDRFILE, ("Address file object allocated at (0x%X).\n", AddrFile));
-
- RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));
-
- /* Make sure address is a local unicast address or 0 */
-
- /* Locate address entry. If specified address is 0, a random address is chosen */
-
- /* FIXME: IPv4 only */
- IPv4Address = Address->Address[0].Address[0].in_addr;
- if (IPv4Address == 0)
- AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
- else
- AddrFile->ADE = AddrLocateADEv4(IPv4Address);
-
- if (!AddrFile->ADE) {
- PoolFreeBuffer(AddrFile);
- TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
- return STATUS_INVALID_PARAMETER;
- }
-
- TI_DbgPrint(MID_TRACE, ("Opening address %s for communication.\n",
- A2S(AddrFile->ADE->Address)));
-
- /* Protocol specific handling */
- switch (Protocol) {
- case IPPROTO_TCP:
- /* FIXME: TCP */
- TI_DbgPrint(MIN_TRACE, ("TCP is not supported.\n"));
- DereferenceObject(AddrFile->ADE);
- PoolFreeBuffer(AddrFile);
- return STATUS_INVALID_PARAMETER;
- case IPPROTO_UDP:
- /* FIXME: If specified port is 0, a port is chosen dynamically */
- AddrFile->Port = Address->Address[0].Address[0].sin_port;
- AddrFile->Send = UDPSendDatagram;
- break;
- default:
- /* Use raw IP for all other protocols */
- AddrFile->Port = 0;
- AddrFile->Send = RawIPSendDatagram;
- break;
- }
-
- TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
- Protocol));
-
- /* Set protocol */
- AddrFile->Protocol = Protocol;
-
- /* Initialize receive and transmit queues */
- InitializeListHead(&AddrFile->ReceiveQueue);
- InitializeListHead(&AddrFile->TransmitQueue);
-
- /* Initialize work queue item. We use this for pending requests */
- ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
-
- /* Initialize spin lock that protects the address file object */
- KeInitializeSpinLock(&AddrFile->Lock);
-
- /* Reference the object */
- AddrFile->RefCount = 1;
-
- /* Set valid flag so the address can be used */
- AF_SET_VALID(AddrFile);
-
- /* Return address file object */
- Request->Handle.AddressHandle = AddrFile;
-
- /* Add address file to global list */
- ExInterlockedInsertTailList(&AddressFileListHead, &AddrFile->ListEntry, &AddressFileListLock);
-
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
-
- return STATUS_SUCCESS;
+ PADDRESS_FILE AddrFile;
+ IPv4_RAW_ADDRESS IPv4Address;
+
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+ AddrFile = ExAllocatePool(NonPagedPool, sizeof(ADDRESS_FILE));
+ if (!AddrFile) {
+ TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ TI_DbgPrint(DEBUG_ADDRFILE, ("Address file object allocated at (0x%X).\n", AddrFile));
+
+ RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));
+
+ AddrFile->Free = AddrFileFree;
+
+ /* Make sure address is a local unicast address or 0 */
+
+ /* Locate address entry. If specified address is 0, a random address is chosen */
+
+ /* FIXME: IPv4 only */
+ IPv4Address = Address->Address[0].Address[0].in_addr;
+ if (IPv4Address == 0)
+ AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
+ else
+ AddrFile->ADE = AddrLocateADEv4(IPv4Address);
+
+ if (!AddrFile->ADE) {
+ ExFreePool(AddrFile);
+ TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ TI_DbgPrint(MID_TRACE, ("Opening address %s for communication.\n",
+ A2S(AddrFile->ADE->Address)));
+
+ /* Protocol specific handling */
+ switch (Protocol) {
+ case IPPROTO_TCP:
+ /* FIXME: If specified port is 0, a port is chosen dynamically */
+ AddrFile->Port = Address->Address[0].Address[0].sin_port;
+ AddrFile->Send = TCPSendDatagram;
+ break;
+
+ case IPPROTO_UDP:
+ /* FIXME: If specified port is 0, a port is chosen dynamically */
+ AddrFile->Port = Address->Address[0].Address[0].sin_port;
+ AddrFile->Send = UDPSendDatagram;
+ break;
+
+ default:
+ /* Use raw IP for all other protocols */
+ AddrFile->Port = 0;
+ AddrFile->Send = RawIPSendDatagram;
+ break;
+ }
+
+ TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
+ Protocol));
+
+ /* Set protocol */
+ AddrFile->Protocol = Protocol;
+
+ /* Initialize receive and transmit queues */
+ InitializeListHead(&AddrFile->ReceiveQueue);
+ InitializeListHead(&AddrFile->TransmitQueue);
+
+ /* Initialize associated connection list */
+ InitializeListHead(&AddrFile->Connections);
+
+ /* Initialize work queue item. We use this for pending requests */
+ ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
+
+ /* Initialize spin lock that protects the address file object */
+ KeInitializeSpinLock(&AddrFile->Lock);
+
+ /* Reference the object */
+ AddrFile->RefCount = 1;
+
+ /* Set valid flag so the address can be used */
+ AF_SET_VALID(AddrFile);
+
+ /* Return address file object */
+ Request->Handle.AddressHandle = AddrFile;
+
+ /* Add address file to global list */
+ ExInterlockedInsertTailList(
+ &AddressFileListHead,
+ &AddrFile->ListEntry,
+ &AddressFileListLock);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+ return STATUS_SUCCESS;
}
* Status of operation
*/
NTSTATUS FileCloseAddress(
- PTDI_REQUEST Request)
+ PTDI_REQUEST Request)
{
- KIRQL OldIrql;
- PADDRESS_FILE AddrFile;
- NTSTATUS Status = STATUS_SUCCESS;
+ KIRQL OldIrql;
+ PADDRESS_FILE AddrFile;
+ NTSTATUS Status = STATUS_SUCCESS;
- TI_DbgPrint(MID_TRACE, ("Called.\n"));
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
- AddrFile = Request->Handle.AddressHandle;
+ AddrFile = Request->Handle.AddressHandle;
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- if ((!AF_IS_BUSY(AddrFile)) && (AddrFile->RefCount == 1)) {
- /* Set address file object exclusive to us */
- AF_SET_BUSY(AddrFile);
- AF_CLR_VALID(AddrFile);
+ if ((!AF_IS_BUSY(AddrFile)) && (AddrFile->RefCount == 1)) {
+ /* Set address file object exclusive to us */
+ AF_SET_BUSY(AddrFile);
+ AF_CLR_VALID(AddrFile);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- DeleteAddress(AddrFile);
- } else {
- if (!AF_IS_PENDING(AddrFile, AFF_DELETE)) {
- AddrFile->Complete = Request->RequestNotifyObject;
- AddrFile->Context = Request->RequestContext;
+ DeleteAddress(AddrFile);
+ } else {
+ if (!AF_IS_PENDING(AddrFile, AFF_DELETE)) {
+ AddrFile->Complete = Request->RequestNotifyObject;
+ AddrFile->Context = Request->RequestContext;
- /* Shedule address file for deletion */
- AF_SET_PENDING(AddrFile, AFF_DELETE);
- AF_CLR_VALID(AddrFile);
+ /* Shedule address file for deletion */
+ AF_SET_PENDING(AddrFile, AFF_DELETE);
+ AF_CLR_VALID(AddrFile);
- if (!AF_IS_BUSY(AddrFile)) {
- /* Worker function is not running, so shedule it to run */
- AF_SET_BUSY(AddrFile);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
- } else
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ if (!AF_IS_BUSY(AddrFile)) {
+ /* Worker function is not running, so shedule it to run */
+ AF_SET_BUSY(AddrFile);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
+ } else
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
- return STATUS_PENDING;
- } else
- Status = STATUS_ADDRESS_CLOSED;
+ return STATUS_PENDING;
+ } else
+ Status = STATUS_ADDRESS_CLOSED;
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- }
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ }
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
- return Status;
+ return Status;
}
/*
* FUNCTION: Opens a connection file object
* ARGUMENTS:
- * Request = Pointer to TDI request structure for this request
+ * Request = Pointer to TDI request structure for this request
+ * ClientContext = Pointer to client context information
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenConnection(
- PTDI_REQUEST Request)
+ PTDI_REQUEST Request,
+ PVOID ClientContext)
{
- return STATUS_NOT_IMPLEMENTED;
+ PCONNECTION_ENDPOINT Connection;
+
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+ Connection = ExAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT));
+ if (!Connection)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ TI_DbgPrint(DEBUG_CPOINT, ("Connection point file object allocated at (0x%X).\n", Connection));
+
+ RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
+
+ /* Initialize spin lock that protects the connection endpoint file object */
+ KeInitializeSpinLock(&Connection->Lock);
+
+ /* Reference the object */
+ Connection->RefCount = 1;
+
+ /* Put connection in the closed state */
+ Connection->State = ctClosed;
+
+ /* Save client context pointer */
+ Connection->ClientContext = ClientContext;
+
+ /* Return connection endpoint file object */
+ Request->Handle.ConnectionContext = Connection;
+
+ /* Add connection endpoint to global list */
+ ExInterlockedInsertTailList(
+ &ConnectionEndpointListHead,
+ &Connection->ListEntry,
+ &ConnectionEndpointListLock);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+ return STATUS_SUCCESS;
}
/*
* FUNCTION: Closes an connection file object
* ARGUMENTS:
- * Request = Pointer to TDI request structure for this request
+ * Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseConnection(
- PTDI_REQUEST Request)
+ PTDI_REQUEST Request)
{
- return STATUS_NOT_IMPLEMENTED;
+ KIRQL OldIrql;
+ PCONNECTION_ENDPOINT Connection;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+ Connection = Request->Handle.ConnectionContext;
+
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+#if 0
+ if ((!AF_IS_BUSY(Connection)) && (Connection->RefCount == 1)) {
+ /* Set connection endpoint file object exclusive to us */
+ AF_SET_BUSY(Connection);
+ AF_CLR_VALID(Connection);
+
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+#endif
+ DeleteConnectionEndpoint(Connection);
+#if 0
+ } else {
+ if (!AF_IS_PENDING(Connection, AFF_DELETE)) {
+ Connection->Complete = Request->RequestNotifyObject;
+ Connection->Context = Request->RequestContext;
+
+ /* Shedule connection endpoint for deletion */
+ AF_SET_PENDING(Connection, AFF_DELETE);
+ AF_CLR_VALID(Connection);
+
+ if (!AF_IS_BUSY(Connection)) {
+ /* Worker function is not running, so shedule it to run */
+ AF_SET_BUSY(Connection);
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ ExQueueWorkItem(&Connection->WorkItem, CriticalWorkQueue);
+ } else
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+
+ return STATUS_PENDING;
+ } else
+ Status = STATUS_ADDRESS_CLOSED;
+
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ }
+#endif
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+ return Status;
}
/*
* FUNCTION: Opens a control channel file object
* ARGUMENTS:
- * Request = Pointer to TDI request structure for this request
+ * Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenControlChannel(
- PTDI_REQUEST Request)
+ PTDI_REQUEST Request)
{
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Closes a control channel file object
* ARGUMENTS:
- * Request = Pointer to TDI request structure for this request
+ * Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseControlChannel(
- PTDI_REQUEST Request)
+ PTDI_REQUEST Request)
{
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
/* EOF */
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
-//DWORD DebugTraceLevel = MAX_TRACE | DEBUG_ICMP | DEBUG_BUFFER;
+//DWORD DebugTraceLevel = MAX_TRACE;
+//DWORD DebugTraceLevel = DEBUG_ULTRA;
#endif /* DBG */
NTSTATUS TiGetProtocolNumber(
- PUNICODE_STRING FileName,
- PULONG Protocol)
+ PUNICODE_STRING FileName,
+ PULONG Protocol)
/*
* FUNCTION: Returns the protocol number from a file name
* ARGUMENTS:
* Status of operation
*/
{
- UNICODE_STRING us;
- NTSTATUS Status;
- ULONG Value;
- PWSTR Name;
+ UNICODE_STRING us;
+ NTSTATUS Status;
+ ULONG Value;
+ PWSTR Name;
- TI_DbgPrint(MAX_TRACE, ("Called. FileName (%wZ).\n", FileName));
+ TI_DbgPrint(MAX_TRACE, ("Called. FileName (%wZ).\n", FileName));
- Name = FileName->Buffer;
+ Name = FileName->Buffer;
- if (*Name++ != (WCHAR)L'\\')
- return STATUS_UNSUCCESSFUL;
+ if (*Name++ != (WCHAR)L'\\')
+ return STATUS_UNSUCCESSFUL;
- if (*Name == (WCHAR)NULL)
- return STATUS_UNSUCCESSFUL;
+ if (*Name == (WCHAR)NULL)
+ return STATUS_UNSUCCESSFUL;
- RtlInitUnicodeString(&us, Name);
+ RtlInitUnicodeString(&us, Name);
- Status = RtlUnicodeStringToInteger(&us, 10, &Value);
- if (!NT_SUCCESS(Status) || ((Value > 255)))
- return STATUS_UNSUCCESSFUL;
+ Status = RtlUnicodeStringToInteger(&us, 10, &Value);
+ if (!NT_SUCCESS(Status) || ((Value > 255)))
+ return STATUS_UNSUCCESSFUL;
- *Protocol = Value;
+ *Protocol = Value;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
* Status of the operation
*/
NTSTATUS TiCreateFileObject(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
{
- PIO_STACK_LOCATION IrpSp;
- PFILE_FULL_EA_INFORMATION EaInfo;
- PTA_ADDRESS_IP Address;
- PTRANSPORT_CONTEXT Context;
- TDI_REQUEST Request;
- NTSTATUS Status;
- ULONG Protocol;
-
- TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
-
- EaInfo = Irp->AssociatedIrp.SystemBuffer;
-
- /* Parameter check */
- if (!EaInfo) {
- TI_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
+ PFILE_FULL_EA_INFORMATION EaInfo;
+ PTRANSPORT_CONTEXT Context;
+ PIO_STACK_LOCATION IrpSp;
+ PTA_ADDRESS_IP Address;
+ TDI_REQUEST Request;
+ PVOID ClientContext;
+ NTSTATUS Status;
+ ULONG Protocol;
+
+ TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
+
+ EaInfo = Irp->AssociatedIrp.SystemBuffer;
+CP
+ /* Parameter check */
+ if (!EaInfo) {
+ TI_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+CP
+ /* Allocate resources here. We release them again if something failed */
+ Context = ExAllocatePool(NonPagedPool, sizeof(TRANSPORT_CONTEXT));
+ if (!Context) {
+ TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+CP
+ Context->RefCount = 1;
+ Context->CancelIrps = FALSE;
+ KeInitializeEvent(&Context->CleanupEvent, NotificationEvent, FALSE);
+CP
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ IrpSp->FileObject->FsContext = Context;
+ Request.RequestContext = Irp;
+CP
+ /* Branch to the right handler */
+ if ((EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) &&
+ (RtlCompareMemory(&EaInfo->EaName, TdiTransportAddress,
+ TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) {
+ /* This is a request to open an address */
+CP
+ /* Parameter checks */
+ Address = (PTA_ADDRESS_IP)(EaInfo->EaName + EaInfo->EaNameLength);
+ if ((EaInfo->EaValueLength < sizeof(TA_ADDRESS_IP)) ||
+ (Address->TAAddressCount != 1) ||
+ (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
+ (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP)) {
+ TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
+ ExFreePool(Context);
+ return STATUS_INVALID_PARAMETER;
+ }
+CP
+ /* Open address file object */
+
+ /* Protocol depends on device object so find the protocol */
+ if (DeviceObject == TCPDeviceObject)
+ Protocol = IPPROTO_TCP;
+ else if (DeviceObject == UDPDeviceObject)
+ Protocol = IPPROTO_UDP;
+ else if (DeviceObject == IPDeviceObject)
+ Protocol = IPPROTO_RAW;
+ else if (DeviceObject == RawIPDeviceObject) {
+ Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
+ if (!NT_SUCCESS(Status)) {
+ TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
+ ExFreePool(Context);
return STATUS_INVALID_PARAMETER;
+ }
+ } else {
+ TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
+ ExFreePool(Context);
+ return STATUS_INVALID_PARAMETER;
}
-
- /* Allocate resources here. We release them again if something failed */
- Context = ExAllocatePool(NonPagedPool, sizeof(TRANSPORT_CONTEXT));
- if (!Context) {
- TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
+CP
+ Status = FileOpenAddress(&Request, Address, Protocol, NULL);
+ if (NT_SUCCESS(Status)) {
+ IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
+ Context->Handle.AddressHandle = Request.Handle.AddressHandle;
+ }
+CP
+ } else if ((EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) &&
+ (RtlCompareMemory(&EaInfo->EaName, TdiConnectionContext,
+ TDI_CONNECTION_CONTEXT_LENGTH) == TDI_CONNECTION_CONTEXT_LENGTH)) {
+ /* This is a request to open a connection endpoint */
+CP
+ /* Parameter checks */
+
+ if (EaInfo->EaValueLength < sizeof(PVOID)) {
+ TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
+ ExFreePool(Context);
+ return STATUS_INVALID_PARAMETER;
}
- Context->RefCount = 1;
- Context->CancelIrps = FALSE;
- KeInitializeEvent(&Context->CleanupEvent, NotificationEvent, FALSE);
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- IrpSp->FileObject->FsContext = Context;
- Request.RequestContext = Irp;
-
- /* Branch to the right handler */
- if ((EaInfo->EaNameLength==TDI_TRANSPORT_ADDRESS_LENGTH) &&
- (RtlCompareMemory(&EaInfo->EaName, TdiTransportAddress,
- TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) {
- /* This is a request to open an address */
-
- /* Parameter checks */
- Address = (PTA_ADDRESS_IP)(EaInfo->EaName + EaInfo->EaNameLength);
- if ((EaInfo->EaValueLength < sizeof(TA_ADDRESS_IP)) ||
- (Address->TAAddressCount != 1) ||
- (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
- (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP)) {
- TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
- ExFreePool(Context);
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Open address file object */
-
- /* Protocol depends on device object so find the protocol */
- if (DeviceObject == TCPDeviceObject)
- Protocol = IPPROTO_TCP;
- else if (DeviceObject == UDPDeviceObject)
- Protocol = IPPROTO_UDP;
- else if (DeviceObject == IPDeviceObject)
- Protocol = IPPROTO_RAW;
- else if (DeviceObject == RawIPDeviceObject) {
- Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
- if (!NT_SUCCESS(Status)) {
- TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
- ExFreePool(Context);
- return STATUS_INVALID_PARAMETER;
- }
- } else {
- TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
- ExFreePool(Context);
- return STATUS_INVALID_PARAMETER;
- }
-
- Status = FileOpenAddress(&Request, Address, Protocol, NULL);
- if (NT_SUCCESS(Status)) {
- IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
- Context->Handle.AddressHandle = Request.Handle.AddressHandle;
- }
- } else {
- TI_DbgPrint(MIN_TRACE, ("Connection endpoint, and control connections are not supported.\n"));
- /* FIXME: Open a connection endpoint, or control connection */
- Status = STATUS_NOT_IMPLEMENTED;
+ /* Can only do connection oriented communication using TCP */
+
+ if (DeviceObject != TCPDeviceObject) {
+ TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
+ ExFreePool(Context);
+ return STATUS_INVALID_PARAMETER;
}
- if (!NT_SUCCESS(Status))
- ExFreePool(Context);
+ ClientContext = *((PVOID*)(EaInfo->EaName + EaInfo->EaNameLength));
- TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+ /* Open connection endpoint file object */
- return Status;
+ Status = FileOpenConnection(&Request, ClientContext);
+ if (NT_SUCCESS(Status)) {
+ IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE;
+ Context->Handle.ConnectionContext = Request.Handle.ConnectionContext;
+ }
+ } else {
+ /* This is a request to open a control connection */
+
+ TI_DbgPrint(MIN_TRACE, ("Control connections are not implemented yet\n"));
+
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+
+ if (!NT_SUCCESS(Status))
+ ExFreePool(Context);
+
+ TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+
+ return Status;
}
VOID TiCleanupFileObjectComplete(
- PVOID Context,
- NTSTATUS Status)
+ PVOID Context,
+ NTSTATUS Status)
/*
* FUNCTION: Completes an object cleanup IRP I/O request
* ARGUMENTS:
* Status = Final status of the operation
*/
{
- PIRP Irp;
- PIO_STACK_LOCATION IrpSp;
- PTRANSPORT_CONTEXT TranContext;
- KIRQL OldIrql;
+ PIRP Irp;
+ PIO_STACK_LOCATION IrpSp;
+ PTRANSPORT_CONTEXT TranContext;
+ KIRQL OldIrql;
- Irp = (PIRP)Context;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
+ Irp = (PIRP)Context;
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
- Irp->IoStatus.Status = Status;
-
- IoAcquireCancelSpinLock(&OldIrql);
+ Irp->IoStatus.Status = Status;
+
+ IoAcquireCancelSpinLock(&OldIrql);
- /* Remove the initial reference provided at object creation time */
- TranContext->RefCount--;
+ /* Remove the initial reference provided at object creation time */
+ TranContext->RefCount--;
#ifdef DBG
- if (TranContext->RefCount != 0)
- TI_DbgPrint(DEBUG_REFCOUNT, ("TranContext->RefCount is %i, should be 0.\n", TranContext->RefCount));
+ if (TranContext->RefCount != 0)
+ TI_DbgPrint(DEBUG_REFCOUNT, ("TranContext->RefCount is %i, should be 0.\n", TranContext->RefCount));
#endif
- KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
+ KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
- IoReleaseCancelSpinLock(OldIrql);
+ IoReleaseCancelSpinLock(OldIrql);
}
* This function does not pend
*/
NTSTATUS TiCleanupFileObject(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
{
- PIO_STACK_LOCATION IrpSp;
- PTRANSPORT_CONTEXT Context;
- TDI_REQUEST Request;
- NTSTATUS Status;
- KIRQL OldIrql;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- Context = IrpSp->FileObject->FsContext;
- if (!Context) {
- TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
- return STATUS_INVALID_PARAMETER;
- }
+ PIO_STACK_LOCATION IrpSp;
+ PTRANSPORT_CONTEXT Context;
+ TDI_REQUEST Request;
+ NTSTATUS Status;
+ KIRQL OldIrql;
- IoAcquireCancelSpinLock(&OldIrql);
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ Context = IrpSp->FileObject->FsContext;
+ if (!Context) {
+ TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
- Context->CancelIrps = TRUE;
- KeResetEvent(&Context->CleanupEvent);
+ IoAcquireCancelSpinLock(&OldIrql);
- IoReleaseCancelSpinLock(OldIrql);
+ Context->CancelIrps = TRUE;
+ KeResetEvent(&Context->CleanupEvent);
- Request.RequestNotifyObject = TiCleanupFileObjectComplete;
- Request.RequestContext = Irp;
+ IoReleaseCancelSpinLock(OldIrql);
- switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
- case TDI_TRANSPORT_ADDRESS_FILE:
- Request.Handle.AddressHandle = Context->Handle.AddressHandle;
- Status = FileCloseAddress(&Request);
- break;
+ Request.RequestNotifyObject = TiCleanupFileObjectComplete;
+ Request.RequestContext = Irp;
- case TDI_CONNECTION_FILE:
- Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
- Status = FileCloseConnection(&Request);
- break;
+ switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
+ case TDI_TRANSPORT_ADDRESS_FILE:
+ Request.Handle.AddressHandle = Context->Handle.AddressHandle;
+ Status = FileCloseAddress(&Request);
+ break;
- case TDI_CONTROL_CHANNEL_FILE:
- Request.Handle.ControlChannel = Context->Handle.ControlChannel;
- Status = FileCloseControlChannel(&Request);
- break;
+ case TDI_CONNECTION_FILE:
+ Request.Handle.ConnectionContext = Context->Handle.ConnectionContext;
+ Status = FileCloseConnection(&Request);
+ break;
- default:
- /* This should never happen */
+ case TDI_CONTROL_CHANNEL_FILE:
+ Request.Handle.ControlChannel = Context->Handle.ControlChannel;
+ Status = FileCloseControlChannel(&Request);
+ break;
- TI_DbgPrint(MIN_TRACE, ("Unknown transport context.\n"));
+ default:
+ /* This should never happen */
- IoAcquireCancelSpinLock(&OldIrql);
- Context->CancelIrps = FALSE;
- IoReleaseCancelSpinLock(OldIrql);
+ TI_DbgPrint(MIN_TRACE, ("Unknown transport context.\n"));
- return STATUS_INVALID_PARAMETER;
- }
+ IoAcquireCancelSpinLock(&OldIrql);
+ Context->CancelIrps = FALSE;
+ IoReleaseCancelSpinLock(OldIrql);
- if (Status != STATUS_PENDING)
- TiCleanupFileObjectComplete(Irp, Status);
-
- KeWaitForSingleObject(&Context->CleanupEvent,
- UserRequest, KernelMode, FALSE, NULL);
-
- return Irp->IoStatus.Status;
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (Status != STATUS_PENDING)
+ TiCleanupFileObjectComplete(Irp, Status);
+
+ KeWaitForSingleObject(&Context->CleanupEvent,
+ UserRequest, KernelMode, FALSE, NULL);
+
+ return Irp->IoStatus.Status;
}
STDCALL
#endif
TiDispatchOpenClose(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
/*
* FUNCTION: Main dispath routine
* ARGUMENTS:
* Status of the operation
*/
{
- PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
- PTRANSPORT_CONTEXT Context;
-
- TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
-
- IoMarkIrpPending(Irp);
- Irp->IoStatus.Status = STATUS_PENDING;
- Irp->IoStatus.Information = 0;
-
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- switch (IrpSp->MajorFunction) {
- /* Open an address file, connection endpoint, or control connection */
- case IRP_MJ_CREATE:
- Status = TiCreateFileObject(DeviceObject, Irp);
- break;
-
- /* Close an address file, connection endpoint, or control connection */
- case IRP_MJ_CLOSE:
- Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
- if (Context)
- ExFreePool(Context);
- Status = STATUS_SUCCESS;
- break;
-
- /* Release resources bound to an address file, connection endpoint,
- or control connection */
- case IRP_MJ_CLEANUP:
- Status = TiCleanupFileObject(DeviceObject, Irp);
- break;
-
- default:
- Status = STATUS_INVALID_DEVICE_REQUEST;
- }
+ PIO_STACK_LOCATION IrpSp;
+ NTSTATUS Status;
+ PTRANSPORT_CONTEXT Context;
- if (Status != STATUS_PENDING) {
- IrpSp->Control &= ~SL_PENDING_RETURNED;
- Irp->IoStatus.Status = Status;
+ TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
- TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
+ IoMarkIrpPending(Irp);
+ Irp->IoStatus.Status = STATUS_PENDING;
+ Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
- }
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
- TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+ switch (IrpSp->MajorFunction) {
+ /* Open an address file, connection endpoint, or control connection */
+ case IRP_MJ_CREATE:
+ Status = TiCreateFileObject(DeviceObject, Irp);
+ break;
- return Status;
+ /* Close an address file, connection endpoint, or control connection */
+ case IRP_MJ_CLOSE:
+ Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
+ if (Context)
+ ExFreePool(Context);
+ Status = STATUS_SUCCESS;
+ break;
+
+ /* Release resources bound to an address file, connection endpoint,
+ or control connection */
+ case IRP_MJ_CLEANUP:
+ Status = TiCleanupFileObject(DeviceObject, Irp);
+ break;
+
+ default:
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ if (Status != STATUS_PENDING) {
+ IrpSp->Control &= ~SL_PENDING_RETURNED;
+ Irp->IoStatus.Status = Status;
+
+ TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
+
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ }
+
+ TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+
+ return Status;
}
STDCALL
#endif
TiDispatchInternal(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
/*
* FUNCTION: Internal IOCTL dispatch routine
* ARGUMENTS:
*/
{
NTSTATUS Status;
- PIO_STACK_LOCATION IrpSp;
+ PIO_STACK_LOCATION IrpSp;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
- TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
- DeviceObject, Irp, IrpSp->MinorFunction));
+ TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
+ DeviceObject, Irp, IrpSp->MinorFunction));
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
- switch (IrpSp->MinorFunction) {
- case TDI_RECEIVE:
- Status = DispTdiReceive(Irp);
- break;
+ switch (IrpSp->MinorFunction) {
+ case TDI_RECEIVE:
+ Status = DispTdiReceive(Irp);
+ break;
- case TDI_RECEIVE_DATAGRAM:
- Status = DispTdiReceiveDatagram(Irp);
- break;
+ case TDI_RECEIVE_DATAGRAM:
+ Status = DispTdiReceiveDatagram(Irp);
+ break;
- case TDI_SEND:
- Status = DispTdiSend(Irp);
- break;
+ case TDI_SEND:
+ Status = DispTdiSend(Irp);
+ break;
- case TDI_SEND_DATAGRAM:
- Status = DispTdiSendDatagram(Irp);
- break;
+ case TDI_SEND_DATAGRAM:
+ Status = DispTdiSendDatagram(Irp);
+ break;
- case TDI_ACCEPT:
- Status = DispTdiAccept(Irp);
- break;
+ case TDI_ACCEPT:
+ Status = DispTdiAccept(Irp);
+ break;
- case TDI_LISTEN:
- Status = DispTdiListen(Irp);
- break;
+ case TDI_LISTEN:
+ Status = DispTdiListen(Irp);
+ break;
- case TDI_CONNECT:
- Status = DispTdiConnect(Irp);
- break;
+ case TDI_CONNECT:
+ Status = DispTdiConnect(Irp);
+ break;
- case TDI_DISCONNECT:
- Status = DispTdiDisconnect(Irp);
- break;
+ case TDI_DISCONNECT:
+ Status = DispTdiDisconnect(Irp);
+ break;
- case TDI_ASSOCIATE_ADDRESS:
- Status = DispTdiAssociateAddress(Irp);
- break;
+ case TDI_ASSOCIATE_ADDRESS:
+ Status = DispTdiAssociateAddress(Irp);
+ break;
- case TDI_DISASSOCIATE_ADDRESS:
- Status = DispTdiDisassociateAddress(Irp);
- break;
+ case TDI_DISASSOCIATE_ADDRESS:
+ Status = DispTdiDisassociateAddress(Irp);
+ break;
- case TDI_QUERY_INFORMATION:
- Status = DispTdiQueryInformation(DeviceObject, Irp);
- break;
+ case TDI_QUERY_INFORMATION:
+ Status = DispTdiQueryInformation(DeviceObject, Irp);
+ break;
- case TDI_SET_INFORMATION:
- Status = DispTdiSetInformation(Irp);
- break;
+ case TDI_SET_INFORMATION:
+ Status = DispTdiSetInformation(Irp);
+ break;
- case TDI_SET_EVENT_HANDLER:
- Status = DispTdiSetEventHandler(Irp);
- break;
+ case TDI_SET_EVENT_HANDLER:
+ Status = DispTdiSetEventHandler(Irp);
+ break;
- case TDI_ACTION:
- Status = STATUS_SUCCESS;
- break;
+ case TDI_ACTION:
+ Status = STATUS_SUCCESS;
+ break;
- /* An unsupported IOCTL code was submitted */
- default:
- Status = STATUS_INVALID_DEVICE_REQUEST;
- }
+ /* An unsupported IOCTL code was submitted */
+ default:
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
- if (Status != STATUS_PENDING) {
- Irp->IoStatus.Status = Status;
+ if (Status != STATUS_PENDING) {
+ Irp->IoStatus.Status = Status;
- TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
+ TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
- IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
- }
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ }
- TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+ TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
return Status;
}
STDCALL
#endif
TiDispatch(
- PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
/*
* FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
* ARGUMENTS:
* Status of the operation
*/
{
- NTSTATUS Status;
- PIO_STACK_LOCATION IrpSp;
+ NTSTATUS Status;
+ PIO_STACK_LOCATION IrpSp;
- TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
+ TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
- Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Information = 0;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
#ifdef _MSC_VER
- Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
- if (NT_SUCCESS(Status)) {
- TiDispatchInternal(DeviceObject, Irp);
- Status = STATUS_PENDING;
- } else {
+ Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
+ if (NT_SUCCESS(Status)) {
+ TiDispatchInternal(DeviceObject, Irp);
+ Status = STATUS_PENDING;
+ } else {
#else
- if (TRUE) {
+ if (TRUE) {
#endif
- /* See if this request is TCP/IP specific */
- switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
- case IOCTL_TCP_QUERY_INFORMATION_EX:
- Status = DispTdiQueryInformationEx(Irp, IrpSp);
- break;
-
- case IOCTL_TCP_SET_INFORMATION_EX:
- Status = DispTdiSetInformationEx(Irp, IrpSp);
- break;
-
- default:
- TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
- IrpSp->Parameters.DeviceIoControl.IoControlCode));
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- }
+ /* See if this request is TCP/IP specific */
+ switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
+ case IOCTL_TCP_QUERY_INFORMATION_EX:
+ Status = DispTdiQueryInformationEx(Irp, IrpSp);
+ break;
+
+ case IOCTL_TCP_SET_INFORMATION_EX:
+ Status = DispTdiSetInformationEx(Irp, IrpSp);
+ break;
+
+ default:
+ TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
+ IrpSp->Parameters.DeviceIoControl.IoControlCode));
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
}
+ }
- if (Status != STATUS_PENDING) {
- Irp->IoStatus.Status = Status;
+ if (Status != STATUS_PENDING) {
+ Irp->IoStatus.Status = Status;
- TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
+ TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
- IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
- }
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ }
- TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+ TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
- return Status;
+ return Status;
}
VOID TiUnload(
- PDRIVER_OBJECT DriverObject)
+ PDRIVER_OBJECT DriverObject)
/*
* FUNCTION: Unloads the driver
* ARGUMENTS:
*/
{
#ifdef DBG
- KIRQL OldIrql;
+ KIRQL OldIrql;
- KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
- if (!IsListEmpty(&AddressFileListHead)) {
- TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
- }
- KeReleaseSpinLock(&AddressFileListLock, OldIrql);
+ KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
+ if (!IsListEmpty(&AddressFileListHead)) {
+ TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
+ }
+ KeReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
- /* Unregister loopback adapter */
- LoopUnregisterAdapter(NULL);
+ /* Unregister loopback adapter */
+ LoopUnregisterAdapter(NULL);
- /* Unregister protocol with NDIS */
- LANUnregisterProtocol();
+ /* Unregister protocol with NDIS */
+ LANUnregisterProtocol();
- /* Shutdown transport level protocol subsystems */
- TCPShutdown();
- UDPShutdown();
- RawIPShutdown();
- DGShutdown();
+ /* Shutdown transport level protocol subsystems */
+ TCPShutdown();
+ UDPShutdown();
+ RawIPShutdown();
+ DGShutdown();
- /* Shutdown network level protocol subsystem */
- IPShutdown();
+ /* Shutdown network level protocol subsystem */
+ IPShutdown();
- /* Free NDIS buffer descriptors */
- if (GlobalBufferPool)
- NdisFreeBufferPool(GlobalBufferPool);
+ /* Free NDIS buffer descriptors */
+ if (GlobalBufferPool)
+ NdisFreeBufferPool(GlobalBufferPool);
- /* Free NDIS packet descriptors */
- if (GlobalPacketPool)
- NdisFreePacketPool(GlobalPacketPool);
+ /* Free NDIS packet descriptors */
+ if (GlobalPacketPool)
+ NdisFreePacketPool(GlobalPacketPool);
- /* Release all device objects */
+ /* Release all device objects */
- if (TCPDeviceObject)
- IoDeleteDevice(TCPDeviceObject);
+ if (TCPDeviceObject)
+ IoDeleteDevice(TCPDeviceObject);
- if (UDPDeviceObject)
- IoDeleteDevice(UDPDeviceObject);
+ if (UDPDeviceObject)
+ IoDeleteDevice(UDPDeviceObject);
- if (RawIPDeviceObject)
- IoDeleteDevice(RawIPDeviceObject);
+ if (RawIPDeviceObject)
+ IoDeleteDevice(RawIPDeviceObject);
- if (IPDeviceObject)
- IoDeleteDevice(IPDeviceObject);
+ if (IPDeviceObject)
+ IoDeleteDevice(IPDeviceObject);
- if (EntityList)
- ExFreePool(EntityList);
+ if (EntityList)
+ ExFreePool(EntityList);
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
STDCALL
#endif
DriverEntry(
- PDRIVER_OBJECT DriverObject,
- PUNICODE_STRING RegistryPath)
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Main driver entry point
* ARGUMENTS:
* Status of driver initialization
*/
{
- NTSTATUS Status;
- UNICODE_STRING strDeviceName;
- STRING strNdisDeviceName;
- NDIS_STATUS NdisStatus;
- PLAN_ADAPTER Adapter;
- NDIS_STRING DeviceName;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- /* FIXME: Create symbolic links in Win32 namespace */
-
- /* Create IP device object */
- RtlInitUnicodeString(&strDeviceName, DD_IP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
- 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;
- }
-
- /* Create RawIP device object */
- RtlInitUnicodeString(&strDeviceName, DD_RAWIP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
- 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 */
- RtlInitUnicodeString(&strDeviceName, DD_UDP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
- 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 */
- RtlInitUnicodeString(&strDeviceName, DD_TCP_DEVICE_NAME);
- Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
- 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;
- }
-
- /* 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 interface list and protecting spin lock */
- InitializeListHead(&InterfaceListHead);
- KeInitializeSpinLock(&InterfaceListLock);
-
- /* Initialize network level protocol subsystem */
- IPStartup(DriverObject, RegistryPath);
-
- /* Initialize transport level protocol subsystems */
- DGStartup();
- RawIPStartup();
- UDPStartup();
- TCPStartup();
-
- /* Register protocol with NDIS */
- RtlInitString(&strNdisDeviceName, IP_DEVICE_NAME);
- Status = LANRegisterProtocol(&strNdisDeviceName);
- if (!NT_SUCCESS(Status)) {
- TiWriteErrorLog(
- DriverObject,
- EVENT_TRANSPORT_REGISTER_FAILED,
- TI_ERROR_DRIVERENTRY,
- Status,
- NULL,
- 0,
- NULL);
- TiUnload(DriverObject);
- return Status;
- }
+ NTSTATUS Status;
+ UNICODE_STRING strDeviceName;
+ STRING strNdisDeviceName;
+ NDIS_STATUS NdisStatus;
+ PLAN_ADAPTER Adapter;
+ NDIS_STRING DeviceName;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ /* FIXME: Create symbolic links in Win32 namespace */
+
+ /* Create IP device object */
+ RtlInitUnicodeString(&strDeviceName, DD_IP_DEVICE_NAME);
+ Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ 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;
+ }
+
+ /* Create RawIP device object */
+ RtlInitUnicodeString(&strDeviceName, DD_RAWIP_DEVICE_NAME);
+ Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ 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 */
+ RtlInitUnicodeString(&strDeviceName, DD_UDP_DEVICE_NAME);
+ Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ 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 */
+ RtlInitUnicodeString(&strDeviceName, DD_TCP_DEVICE_NAME);
+ Status = IoCreateDevice(DriverObject, 0, &strDeviceName,
+ 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;
+ }
+
+ /* 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(DriverObject, RegistryPath);
+
+ /* Initialize transport level protocol subsystems */
+ DGStartup();
+ RawIPStartup();
+ UDPStartup();
+ TCPStartup();
+
+ /* Register protocol with NDIS */
+ RtlInitString(&strNdisDeviceName, IP_DEVICE_NAME);
+ Status = LANRegisterProtocol(&strNdisDeviceName);
+ if (!NT_SUCCESS(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;
- }
+ /* 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;
+ }
- /* Open underlying adapter(s) we are bound to */
+/* Open underlying adapter(s) we are bound to */
- /* FIXME: Get binding information from registry */
+ /* FIXME: Get binding information from registry */
- /* Put your own NDIS adapter device name here */
+ /* Put your own NDIS adapter device name here */
#if 0
- /* ReactOS */
- NdisInitUnicodeString(&DeviceName, L"\\Device\\ne2000");
-
- /* NT4 style */
- //NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
-
- /* NT5 style */
- //NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
-
- NdisStatus = LANRegisterAdapter(&DeviceName, &Adapter);
-
- /* Skip network adapter if it does not exist */
- if (!NT_SUCCESS(NdisStatus)) {
- TI_DbgPrint(MIN_TRACE, ("Failed to intialize adapter. Status (0x%X).\n", Status));
- TiWriteErrorLog(
- DriverObject,
- EVENT_TRANSPORT_ADAPTER_NOT_FOUND,
- TI_ERROR_DRIVERENTRY,
- NdisStatus,
- NULL,
- 0,
- NULL);
- TiUnload(DriverObject);
- return STATUS_DEVICE_DOES_NOT_EXIST;
- }
+ /* ReactOS */
+ NdisInitUnicodeString(&DeviceName, L"\\Device\\ne2000");
+
+ /* NT4 style */
+ //NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
+
+ /* NT5 style */
+ //NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
+
+ NdisStatus = LANRegisterAdapter(&DeviceName, &Adapter);
+
+ /* Skip network adapter if it does not exist */
+ if (!NT_SUCCESS(NdisStatus)) {
+ TI_DbgPrint(MIN_TRACE, ("Failed to intialize adapter. Status (0x%X).\n", Status));
+ TiWriteErrorLog(
+ DriverObject,
+ EVENT_TRANSPORT_ADAPTER_NOT_FOUND,
+ TI_ERROR_DRIVERENTRY,
+ NdisStatus,
+ NULL,
+ 0,
+ NULL);
+ TiUnload(DriverObject);
+ return STATUS_DEVICE_DOES_NOT_EXIST;
+ }
#endif
- /* Setup network layer and transport layer entities */
- EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * 2);
- if (!NT_SUCCESS(Status)) {
- TiUnload(DriverObject);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- EntityList[0].tei_entity = CL_NL_ENTITY;
- EntityList[0].tei_instance = 0;
- EntityList[1].tei_entity = CL_TL_ENTITY;
- EntityList[1].tei_instance = 0;
- EntityCount = 2;
-
- /* 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 = (PDRIVER_UNLOAD)TiUnload;
-
- return STATUS_SUCCESS;
+ /* Setup network layer and transport layer entities */
+ EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * 2);
+ if (!NT_SUCCESS(Status)) {
+ TiUnload(DriverObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ EntityList[0].tei_entity = CL_NL_ENTITY;
+ EntityList[0].tei_instance = 0;
+ EntityList[1].tei_entity = CL_TL_ENTITY;
+ EntityList[1].tei_instance = 0;
+ EntityCount = 2;
+
+ /* 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 = (PDRIVER_UNLOAD)TiUnload;
+
+ return STATUS_SUCCESS;
}
UINT RandomNumber = 0x12345678;
+inline NTSTATUS BuildDatagramSendRequest(
+ PDATAGRAM_SEND_REQUEST *SendRequest,
+ PIP_ADDRESS RemoteAddress,
+ USHORT RemotePort,
+ PNDIS_BUFFER Buffer,
+ DWORD BufferSize,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ DATAGRAM_BUILD_ROUTINE Build,
+ ULONG Flags)
+/*
+ * FUNCTION: Allocates and intializes a datagram send request
+ * ARGUMENTS:
+ * SendRequest = Pointer to datagram send request
+ * RemoteAddress = Pointer to remote IP address
+ * RemotePort = Remote port number
+ * Buffer = Pointer to NDIS buffer to send
+ * BufferSize = Size of Buffer
+ * Complete = Completion routine
+ * Context = Pointer to context information
+ * Build = Datagram build routine
+ * Flags = Protocol specific flags
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PDATAGRAM_SEND_REQUEST Request;
+
+ Request = ExAllocatePool(NonPagedPool, sizeof(DATAGRAM_SEND_REQUEST));
+ if (!Request)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ InitializeDatagramSendRequest(
+ Request,
+ RemoteAddress,
+ RemotePort,
+ Buffer,
+ BufferSize,
+ Complete,
+ Context,
+ Build,
+ Flags);
+
+ *SendRequest = Request;
+
+ return STATUS_SUCCESS;
+}
+
+
+inline NTSTATUS BuildTCPSendRequest(
+ PTCP_SEND_REQUEST *SendRequest,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ PVOID ProtocolContext)
+/*
+ * FUNCTION: Allocates and intializes a TCP send request
+ * ARGUMENTS:
+ * SendRequest = Pointer to TCP send request
+ * Complete = Completion routine
+ * Context = Pointer to context information
+ * ProtocolContext = Protocol specific context
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PTCP_SEND_REQUEST Request;
+
+ Request = ExAllocatePool(NonPagedPool, sizeof(TCP_SEND_REQUEST));
+ if (!Request)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ InitializeTCPSendRequest(
+ Request,
+ Complete,
+ Context,
+ ProtocolContext);
+
+ *SendRequest = Request;
+
+ return STATUS_SUCCESS;
+}
+
+
UINT Random(
VOID)
/*
return;
}
+ TI_DbgPrint(MIN_TRACE, ("IPPacket is at (0x%X).\n", IPPacket));
TI_DbgPrint(MIN_TRACE, ("Header buffer is at (0x%X).\n", IPPacket->Header));
TI_DbgPrint(MIN_TRACE, ("Header size is (%d).\n", IPPacket->HeaderSize));
TI_DbgPrint(MIN_TRACE, ("TotalSize (%d).\n", IPPacket->TotalSize));
VOID DatagramWorker(
- PVOID Context)
+ PVOID Context)
/*
- * FUNCTION: Handles pending requests
+ * FUNCTION: Handles pending send requests
* ARGUMENTS:
* Context = Pointer to context information (unused)
* NOTES:
* It processes send requests or shedules them to be processed
*/
{
- PLIST_ENTRY CurrentADFEntry;
- PLIST_ENTRY CurrentSREntry;
- PADDRESS_FILE CurrentADF;
- PDATAGRAM_SEND_REQUEST CurrentSR;
- KIRQL OldIrql1;
- KIRQL OldIrql2;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- KeAcquireSpinLock(&DGPendingListLock, &OldIrql1);
-
- CurrentADFEntry = DGPendingListHead.Flink;
- while (CurrentADFEntry != &DGPendingListHead) {
- RemoveEntryList(CurrentADFEntry);
- CurrentADF = CONTAINING_RECORD(CurrentADFEntry,
- ADDRESS_FILE,
- ListEntry);
-
- KeAcquireSpinLock(&CurrentADF->Lock, &OldIrql2);
-
- if (AF_IS_BUSY(CurrentADF)) {
- /* The send worker function is already running so we just
- set the pending send flag on the address file object */
-
- AF_SET_PENDING(CurrentADF, AFF_SEND);
- KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
- } else {
- if (!IsListEmpty(&CurrentADF->TransmitQueue)) {
- /* The transmit queue is not empty. Dequeue a send
- request and process it */
-
- CurrentSREntry = RemoveHeadList(&CurrentADF->TransmitQueue);
- CurrentSR = CONTAINING_RECORD(CurrentADFEntry,
- DATAGRAM_SEND_REQUEST,
- ListEntry);
-
- KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
-
- DGSend(CurrentADF, CurrentSR);
- } else
- KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
- }
- CurrentADFEntry = CurrentADFEntry->Flink;
+ PLIST_ENTRY CurrentADFEntry;
+ PLIST_ENTRY CurrentSREntry;
+ PADDRESS_FILE CurrentADF;
+ PDATAGRAM_SEND_REQUEST CurrentSR;
+ KIRQL OldIrql1;
+ KIRQL OldIrql2;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ KeAcquireSpinLock(&DGPendingListLock, &OldIrql1);
+
+ CurrentADFEntry = DGPendingListHead.Flink;
+ while (CurrentADFEntry != &DGPendingListHead) {
+ RemoveEntryList(CurrentADFEntry);
+ CurrentADF = CONTAINING_RECORD(CurrentADFEntry,
+ ADDRESS_FILE,
+ ListEntry);
+
+ KeAcquireSpinLock(&CurrentADF->Lock, &OldIrql2);
+
+ if (AF_IS_BUSY(CurrentADF)) {
+ /* The send worker function is already running so we just
+ set the pending send flag on the address file object */
+
+ AF_SET_PENDING(CurrentADF, AFF_SEND);
+ KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
+ } else {
+ if (!IsListEmpty(&CurrentADF->TransmitQueue)) {
+ /* The transmit queue is not empty. Dequeue a send
+ request and process it */
+
+ CurrentSREntry = RemoveHeadList(&CurrentADF->TransmitQueue);
+ CurrentSR = CONTAINING_RECORD(CurrentADFEntry,
+ DATAGRAM_SEND_REQUEST,
+ ListEntry);
+
+ KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
+
+ DGSend(CurrentADF, CurrentSR);
+ } else
+ KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
}
+ CurrentADFEntry = CurrentADFEntry->Flink;
+ }
- KeReleaseSpinLock(&DGPendingListLock, OldIrql1);
+ KeReleaseSpinLock(&DGPendingListLock, OldIrql1);
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID SendDatagramComplete(
- PVOID Context,
- PNDIS_PACKET Packet,
- NDIS_STATUS NdisStatus)
+ PVOID Context,
+ PNDIS_PACKET Packet,
+ NDIS_STATUS NdisStatus)
/*
* FUNCTION: Datagram transmit completion handler
* ARGUMENTS:
* are pending address files in the queue
*/
{
- KIRQL OldIrql;
- ULONG BytesSent;
- PVOID CompleteContext;
- PNDIS_BUFFER NdisBuffer;
- PDATAGRAM_SEND_REQUEST SendRequest;
- DATAGRAM_COMPLETION_ROUTINE Complete;
- BOOLEAN QueueWorkItem;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
- Complete = SendRequest->Complete;
- CompleteContext = SendRequest->Context;
- BytesSent = SendRequest->BufferSize;
-
- /* Remove data buffer before releasing memory for packet buffers */
- NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
- NdisUnchainBufferAtBack(Packet, &NdisBuffer);
- FreeNdisPacket(Packet);
- DereferenceObject(SendRequest->RemoteAddress);
- PoolFreeBuffer(SendRequest);
-
- /* If there are pending send requests, shedule worker function */
- KeAcquireSpinLock(&DGPendingListLock, &OldIrql);
- QueueWorkItem = (!IsListEmpty(&DGPendingListHead));
- KeReleaseSpinLock(&DGPendingListLock, OldIrql);
- if (QueueWorkItem)
- ExQueueWorkItem(&DGWorkItem, CriticalWorkQueue);
-
- /* Call completion routine for send request */
- (*Complete)(CompleteContext, NdisStatus, BytesSent);
-
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ KIRQL OldIrql;
+ ULONG BytesSent;
+ PVOID CompleteContext;
+ PNDIS_BUFFER NdisBuffer;
+ PDATAGRAM_SEND_REQUEST SendRequest;
+ DATAGRAM_COMPLETION_ROUTINE Complete;
+ BOOLEAN QueueWorkItem;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
+ Complete = SendRequest->Complete;
+ CompleteContext = SendRequest->Context;
+ BytesSent = SendRequest->BufferSize;
+
+ /* Remove data buffer before releasing memory for packet buffers */
+ NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
+ NdisUnchainBufferAtBack(Packet, &NdisBuffer);
+ FreeNdisPacket(Packet);
+ DereferenceObject(SendRequest->RemoteAddress);
+ ExFreePool(SendRequest);
+
+ /* If there are pending send requests, shedule worker function */
+ KeAcquireSpinLock(&DGPendingListLock, &OldIrql);
+ QueueWorkItem = (!IsListEmpty(&DGPendingListHead));
+ KeReleaseSpinLock(&DGPendingListLock, OldIrql);
+ if (QueueWorkItem)
+ ExQueueWorkItem(&DGWorkItem, CriticalWorkQueue);
+
+ TI_DbgPrint(MAX_TRACE, ("Calling 0x%X.\n", Complete));
+
+ /* Call completion routine for send request */
+ (*Complete)(CompleteContext, NdisStatus, BytesSent);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID DGSend(
- PVOID Context,
- PDATAGRAM_SEND_REQUEST SendRequest)
+ PVOID Context,
+ PDATAGRAM_SEND_REQUEST SendRequest)
/*
* FUNCTION: Sends a datagram to IP layer
* ARGUMENTS:
* SendRequest = Pointer to send request
*/
{
- KIRQL OldIrql;
- NTSTATUS Status;
- USHORT LocalPort;
- PIP_PACKET IPPacket;
- PROUTE_CACHE_NODE RCN;
- PLIST_ENTRY CurrentEntry;
- PADDRESS_FILE AddrFile = Context;
- PADDRESS_ENTRY ADE;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- /* Get the information we need from the address file
- now so we minimize the time we hold the spin lock */
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- LocalPort = AddrFile->Port;
- ADE = AddrFile->ADE;
- ReferenceObject(ADE);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- /* Loop until there are no more send requests in the
- transmit queue or until we run out of resources */
- for (;;) {
- Status = SendRequest->Build(SendRequest, ADE->Address, LocalPort, &IPPacket);
- if (!NT_SUCCESS(Status)) {
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- /* An error occurred, enqueue the send request again and return */
- InsertTailList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
- DereferenceObject(ADE);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- TI_DbgPrint(MIN_TRACE, ("Leaving (insufficient resources).\n"));
- return;
- }
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ USHORT LocalPort;
+ PIP_PACKET IPPacket;
+ PROUTE_CACHE_NODE RCN;
+ PLIST_ENTRY CurrentEntry;
+ PADDRESS_FILE AddrFile = Context;
+ PADDRESS_ENTRY ADE;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ /* Get the information we need from the address file
+ now so we minimize the time we hold the spin lock */
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ LocalPort = AddrFile->Port;
+ ADE = AddrFile->ADE;
+ ReferenceObject(ADE);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ /* Loop until there are no more send requests in the
+ transmit queue or until we run out of resources */
+ for (;;) {
+ Status = (*SendRequest->Build)(SendRequest, ADE->Address, LocalPort, &IPPacket);
+ if (!NT_SUCCESS(Status)) {
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ /* An error occurred, enqueue the send request again and return */
+ InsertTailList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
+ DereferenceObject(ADE);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ TI_DbgPrint(MIN_TRACE, ("Leaving (insufficient resources).\n"));
+ return;
+ }
- /* Get a route to the destination address */
- if (RouteGetRouteToDestination(SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS) {
- /* Set completion routine and send the packet */
- PC(IPPacket->NdisPacket)->Complete = SendDatagramComplete;
- PC(IPPacket->NdisPacket)->Context = SendRequest;
- if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS)
- SendDatagramComplete(SendRequest,
- IPPacket->NdisPacket,
- NDIS_STATUS_REQUEST_ABORTED);
- /* We're done with the RCN */
- DereferenceObject(RCN);
- } else {
- /* No route to destination */
- /* FIXME: Which error code should we use here? */
- TI_DbgPrint(MIN_TRACE, ("No route to destination address (0x%X).\n",
- SendRequest->RemoteAddress->Address.IPv4Address));
- SendDatagramComplete(SendRequest,
- IPPacket->NdisPacket,
- NDIS_STATUS_REQUEST_ABORTED);
- }
+ /* Get a route to the destination address */
+ if (RouteGetRouteToDestination(SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS) {
+ /* Set completion routine and send the packet */
+ PC(IPPacket->NdisPacket)->Complete = SendDatagramComplete;
+ PC(IPPacket->NdisPacket)->Context = SendRequest;
+ if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS)
+ SendDatagramComplete(
+ SendRequest,
+ IPPacket->NdisPacket,
+ NDIS_STATUS_REQUEST_ABORTED);
+ /* We're done with the RCN */
+ DereferenceObject(RCN);
+ } else {
+ /* No route to destination */
+ /* FIXME: Which error code should we use here? */
+ TI_DbgPrint(MIN_TRACE, ("No route to destination address (0x%X).\n",
+ SendRequest->RemoteAddress->Address.IPv4Address));
+ SendDatagramComplete(
+ SendRequest,
+ IPPacket->NdisPacket,
+ NDIS_STATUS_REQUEST_ABORTED);
+ }
- PoolFreeBuffer(IPPacket);
+ (*IPPacket->Free)(IPPacket);
- /* Check transmit queue for more to send */
+ /* Check transmit queue for more to send */
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
- if (!IsListEmpty(&AddrFile->TransmitQueue)) {
- /* Transmit queue is not empty, process one more request */
- CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
- SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+ if (!IsListEmpty(&AddrFile->TransmitQueue)) {
+ /* Transmit queue is not empty, process one more request */
+ CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
+ SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- } else {
- /* Transmit queue is empty */
- AF_CLR_PENDING(AddrFile, AFF_SEND);
- DereferenceObject(ADE);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ } else {
+ /* Transmit queue is empty */
+ AF_CLR_PENDING(AddrFile, AFF_SEND);
+ DereferenceObject(ADE);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving (empty queue).\n"));
- return;
- }
+ TI_DbgPrint(MAX_TRACE, ("Leaving (empty queue).\n"));
+ return;
}
+ }
}
VOID DGDeliverData(
- PADDRESS_FILE AddrFile,
- PIP_ADDRESS Address,
- PIP_PACKET IPPacket,
- UINT DataSize)
+ PADDRESS_FILE AddrFile,
+ PIP_ADDRESS Address,
+ PIP_PACKET IPPacket,
+ UINT DataSize)
/*
* FUNCTION: Delivers datagram data to a user
* ARGUMENTS:
* handler if it exists, otherwise we drop the packet.
*/
{
- KIRQL OldIrql;
- PTDI_IND_RECEIVE_DATAGRAM ReceiveHandler;
- PVOID HandlerContext;
- LONG AddressLength;
- PVOID SourceAddress;
- ULONG BytesTaken;
- NTSTATUS Status;
- PVOID DataBuffer;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+ KIRQL OldIrql;
+ PTDI_IND_RECEIVE_DATAGRAM ReceiveHandler;
+ PVOID HandlerContext;
+ LONG AddressLength;
+ PVOID SourceAddress;
+ ULONG BytesTaken;
+ NTSTATUS Status;
+ PVOID DataBuffer;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ if (AddrFile->Protocol == IPPROTO_UDP) {
+ DataBuffer = IPPacket->Data;
+ } else {
+ /* Give client the IP header too if it is a raw IP file object */
+ DataBuffer = IPPacket->Header;
+ }
+
+ if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
+ PLIST_ENTRY CurrentEntry;
+ PDATAGRAM_RECEIVE_REQUEST Current;
+ BOOLEAN Found;
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n"));
- if (AddrFile->Protocol == IPPROTO_UDP) {
- DataBuffer = IPPacket->Data;
- } else {
- /* Give client the IP header too if it is a raw IP file object */
- DataBuffer = IPPacket->Header;
+ /* Search receive request list to find a match */
+ Found = FALSE;
+ CurrentEntry = AddrFile->ReceiveQueue.Flink;
+ while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
+ Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
+ if (!Current->RemoteAddress)
+ Found = TRUE;
+ else if (AddrIsEqual(Address, Current->RemoteAddress))
+ Found = TRUE;
+
+ if (Found) {
+ /* FIXME: Maybe we should check if the buffer of this
+ receive request is large enough and if not, search
+ for another */
+
+ /* Remove the request from the queue */
+ RemoveEntryList(&Current->ListEntry);
+ AddrFile->RefCount--;
+ break;
+ }
+ CurrentEntry = CurrentEntry->Flink;
}
- if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
- PLIST_ENTRY CurrentEntry;
- PDATAGRAM_RECEIVE_REQUEST Current;
- BOOLEAN Found;
-
- TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n"));
-
- /* Search receive request list to find a match */
- Found = FALSE;
- CurrentEntry = AddrFile->ReceiveQueue.Flink;
- while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
- Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
- if (!Current->RemoteAddress)
- Found = TRUE;
- else if (AddrIsEqual(Address, Current->RemoteAddress))
- Found = TRUE;
-
- if (Found) {
- /* FIXME: Maybe we should check if the buffer of this
- receive request is large enough and if not, search
- for another */
-
- /* Remove the request from the queue */
- RemoveEntryList(&Current->ListEntry);
- AddrFile->RefCount--;
- break;
- }
- CurrentEntry = CurrentEntry->Flink;
- }
-
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- if (Found) {
- TI_DbgPrint(MAX_TRACE, ("Suitable receive request found.\n"));
-
- /* Copy the data into buffer provided by the user */
- CopyBufferToBufferChain(Current->Buffer,
- 0,
- DataBuffer,
- DataSize);
-
- /* Complete the receive request */
- (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize);
-
- /* Finally free the receive request */
- if (Current->RemoteAddress)
- PoolFreeBuffer(Current->RemoteAddress);
- PoolFreeBuffer(Current);
- }
- } else if (AddrFile->RegisteredReceiveDatagramHandler) {
- TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- ReceiveHandler = AddrFile->ReceiveDatagramHandler;
- HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
+ if (Found) {
+ TI_DbgPrint(MAX_TRACE, ("Suitable receive request found.\n"));
+
+ /* Copy the data into buffer provided by the user */
+ CopyBufferToBufferChain(
+ Current->Buffer,
+ 0,
+ DataBuffer,
+ DataSize);
+
+ /* Complete the receive request */
+ (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize);
+
+ /* Finally free the receive request */
+ if (Current->RemoteAddress)
+ DereferenceObject(Current->RemoteAddress);
+ ExFreePool(Current);
+ }
+ } else if (AddrFile->RegisteredReceiveDatagramHandler) {
+ TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ ReceiveHandler = AddrFile->ReceiveDatagramHandler;
+ HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
- if (Address->Type == IP_ADDRESS_V4) {
- AddressLength = sizeof(IPv4_RAW_ADDRESS);
- SourceAddress = &Address->Address.IPv4Address;
- } else /* (Address->Type == IP_ADDRESS_V6) */ {
- AddressLength = sizeof(IPv6_RAW_ADDRESS);
- SourceAddress = Address->Address.IPv6Address;
- }
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- Status = (*ReceiveHandler)(HandlerContext,
- AddressLength,
- SourceAddress,
- 0,
- NULL,
- TDI_RECEIVE_ENTIRE_MESSAGE,
- DataSize,
- DataSize,
- &BytesTaken,
- DataBuffer,
- NULL);
- } else {
- TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
+ if (Address->Type == IP_ADDRESS_V4) {
+ AddressLength = sizeof(IPv4_RAW_ADDRESS);
+ SourceAddress = &Address->Address.IPv4Address;
+ } else /* (Address->Type == IP_ADDRESS_V6) */ {
+ AddressLength = sizeof(IPv6_RAW_ADDRESS);
+ SourceAddress = Address->Address.IPv6Address;
}
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ Status = (*ReceiveHandler)(
+ HandlerContext,
+ AddressLength,
+ SourceAddress,
+ 0,
+ NULL,
+ TDI_RECEIVE_ENTIRE_MESSAGE,
+ DataSize,
+ DataSize,
+ &BytesTaken,
+ DataBuffer,
+ NULL);
+ } else {
+ TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
+ }
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID DGCancelSendRequest(
- PADDRESS_FILE AddrFile,
- PVOID Context)
+ PADDRESS_FILE AddrFile,
+ PVOID Context)
/*
* FUNCTION: Cancels a datagram send request
* ARGUMENTS:
* Context = Pointer to context information for completion handler
*/
{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PDATAGRAM_SEND_REQUEST Current = NULL;
- BOOLEAN Found = FALSE;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
- /* Search the request list for the specified request and remove it */
- CurrentEntry = AddrFile->TransmitQueue.Flink;
- while ((CurrentEntry != &AddrFile->TransmitQueue) && (!Found)) {
- Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
- if (Context == Current->Context) {
- /* We've found the request, now remove it from the queue */
- RemoveEntryList(CurrentEntry);
- AddrFile->RefCount--;
- Found = TRUE;
- break;
- }
- CurrentEntry = CurrentEntry->Flink;
- }
-
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- if (Found) {
- /* Complete the request and free its resources */
- (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
- PoolFreeBuffer(Current->RemoteAddress);
- PoolFreeBuffer(Current);
- } else {
- TI_DbgPrint(MID_TRACE, ("Cannot find send request.\n"));
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PDATAGRAM_SEND_REQUEST Current = NULL;
+ BOOLEAN Found = FALSE;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ /* Search the request list for the specified request and remove it */
+ CurrentEntry = AddrFile->TransmitQueue.Flink;
+ while ((CurrentEntry != &AddrFile->TransmitQueue) && (!Found)) {
+ Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+ if (Context == Current->Context) {
+ /* We've found the request, now remove it from the queue */
+ RemoveEntryList(CurrentEntry);
+ AddrFile->RefCount--;
+ Found = TRUE;
+ break;
}
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ if (Found) {
+ /* Complete the request and free its resources */
+ (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
+ DereferenceObject(Current->RemoteAddress);
+ ExFreePool(Current);
+ } else {
+ TI_DbgPrint(MID_TRACE, ("Cannot find send request.\n"));
+ }
}
VOID DGCancelReceiveRequest(
- PADDRESS_FILE AddrFile,
- PVOID Context)
+ PADDRESS_FILE AddrFile,
+ PVOID Context)
/*
* FUNCTION: Cancels a datagram receive request
* ARGUMENTS:
* Context = Pointer to context information for completion handler
*/
{
- KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PDATAGRAM_RECEIVE_REQUEST Current = NULL;
- BOOLEAN Found = FALSE;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
- /* Search the request list for the specified request and remove it */
- CurrentEntry = AddrFile->ReceiveQueue.Flink;
- while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
- Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
- if (Context == Current->Context) {
- /* We've found the request, now remove it from the queue */
- RemoveEntryList(CurrentEntry);
- AddrFile->RefCount--;
- Found = TRUE;
- break;
- }
- CurrentEntry = CurrentEntry->Flink;
+ KIRQL OldIrql;
+ PLIST_ENTRY CurrentEntry;
+ PDATAGRAM_RECEIVE_REQUEST Current = NULL;
+ BOOLEAN Found = FALSE;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ /* Search the request list for the specified request and remove it */
+ CurrentEntry = AddrFile->ReceiveQueue.Flink;
+ while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
+ Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
+ if (Context == Current->Context) {
+ /* We've found the request, now remove it from the queue */
+ RemoveEntryList(CurrentEntry);
+ AddrFile->RefCount--;
+ Found = TRUE;
+ break;
}
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ if (Found) {
+ /* Complete the request and free its resources */
+ (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
+ /* Remote address can be NULL if the caller wants to receive
+ packets sent from any address */
+ if (Current->RemoteAddress)
+ DereferenceObject(Current->RemoteAddress);
+ ExFreePool(Current);
+ } else {
+ TI_DbgPrint(MID_TRACE, ("Cannot find receive request.\n"));
+ }
+}
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- if (Found) {
- /* Complete the request and free its resources */
- (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
- /* Remote address can be NULL if the caller wants to receive
- packets sent from any address */
- if (Current->RemoteAddress)
- PoolFreeBuffer(Current->RemoteAddress);
- PoolFreeBuffer(Current);
- } else {
- TI_DbgPrint(MID_TRACE, ("Cannot find receive request.\n"));
- }
+NTSTATUS DGTransmit(
+ PADDRESS_FILE AddressFile,
+ PDATAGRAM_SEND_REQUEST SendRequest)
+/*
+ * FUNCTION: Transmits or queues a send request
+ * ARGUMENTS:
+ * AddressFile = Pointer to address file
+ * SendRequest = Pointer to send request
+ * RETURNS:
+ * Status of operation
+ */
+{
+ KIRQL OldIrql;
+CP
+ KeAcquireSpinLock(&AddressFile->Lock, &OldIrql);
+CP
+ if (AF_IS_BUSY(AddressFile)) {
+CP
+ /* Queue send request on the transmit queue */
+ InsertTailList(&AddressFile->TransmitQueue, &SendRequest->ListEntry);
+CP
+ /* Reference address file and set pending send request flag */
+ ReferenceObject(AddressFile);
+CP
+ AF_SET_PENDING(AddressFile, AFF_SEND);
+CP
+ KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
+CP
+ TI_DbgPrint(MAX_TRACE, ("Leaving (queued).\n"));
+ } else {
+CP
+ KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
+CP
+ /* Send the datagram */
+ DGSend(AddressFile, SendRequest);
+CP
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+ }
+CP
+ return STATUS_PENDING;
}
-
NTSTATUS DGSendDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG DataSize,
- DATAGRAM_BUILD_ROUTINE Build)
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG DataSize,
+ DATAGRAM_BUILD_ROUTINE Build)
/*
* FUNCTION: Sends a datagram to a remote address
* ARGUMENTS:
* Status of operation
*/
{
- PADDRESS_FILE AddrFile;
- KIRQL OldIrql;
- NTSTATUS Status;
- PDATAGRAM_SEND_REQUEST SendRequest = NULL;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- AddrFile = Request->Handle.AddressHandle;
-
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
- if (AF_IS_VALID(AddrFile)) {
- SendRequest = PoolAllocateBuffer(sizeof(DATAGRAM_SEND_REQUEST));
- if (SendRequest) {
- /* Initialize a send request */
- Status = AddrGetAddress(ConnInfo->RemoteAddress,
- &SendRequest->RemoteAddress, &SendRequest->RemotePort,
- &AddrFile->AddrCache);
- if (NT_SUCCESS(Status)) {
- SendRequest->Buffer = Buffer;
- SendRequest->BufferSize = DataSize;
- SendRequest->Complete = Request->RequestNotifyObject;
- SendRequest->Context = Request->RequestContext;
- SendRequest->Build = Build;
-
- if (AF_IS_BUSY(AddrFile)) {
- /* Queue send request on the transmit queue */
- InsertTailList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
-
- /* Reference address file and set pending send request flag */
- AddrFile->RefCount++;
- AF_SET_PENDING(AddrFile, AFF_SEND);
-
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- TI_DbgPrint(MAX_TRACE, ("Leaving (queued).\n"));
- } else {
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- /* Send the datagram */
- DGSend(AddrFile, SendRequest);
-
- TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
- }
- return STATUS_PENDING;
- }
- } else
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ PADDRESS_FILE AddrFile;
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ PDATAGRAM_SEND_REQUEST SendRequest;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ AddrFile = Request->Handle.AddressHandle;
+
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ if (AF_IS_VALID(AddrFile)) {
+ /* Initialize a send request */
+ Status = BuildDatagramSendRequest(
+ &SendRequest,
+ NULL,
+ 0,
+ Buffer,
+ DataSize,
+ Request->RequestNotifyObject,
+ Request->RequestContext,
+ Build,
+ 0);
+ if (NT_SUCCESS(Status)) {
+ Status = AddrGetAddress(
+ ConnInfo->RemoteAddress,
+ &SendRequest->RemoteAddress,
+ &SendRequest->RemotePort,
+ &AddrFile->AddrCache);
+ if (NT_SUCCESS(Status)) {
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ return DGTransmit(AddrFile, SendRequest);
+ } else {
+ ExFreePool(SendRequest);
+ }
} else
- Status = STATUS_ADDRESS_CLOSED;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ } else
+ Status = STATUS_ADDRESS_CLOSED;
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
+ TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
- return Status;
+ return Status;
}
NTSTATUS DGReceiveDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG ReceiveLength,
- ULONG ReceiveFlags,
- PTDI_CONNECTION_INFORMATION ReturnInfo,
- PULONG BytesReceived)
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG ReceiveLength,
+ ULONG ReceiveFlags,
+ PTDI_CONNECTION_INFORMATION ReturnInfo,
+ PULONG BytesReceived)
/*
* FUNCTION: Attempts to receive a datagram from a remote address
* ARGUMENTS:
* This is the high level interface for receiving datagrams
*/
{
- PADDRESS_FILE AddrFile;
- KIRQL OldIrql;
- NTSTATUS Status;
- PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
+ PADDRESS_FILE AddrFile;
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- AddrFile = Request->Handle.AddressHandle;
+ AddrFile = Request->Handle.AddressHandle;
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ if (AF_IS_VALID(AddrFile)) {
+ ReceiveRequest = ExAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
+ if (ReceiveRequest) {
+ /* Initialize a receive request */
- if (AF_IS_VALID(AddrFile)) {
- ReceiveRequest = PoolAllocateBuffer(sizeof(DATAGRAM_RECEIVE_REQUEST));
- if (ReceiveRequest) {
- /* Initialize a receive request */
-
- /* Extract the remote address filter from the request (if any) */
- if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress)) {
- Status = AddrGetAddress(ConnInfo->RemoteAddress,
- &ReceiveRequest->RemoteAddress,
- &ReceiveRequest->RemotePort,
- &AddrFile->AddrCache);
- if (!NT_SUCCESS(Status)) {
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- PoolFreeBuffer(ReceiveRequest);
- return Status;
- }
- } else {
- ReceiveRequest->RemotePort = 0;
- ReceiveRequest->RemoteAddress = NULL;
- }
- ReceiveRequest->ReturnInfo = ReturnInfo;
- ReceiveRequest->Buffer = Buffer;
- /* If ReceiveLength is 0, the whole buffer is available to us */
- ReceiveRequest->BufferSize = (ReceiveLength == 0) ?
- MmGetMdlByteCount(Buffer) : ReceiveLength;
- ReceiveRequest->Complete = Request->RequestNotifyObject;
- ReceiveRequest->Context = Request->RequestContext;
-
- /* Queue receive request */
- InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
-
- /* Reference address file and set pending receive request flag */
- AddrFile->RefCount++;
- AF_SET_PENDING(AddrFile, AFF_RECEIVE);
-
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
- TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
-
- return STATUS_PENDING;
- } else
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ /* Extract the remote address filter from the request (if any) */
+ if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress)) {
+ Status = AddrGetAddress(ConnInfo->RemoteAddress,
+ &ReceiveRequest->RemoteAddress,
+ &ReceiveRequest->RemotePort,
+ &AddrFile->AddrCache);
+ if (!NT_SUCCESS(Status)) {
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ ExFreePool(ReceiveRequest);
+ return Status;
+ }
+ } else {
+ ReceiveRequest->RemotePort = 0;
+ ReceiveRequest->RemoteAddress = NULL;
+ }
+ ReceiveRequest->ReturnInfo = ReturnInfo;
+ ReceiveRequest->Buffer = Buffer;
+ /* If ReceiveLength is 0, the whole buffer is available to us */
+ ReceiveRequest->BufferSize = (ReceiveLength == 0) ?
+ MmGetMdlByteCount(Buffer) : ReceiveLength;
+ ReceiveRequest->Complete = Request->RequestNotifyObject;
+ ReceiveRequest->Context = Request->RequestContext;
+
+ /* Queue receive request */
+ InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
+
+ /* Reference address file and set pending receive request flag */
+ AddrFile->RefCount++;
+ AF_SET_PENDING(AddrFile, AFF_RECEIVE);
+
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+
+ return STATUS_PENDING;
} else
- Status = STATUS_INVALID_ADDRESS;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ } else
+ Status = STATUS_INVALID_ADDRESS;
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
- TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
+ TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
- return Status;
+ return Status;
}
NTSTATUS DGStartup(
- VOID)
+ VOID)
/*
* FUNCTION: Initializes the datagram subsystem
* RETURNS:
* Status of operation
*/
{
- InitializeListHead(&DGPendingListHead);
+ InitializeListHead(&DGPendingListHead);
- KeInitializeSpinLock(&DGPendingListLock);
+ KeInitializeSpinLock(&DGPendingListLock);
- ExInitializeWorkItem(&DGWorkItem, DatagramWorker, NULL);
+ ExInitializeWorkItem(&DGWorkItem, DatagramWorker, NULL);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS DGShutdown(
- VOID)
+ VOID)
/*
* FUNCTION: Shuts down the datagram subsystem
* RETURNS:
* Status of operation
*/
{
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", SendRequest->Buffer->ByteOffset));
/* Prepare packet */
- Packet = PoolAllocateBuffer(sizeof(IP_PACKET));
- if (!Packet) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet.\n"));
+
+ /* FIXME: Assumes IPv4 */
+ Packet = IPCreatePacket(IP_ADDRESS_V4);
+ if (!Packet)
return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlZeroMemory(Packet, sizeof(IP_PACKET));
Packet->Flags = IP_PACKET_FLAG_RAW; /* Don't touch IP header */
- Packet->RefCount = 1;
Packet->TotalSize = SendRequest->BufferSize;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus));
- PoolFreeBuffer(Packet);
+ TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus))
+ (*Packet->Free)(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
if (MaxLLHeaderSize != 0) {
- Header = PoolAllocateBuffer(MaxLLHeaderSize);
+ Header = ExAllocatePool(NonPagedPool, MaxLLHeaderSize);
if (!Header) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
NdisFreePacket(Packet->NdisPacket);
- PoolFreeBuffer(Packet);
+ (*Packet->Free)(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
MaxLLHeaderSize);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
- PoolFreeBuffer(Header);
+ ExFreePool(Header);
NdisFreePacket(Packet->NdisPacket);
- PoolFreeBuffer(Packet);
+ (*Packet->Free)(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Chain header at front of packet */
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
+#include <tcp.h>
+#include <pool.h>
+#include <address.h>
+#include <datagram.h>
BOOLEAN TCPInitialized = FALSE;
+NTSTATUS TCPiAddHeaderIPv4(
+ PDATAGRAM_SEND_REQUEST SendRequest,
+ PIP_ADDRESS LocalAddress,
+ USHORT LocalPort,
+ PIP_PACKET IPPacket)
+/*
+ * FUNCTION: Adds an IPv4 and TCP header to an IP packet
+ * ARGUMENTS:
+ * SendRequest = Pointer to send request
+ * LocalAddress = Pointer to our local address
+ * LocalPort = The port we send this segment from
+ * IPPacket = Pointer to IP packet
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PIPv4_HEADER IPHeader;
+ PTCP_HEADER TCPHeader;
+ PVOID Header;
+ ULONG BufferSize;
+ NDIS_STATUS NdisStatus;
+ PNDIS_BUFFER HeaderBuffer;
+
+ BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + sizeof(TCP_HEADER);
+ Header = ExAllocatePool(NonPagedPool, BufferSize);
+ if (!Header)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", BufferSize, Header));
+
+ /* Allocate NDIS buffer for maximum Link level, IP and TCP header */
+ NdisAllocateBuffer(&NdisStatus,
+ &HeaderBuffer,
+ GlobalBufferPool,
+ Header,
+ BufferSize);
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ ExFreePool(Header);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Chain header at front of NDIS packet */
+ NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
+
+ IPPacket->Header = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
+ IPPacket->HeaderSize = 20;
+
+ /* Build IPv4 header */
+ IPHeader = (PIPv4_HEADER)IPPacket->Header;
+ /* Version = 4, Length = 5 DWORDs */
+ IPHeader->VerIHL = 0x45;
+ /* Normal Type-of-Service */
+ IPHeader->Tos = 0;
+ /* Length of header and data */
+ IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
+ /* Identification */
+ IPHeader->Id = 0;
+ /* One fragment at offset 0 */
+ IPHeader->FlagsFragOfs = 0;
+ /* Time-to-Live is 128 */
+ IPHeader->Ttl = 128;
+ /* Transmission Control Protocol */
+ IPHeader->Protocol = IPPROTO_TCP;
+ /* Checksum is 0 (for later calculation of this) */
+ IPHeader->Checksum = 0;
+ /* Source address */
+ IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
+ /* Destination address. FIXME: IPv4 only */
+ IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
+
+ /* Build TCP header */
+ TCPHeader = (PTCP_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
+ /* Port values are already big-endian values */
+ TCPHeader->SourcePort = LocalPort;
+ TCPHeader->DestPort = SendRequest->RemotePort;
+ TCPHeader->SeqNum = 0;
+ TCPHeader->AckNum = 0;
+ TCPHeader->DataOfs = 0;
+ TCPHeader->Flags = SendRequest->Flags;
+ TCPHeader->Window = 0;
+ /* FIXME: Calculate TCP checksum and put it in TCP header */
+ TCPHeader->Checksum = 0;
+ TCPHeader->Urgent = 0;
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS TCPiBuildPacket(
+ PVOID Context,
+ PIP_ADDRESS LocalAddress,
+ USHORT LocalPort,
+ PIP_PACKET *IPPacket)
+/*
+ * FUNCTION: Builds a TCP packet
+ * ARGUMENTS:
+ * Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
+ * LocalAddress = Pointer to our local address
+ * LocalPort = The port we send this segment from
+ * IPPacket = Address of pointer to IP packet
+ * RETURNS:
+ * Status of operation
+ * NOTES:
+ * The ProcotolContext field in the send request structure (pointed to
+ * by the Context field) contains a pointer to the CONNECTION_ENDPOINT
+ * structure for the connection
+ */
+{
+ NTSTATUS Status;
+ PIP_PACKET Packet;
+ NDIS_STATUS NdisStatus;
+ PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ /* Prepare packet */
+
+ /* FIXME: Assumes IPv4*/
+ Packet = IPCreatePacket(IP_ADDRESS_V4);
+ if (!Packet)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Packet->TotalSize = sizeof(IPv4_HEADER) +
+ sizeof(TCP_HEADER) +
+ SendRequest->BufferSize;
+
+ /* Allocate NDIS packet */
+ NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ (*Packet->Free)(Packet);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ switch (SendRequest->RemoteAddress->Type) {
+ case IP_ADDRESS_V4:
+ Status = TCPiAddHeaderIPv4(SendRequest, LocalAddress, LocalPort, Packet);
+ break;
+ case IP_ADDRESS_V6:
+ /* FIXME: Support IPv6 */
+ TI_DbgPrint(MIN_TRACE, ("IPv6 TCP segments are not supported.\n"));
+ default:
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+ if (!NT_SUCCESS(Status)) {
+ TI_DbgPrint(MIN_TRACE, ("Cannot add TCP header. Status (0x%X)\n", Status));
+ NdisFreePacket(Packet->NdisPacket);
+ (*Packet->Free)(Packet);
+ return Status;
+ }
+
+ /* Chain data after header */
+ NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
+
+ //DISPLAY_IP_PACKET(Packet);
+
+ *IPPacket = Packet;
+
+ return STATUS_SUCCESS;
+}
+
+
+VOID TCPiSendRequestComplete(
+ PVOID Context,
+ NTSTATUS Status,
+ ULONG Count)
+/*
+ * FUNCTION: Completion routine for datagram send requests
+ * ARGUMENTS:
+ * Context = Pointer to context information (TCP_SEND_REQUEST)
+ * Status = Status of the request
+ * Count = Number of bytes sent or received
+ */
+{
+ DATAGRAM_COMPLETION_ROUTINE Complete;
+ PVOID CompleteContext;
+ PTCP_SEND_REQUEST SendRequest = (PTCP_SEND_REQUEST)Context;
+
+ Complete = SendRequest->Complete;
+ CompleteContext = SendRequest->Context;
+ ExFreePool(SendRequest);
+
+ TI_DbgPrint(MAX_TRACE, ("Calling completion routine.\n"));
+
+ /* Call upper level completion routine */
+ (*Complete)(CompleteContext, Status, Count);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+}
+
+
+VOID TCPTimeout(VOID)
+/*
+ * FUNCTION: Transmission Control Protocol timeout handler
+ * NOTES:
+ * This routine is called by IPTimeout to perform several
+ * maintainance tasks
+ */
+{
+}
+
+
+inline NTSTATUS TCPBuildSendRequest(
+ PTCP_SEND_REQUEST *SendRequest,
+ PDATAGRAM_SEND_REQUEST *DGSendRequest,
+ PCONNECTION_ENDPOINT Connection,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ PNDIS_BUFFER Buffer,
+ DWORD BufferSize,
+ ULONG Flags)
+/*
+ * FUNCTION: Allocates and intializes a TCP send request
+ * ARGUMENTS:
+ * SendRequest = TCP send request
+ * DGSendRequest = Datagram send request (optional)
+ * Connection = Connection endpoint
+ * Complete = Completion routine
+ * Context = Pointer to context information
+ * Buffer = Pointer to NDIS buffer to send
+ * BufferSize = Size of Buffer
+ * Flags = Protocol specific flags
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PDATAGRAM_SEND_REQUEST DGSendReq;
+ NTSTATUS Status;
+
+ Status = BuildTCPSendRequest(
+ SendRequest,
+ Complete,
+ Context,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Status = BuildDatagramSendRequest(
+ &DGSendReq, /* Datagram send request */
+ Connection->RemoteAddress, /* Address of remote peer */
+ Connection->RemotePort, /* Port of remote peer */
+ Buffer, /* Buffer */
+ BufferSize, /* Size of buffer */
+ TCPiSendRequestComplete, /* Completion function */
+ *SendRequest, /* Context for completion function */
+ TCPiBuildPacket, /* Packet build function */
+ Flags); /* Protocol specific flags */
+ if (!NT_SUCCESS(Status)) {
+ ExFreePool(*SendRequest);
+ return Status;
+ }
+
+ if (DGSendRequest)
+ *DGSendRequest = DGSendReq;
+
+ return STATUS_SUCCESS;
+}
+
+
+inline NTSTATUS TCPBuildAndTransmitSendRequest(
+ PCONNECTION_ENDPOINT Connection,
+ DATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context,
+ PNDIS_BUFFER Buffer,
+ DWORD BufferSize,
+ ULONG Flags)
+/*
+ * FUNCTION: Allocates and intializes a TCP send request
+ * ARGUMENTS:
+ * Connection = Connection endpoint
+ * Complete = Completion routine
+ * Context = Pointer to context information
+ * Buffer = Pointer to NDIS buffer to send
+ * BufferSize = Size of Buffer
+ * Flags = Protocol specific flags
+ * RETURNS:
+ * Status of operation
+ */
+{
+ PDATAGRAM_SEND_REQUEST DGSendRequest;
+ PTCP_SEND_REQUEST TCPSendRequest;
+ NTSTATUS Status;
+
+ Status = TCPBuildSendRequest(
+ &TCPSendRequest,
+ &DGSendRequest,
+ Connection, /* Connection endpoint */
+ Complete, /* Completion routine */
+ Context, /* Completion routine context */
+ Buffer, /* Buffer */
+ BufferSize, /* Size of buffer */
+ Flags); /* Protocol specific flags */
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Status = DGTransmit(
+ Connection->AddressFile,
+ DGSendRequest);
+ if (!NT_SUCCESS(Status)) {
+ ExFreePool(DGSendRequest);
+ ExFreePool(TCPSendRequest);
+ return Status;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS TCPConnect(
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PTDI_CONNECTION_INFORMATION ReturnInfo)
+/*
+ * FUNCTION: Attempts to connect to a remote peer
+ * ARGUMENTS:
+ * Request = Pointer to TDI request
+ * ConnInfo = Pointer to connection information
+ * ReturnInfo = Pointer to structure for return information
+ * RETURNS:
+ * Status of operation
+ * NOTES:
+ * This is the high level interface for connecting to remote peers
+ */
+{
+ PDATAGRAM_SEND_REQUEST DGSendRequest;
+ PTCP_SEND_REQUEST TCPSendRequest;
+ PCONNECTION_ENDPOINT Connection;
+ LARGE_INTEGER DueTime;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+ Connection = Request->Handle.ConnectionContext;
+
+ KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+
+ if (Connection->State != ctClosed) {
+ /* The connection has already been opened so return success */
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ return STATUS_SUCCESS;
+ }
+
+ Connection->LocalAddress = Connection->AddressFile->ADE->Address;
+ Connection->LocalPort = Connection->AddressFile->Port;
+
+ Status = AddrBuildAddress(
+ (PTA_ADDRESS)ConnInfo->RemoteAddress,
+ &Connection->RemoteAddress,
+ &Connection->RemotePort);
+ if (!NT_SUCCESS(Status)) {
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ return Status;
+ }
+
+ /* Issue SYN segment */
+
+ Status = TCPBuildAndTransmitSendRequest(
+ Connection, /* Connection endpoint */
+ Request->RequestNotifyObject, /* Completion routine */
+ Request->RequestContext, /* Completion routine context */
+ NULL, /* Buffer */
+ 0, /* Size of buffer */
+ SRF_SYN); /* Protocol specific flags */
+ if (!NT_SUCCESS(Status)) {
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+ ExFreePool(Connection->RemoteAddress);
+ return Status;
+ }
+
+ KeReleaseSpinLock(&Connection->Lock, OldIrql);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
+
+ return Status;
+}
+
+
+NTSTATUS TCPSendDatagram(
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG DataSize)
+/*
+ * FUNCTION: Sends TCP data to a remote address
+ * ARGUMENTS:
+ * Request = Pointer to TDI request
+ * ConnInfo = Pointer to connection information
+ * Buffer = Pointer to NDIS buffer with data
+ * DataSize = Size in bytes of data to be sent
+ * RETURNS:
+ * Status of operation
+ */
+{
+ return STATUS_SUCCESS;
+}
+
+
+VOID TCPReceive(
+ PNET_TABLE_ENTRY NTE,
+ PIP_PACKET IPPacket)
+/*
+ * FUNCTION: Receives and queues TCP data
+ * ARGUMENTS:
+ * NTE = Pointer to net table entry which the packet was received on
+ * IPPacket = Pointer to an IP packet that was received
+ * NOTES:
+ * This is the low level interface for receiving TCP data
+ */
+{
+ PIPv4_HEADER IPv4Header;
+ PADDRESS_FILE AddrFile;
+ PTCP_HEADER TCPHeader;
+ PIP_ADDRESS DstAddress;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ switch (IPPacket->Type) {
+ /* IPv4 packet */
+ case IP_ADDRESS_V4:
+ IPv4Header = IPPacket->Header;
+ DstAddress = &IPPacket->DstAddr;
+ break;
+
+ /* IPv6 packet */
+ case IP_ADDRESS_V6:
+ TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 TCP data (%i bytes).\n",
+ IPPacket->TotalSize));
+
+ /* FIXME: IPv6 is not supported */
+ return;
+
+ default:
+ return;
+ }
+
+ TCPHeader = (PTCP_HEADER)IPPacket->Data;
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+}
+
+
NTSTATUS TCPStartup(
- VOID)
+ VOID)
/*
* FUNCTION: Initializes the TCP subsystem
* RETURNS:
* Status of operation
*/
{
- TCPInitialized = TRUE;
+ /* Register this protocol with IP layer */
+ IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
- return STATUS_SUCCESS;
+ TCPInitialized = TRUE;
+
+ return STATUS_SUCCESS;
}
NTSTATUS TCPShutdown(
- VOID)
+ VOID)
/*
* FUNCTION: Shuts down the TCP subsystem
* RETURNS:
* Status of operation
*/
{
- if (!TCPInitialized)
- return STATUS_SUCCESS;
-
+ if (!TCPInitialized)
return STATUS_SUCCESS;
+
+ /* Deregister this protocol with IP layer */
+ IPRegisterProtocol(IPPROTO_TCP, NULL);
+
+ TCPInitialized = FALSE;
+
+ return STATUS_SUCCESS;
}
/* EOF */
NTSTATUS AddUDPHeaderIPv4(
- PDATAGRAM_SEND_REQUEST SendRequest,
- PIP_ADDRESS LocalAddress,
- USHORT LocalPort,
- PIP_PACKET IPPacket)
+ PDATAGRAM_SEND_REQUEST SendRequest,
+ PIP_ADDRESS LocalAddress,
+ USHORT LocalPort,
+ PIP_PACKET IPPacket)
/*
* FUNCTION: Adds an IPv4 and UDP header to an IP packet
* ARGUMENTS:
* Status of operation
*/
{
- PIPv4_HEADER IPHeader;
- PUDP_HEADER UDPHeader;
- PVOID Header;
+ PIPv4_HEADER IPHeader;
+ PUDP_HEADER UDPHeader;
+ PVOID Header;
ULONG BufferSize;
- NDIS_STATUS NdisStatus;
- PNDIS_BUFFER HeaderBuffer;
+ NDIS_STATUS NdisStatus;
+ PNDIS_BUFFER HeaderBuffer;
BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + sizeof(UDP_HEADER);
- Header = PoolAllocateBuffer(BufferSize);
-
- if (!Header) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", BufferSize, Header));
-
- /* Allocate NDIS buffer for maximum Link level, IP and UDP header */
- NdisAllocateBuffer(&NdisStatus,
- &HeaderBuffer,
- GlobalBufferPool,
- Header,
- BufferSize);
- if (NdisStatus != NDIS_STATUS_SUCCESS) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
- PoolFreeBuffer(Header);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Chain header at front of NDIS packet */
- NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
-
- IPPacket->Header = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
- IPPacket->HeaderSize = 20;
-
- /* Build IPv4 header */
- IPHeader = (PIPv4_HEADER)IPPacket->Header;
- /* Version = 4, Length = 5 DWORDs */
- IPHeader->VerIHL = 0x45;
- /* Normal Type-of-Service */
- IPHeader->Tos = 0;
- /* Length of header and data */
- IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
- /* Identification */
- IPHeader->Id = 0;
- /* One fragment at offset 0 */
- IPHeader->FlagsFragOfs = 0;
- /* Time-to-Live is 128 */
- IPHeader->Ttl = 128;
- /* User Datagram Protocol */
- IPHeader->Protocol = IPPROTO_UDP;
- /* Checksum is 0 (for later calculation of this) */
- IPHeader->Checksum = 0;
- /* Source address */
- IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
- /* Destination address. FIXME: IPv4 only */
- IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
-
- /* Build UDP header */
- UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
- /* Port values are already big-endian values */
- UDPHeader->SourcePort = LocalPort;
- UDPHeader->DestPort = SendRequest->RemotePort;
- /* FIXME: Calculate UDP checksum and put it in UDP header */
- UDPHeader->Checksum = 0;
- /* Length of UDP header and data */
- UDPHeader->Length = WH2N((USHORT)IPPacket->TotalSize - IPPacket->HeaderSize);
-
- return STATUS_SUCCESS;
+ Header = ExAllocatePool(NonPagedPool, BufferSize);
+ if (!Header) {
+ TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", BufferSize, Header));
+
+ /* Allocate NDIS buffer for maximum Link level, IP and UDP header */
+ NdisAllocateBuffer(&NdisStatus,
+ &HeaderBuffer,
+ GlobalBufferPool,
+ Header,
+ BufferSize);
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
+ ExFreePool(Header);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Chain header at front of NDIS packet */
+ NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
+
+ IPPacket->Header = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
+ IPPacket->HeaderSize = 20;
+
+ /* Build IPv4 header */
+ IPHeader = (PIPv4_HEADER)IPPacket->Header;
+ /* Version = 4, Length = 5 DWORDs */
+ IPHeader->VerIHL = 0x45;
+ /* Normal Type-of-Service */
+ IPHeader->Tos = 0;
+ /* Length of header and data */
+ IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
+ /* Identification */
+ IPHeader->Id = 0;
+ /* One fragment at offset 0 */
+ IPHeader->FlagsFragOfs = 0;
+ /* Time-to-Live is 128 */
+ IPHeader->Ttl = 128;
+ /* User Datagram Protocol */
+ IPHeader->Protocol = IPPROTO_UDP;
+ /* Checksum is 0 (for later calculation of this) */
+ IPHeader->Checksum = 0;
+ /* Source address */
+ IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
+ /* Destination address. FIXME: IPv4 only */
+ IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
+
+ /* Build UDP header */
+ UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
+ /* Port values are already big-endian values */
+ UDPHeader->SourcePort = LocalPort;
+ UDPHeader->DestPort = SendRequest->RemotePort;
+ /* FIXME: Calculate UDP checksum and put it in UDP header */
+ UDPHeader->Checksum = 0;
+ /* Length of UDP header and data */
+ UDPHeader->Length = WH2N((USHORT)IPPacket->TotalSize - IPPacket->HeaderSize);
+
+ return STATUS_SUCCESS;
}
NTSTATUS BuildUDPPacket(
- PVOID Context,
- PIP_ADDRESS LocalAddress,
- USHORT LocalPort,
- PIP_PACKET *IPPacket)
+ PVOID Context,
+ PIP_ADDRESS LocalAddress,
+ USHORT LocalPort,
+ PIP_PACKET *IPPacket)
/*
* FUNCTION: Builds an UDP packet
* ARGUMENTS:
* Status of operation
*/
{
- NTSTATUS Status;
- PIP_PACKET Packet;
- NDIS_STATUS NdisStatus;
- PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- /* Prepare packet */
- Packet = PoolAllocateBuffer(sizeof(IP_PACKET));
- if (!Packet) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlZeroMemory(Packet, sizeof(IP_PACKET));
- Packet->RefCount = 1;
- Packet->TotalSize = sizeof(IPv4_HEADER) +
- sizeof(UDP_HEADER) +
- SendRequest->BufferSize;
-
- /* Allocate NDIS packet */
- NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
- if (NdisStatus != NDIS_STATUS_SUCCESS) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus));
- PoolFreeBuffer(Packet);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- switch (SendRequest->RemoteAddress->Type) {
- case IP_ADDRESS_V4:
- Status = AddUDPHeaderIPv4(SendRequest, LocalAddress, LocalPort, Packet);
- break;
- case IP_ADDRESS_V6:
- /* FIXME: Support IPv6 */
- TI_DbgPrint(MIN_TRACE, ("IPv6 UDP datagrams are not supported.\n"));
- default:
- Status = STATUS_UNSUCCESSFUL;
- break;
- }
- if (!NT_SUCCESS(Status)) {
- TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", Status));
- NdisFreePacket(Packet->NdisPacket);
- PoolFreeBuffer(Packet);
- return Status;
- }
-
- /* Chain data after header */
- NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
-
- DISPLAY_IP_PACKET(Packet);
-
- *IPPacket = Packet;
-
- return STATUS_SUCCESS;
+ NTSTATUS Status;
+ PIP_PACKET Packet;
+ NDIS_STATUS NdisStatus;
+ PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ /* Prepare packet */
+
+ /* FIXME: Assumes IPv4 */
+ Packet = IPCreatePacket(IP_ADDRESS_V4);
+ if (!Packet)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Packet->TotalSize = sizeof(IPv4_HEADER) +
+ sizeof(UDP_HEADER) +
+ SendRequest->BufferSize;
+
+ /* Allocate NDIS packet */
+ NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus));
+ (*Packet->Free)(Packet);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ switch (SendRequest->RemoteAddress->Type) {
+ case IP_ADDRESS_V4:
+ Status = AddUDPHeaderIPv4(SendRequest, LocalAddress, LocalPort, Packet);
+ break;
+ case IP_ADDRESS_V6:
+ /* FIXME: Support IPv6 */
+ TI_DbgPrint(MIN_TRACE, ("IPv6 UDP datagrams are not supported.\n"));
+ default:
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
+ if (!NT_SUCCESS(Status)) {
+ TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", Status));
+ NdisFreePacket(Packet->NdisPacket);
+ (*Packet->Free)(Packet);
+ return Status;
+ }
+
+ /* Chain data after header */
+ NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
+
+ DISPLAY_IP_PACKET(Packet);
+
+ *IPPacket = Packet;
+
+ return STATUS_SUCCESS;
}
NTSTATUS UDPSendDatagram(
- PTDI_REQUEST Request,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PNDIS_BUFFER Buffer,
- ULONG DataSize)
+ PTDI_REQUEST Request,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PNDIS_BUFFER Buffer,
+ ULONG DataSize)
/*
* FUNCTION: Sends an UDP datagram to a remote address
* ARGUMENTS:
* Status of operation
*/
{
- return DGSendDatagram(Request,
- ConnInfo,
- Buffer,
- DataSize,
- BuildUDPPacket);
+ return DGSendDatagram(Request,
+ ConnInfo,
+ Buffer,
+ DataSize,
+ BuildUDPPacket);
}
* This is the high level interface for receiving UDP datagrams
*/
{
- return DGReceiveDatagram(Request,
- ConnInfo,
- Buffer,
- ReceiveLength,
- ReceiveFlags,
- ReturnInfo,
- BytesReceived);
+ return DGReceiveDatagram(Request,
+ ConnInfo,
+ Buffer,
+ ReceiveLength,
+ ReceiveFlags,
+ ReturnInfo,
+ BytesReceived);
}
VOID UDPReceive(
- PNET_TABLE_ENTRY NTE,
- PIP_PACKET IPPacket)
+ PNET_TABLE_ENTRY NTE,
+ PIP_PACKET IPPacket)
/*
- * FUNCTION: Receives and queues a UDP datagram
- * ARGUMENTS:
- * NTE = Pointer to net table entry which the packet was received on
- * IPPacket = Pointer to an IP packet that was received
- * NOTES:
- * This is the low level interface for receiving UDP datagrams. It strips
- * the UDP header from a packet and delivers the data to anyone that wants it
- */
+* FUNCTION: Receives and queues a UDP datagram
+* ARGUMENTS:
+* NTE = Pointer to net table entry which the packet was received on
+* IPPacket = Pointer to an IP packet that was received
+* NOTES:
+* This is the low level interface for receiving UDP datagrams. It strips
+* the UDP header from a packet and delivers the data to anyone that wants it
+*/
{
- AF_SEARCH SearchContext;
- PIPv4_HEADER IPv4Header;
- PADDRESS_FILE AddrFile;
- PUDP_HEADER UDPHeader;
- PIP_ADDRESS DstAddress;
- UINT DataSize, i;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- switch (IPPacket->Type) {
- /* IPv4 packet */
- case IP_ADDRESS_V4:
- IPv4Header = IPPacket->Header;
- DstAddress = &IPPacket->DstAddr;
- break;
-
- /* IPv6 packet */
- case IP_ADDRESS_V6:
- TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 UDP datagram (%i bytes).\n", IPPacket->TotalSize));
-
- /* FIXME: IPv6 is not supported */
- return;
-
- default:
- return;
- }
-
- UDPHeader = (PUDP_HEADER)IPPacket->Data;
-
- /* FIXME: Calculate and validate UDP checksum */
-
- /* Sanity checks */
- i = WH2N(UDPHeader->Length);
- if ((i < sizeof(UDP_HEADER)) || (i > IPPacket->TotalSize - IPPacket->Position)) {
- /* Incorrect or damaged packet received, discard it */
- TI_DbgPrint(MIN_TRACE, ("Incorrect or damaged UDP packet received.\n"));
- return;
- }
-
- DataSize = i - sizeof(UDP_HEADER);
-
- /* Go to UDP data area */
- (ULONG_PTR)IPPacket->Data += sizeof(UDP_HEADER);
-
- /* Locate a receive request on destination address file object
- and deliver the packet if one is found. If there is no receive
- request on the address file object, call the associated receive
- handler. If no receive handler is registered, drop the packet */
-
- AddrFile = AddrSearchFirst(DstAddress,
- UDPHeader->DestPort,
- IPPROTO_UDP,
- &SearchContext);
- if (AddrFile) {
- do {
- DGDeliverData(AddrFile,
- DstAddress,
- IPPacket,
- DataSize);
- } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
- } else {
- /* There are no open address files that will take this datagram */
- /* FIXME: IPv4 only */
- TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 UDP datagram to address (0x%X).\n",
- DN2H(DstAddress->Address.IPv4Address)));
-
- /* FIXME: Send ICMP reply */
- }
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ AF_SEARCH SearchContext;
+ PIPv4_HEADER IPv4Header;
+ PADDRESS_FILE AddrFile;
+ PUDP_HEADER UDPHeader;
+ PIP_ADDRESS DstAddress;
+ UINT DataSize, i;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ switch (IPPacket->Type) {
+ /* IPv4 packet */
+ case IP_ADDRESS_V4:
+ IPv4Header = IPPacket->Header;
+ DstAddress = &IPPacket->DstAddr;
+ break;
+
+ /* IPv6 packet */
+ case IP_ADDRESS_V6:
+ TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 UDP datagram (%i bytes).\n", IPPacket->TotalSize));
+
+ /* FIXME: IPv6 is not supported */
+ return;
+
+ default:
+ return;
+ }
+
+ UDPHeader = (PUDP_HEADER)IPPacket->Data;
+
+ /* FIXME: Calculate and validate UDP checksum */
+
+ /* Sanity checks */
+ i = WH2N(UDPHeader->Length);
+ if ((i < sizeof(UDP_HEADER)) || (i > IPPacket->TotalSize - IPPacket->Position)) {
+ /* Incorrect or damaged packet received, discard it */
+ TI_DbgPrint(MIN_TRACE, ("Incorrect or damaged UDP packet received.\n"));
+ return;
+ }
+
+ DataSize = i - sizeof(UDP_HEADER);
+
+ /* Go to UDP data area */
+ (ULONG_PTR)IPPacket->Data += sizeof(UDP_HEADER);
+
+ /* Locate a receive request on destination address file object
+ and deliver the packet if one is found. If there is no receive
+ request on the address file object, call the associated receive
+ handler. If no receive handler is registered, drop the packet */
+
+ AddrFile = AddrSearchFirst(DstAddress,
+ UDPHeader->DestPort,
+ IPPROTO_UDP,
+ &SearchContext);
+ if (AddrFile) {
+ do {
+ DGDeliverData(AddrFile,
+ DstAddress,
+ IPPacket,
+ DataSize);
+ } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
+ } else {
+ /* There are no open address files that will take this datagram */
+ /* FIXME: IPv4 only */
+ TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 UDP datagram to address (0x%X).\n",
+ DN2H(DstAddress->Address.IPv4Address)));
+
+ /* FIXME: Send ICMP reply */
+ }
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
NTSTATUS UDPStartup(
- VOID)
+ VOID)
/*
* FUNCTION: Initializes the UDP subsystem
* RETURNS:
* Status of operation
*/
{
- RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
+ RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
- /* Register this protocol with IP layer */
- IPRegisterProtocol(IPPROTO_UDP, UDPReceive);
+ /* Register this protocol with IP layer */
+ IPRegisterProtocol(IPPROTO_UDP, UDPReceive);
- UDPInitialized = TRUE;
+ UDPInitialized = TRUE;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
NTSTATUS UDPShutdown(
- VOID)
+ VOID)
/*
* FUNCTION: Shuts down the UDP subsystem
* RETURNS:
* Status of operation
*/
{
- if (!UDPInitialized)
- return STATUS_SUCCESS;
+ if (!UDPInitialized)
+ return STATUS_SUCCESS;
- /* Deregister this protocol with IP layer */
- IPRegisterProtocol(IPPROTO_UDP, NULL);
+ /* Deregister this protocol with IP layer */
+ IPRegisterProtocol(IPPROTO_UDP, NULL);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/* EOF */
#ifdef NASSERT
#define ASSERT(x)
#else /* NASSERT */
-#define ASSERT(x) if (!(x)) { WSH_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
+#define ASSERT(x) if (!(x)) { WSH_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); ExitProcess(0); }
#endif /* NASSERT */
-#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
-
#else /* DBG */
#define WSH_DbgPrint(_t_, _x_)
-#define ASSERT_IRQL(x)
#define ASSERT(x)
#endif /* DBG */
WSH_DbgPrint(MAX_TRACE, ("\n"));
- /* FIXME: Raw IP only. Support UDP and TCP */
- ASSERT(*SocketType == SOCK_RAW);
+ switch (*SocketType) {
+ case SOCK_STREAM:
+ RtlInitUnicodeString(&String, DD_TCP_DEVICE_NAME);
+ break;
- if (*Protocol < 0 || *Protocol > 255)
- return WSAEINVAL;
+ case SOCK_DGRAM:
+ RtlInitUnicodeString(&String, DD_UDP_DEVICE_NAME);
+ break;
- RtlInitUnicodeString(&String, DD_RAW_IP_DEVICE_NAME);
+ case SOCK_RAW:
+ if ((*Protocol < 0) || (*Protocol > 255))
+ return WSAEINVAL;
+
+ RtlInitUnicodeString(&String, DD_RAW_IP_DEVICE_NAME);
+ break;
+
+ default:
+ return WSAEINVAL;
+ }
RtlInitUnicodeString(TransportDeviceName, NULL);
/* Append the transport device name */
Status = RtlAppendUnicodeStringToString(TransportDeviceName, &String);
- /* Append a separator */
- TransportDeviceName->Buffer[TransportDeviceName->Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
- TransportDeviceName->Length += sizeof(WCHAR);
- TransportDeviceName->Buffer[TransportDeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ if (*SocketType == SOCK_RAW) {
+ /* Append a separator */
+ TransportDeviceName->Buffer[TransportDeviceName->Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
+ TransportDeviceName->Length += sizeof(WCHAR);
+ TransportDeviceName->Buffer[TransportDeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
- /* Append the protocol number */
- String.Buffer = TransportDeviceName->Buffer + (TransportDeviceName->Length / sizeof(WCHAR));
- String.Length = 0;
- String.MaximumLength = TransportDeviceName->MaximumLength - TransportDeviceName->Length;
+ /* Append the protocol number */
+ String.Buffer = TransportDeviceName->Buffer + (TransportDeviceName->Length / sizeof(WCHAR));
+ String.Length = 0;
+ String.MaximumLength = TransportDeviceName->MaximumLength - TransportDeviceName->Length;
- Status = RtlIntegerToUnicodeString((ULONG)*Protocol, 10, &String);
+ Status = RtlIntegerToUnicodeString((ULONG)*Protocol, 10, &String);
- TransportDeviceName->Length += String.Length;
+ TransportDeviceName->Length += String.Length;
+ }
/* Setup a socket context area */
#define AFD_SOCKET_LENGTH (sizeof(AfdSocket) - 1)
typedef struct _AFD_SOCKET_INFORMATION {
- BOOL CommandChannel;
- INT AddressFamily;
- INT SocketType;
- INT Protocol;
- PVOID HelperContext;
- DWORD NotificationEvents;
- UNICODE_STRING TdiDeviceName;
- SOCKADDR Name;
-} AFD_SOCKET_INFORMATION, *PAFD_SOCKET_INFORMATION;
+ BOOL CommandChannel;
+ INT AddressFamily;
+ INT SocketType;
+ INT Protocol;
+ PVOID HelperContext;
+ DWORD NotificationEvents;
+ UNICODE_STRING TdiDeviceName;
+ SOCKADDR Name;
+} __attribute__((packed)) AFD_SOCKET_INFORMATION, *PAFD_SOCKET_INFORMATION;
/* AFD IOCTL code definitions */
#define FSCTL_AFD_BASE FILE_DEVICE_NAMED_PIPE // ???
#define AFD_CTL_CODE(Function, Method, Access) \
- CTL_CODE(FSCTL_AFD_BASE, Function, Method, Access)
+ CTL_CODE(FSCTL_AFD_BASE, Function, Method, Access)
#define IOCTL_AFD_BIND \
- AFD_CTL_CODE(0, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ AFD_CTL_CODE(0, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_LISTEN \
- AFD_CTL_CODE(1, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ AFD_CTL_CODE(1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_SENDTO \
- AFD_CTL_CODE(2, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ AFD_CTL_CODE(2, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_RECVFROM \
- AFD_CTL_CODE(3, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ AFD_CTL_CODE(3, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_AFD_SELECT \
- AFD_CTL_CODE(4, METHOD_BUFFERED, FILE_ANY_ACCESS)
+ AFD_CTL_CODE(4, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AFD_EVENTSELECT \
+ AFD_CTL_CODE(5, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AFD_ENUMNETWORKEVENTS \
+ AFD_CTL_CODE(6, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AFD_RECV \
+ AFD_CTL_CODE(7, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AFD_SEND \
+ AFD_CTL_CODE(8, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AFD_ACCEPT \
+ AFD_CTL_CODE(9, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_AFD_CONNECT \
+ AFD_CTL_CODE(10, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
typedef struct _FILE_REQUEST_BIND {
- SOCKADDR Name;
-} FILE_REQUEST_BIND, *PFILE_REQUEST_BIND;
+ SOCKADDR Name;
+} __attribute__((packed)) FILE_REQUEST_BIND, *PFILE_REQUEST_BIND;
typedef struct _FILE_REPLY_BIND {
- INT Status;
- HANDLE TdiAddressObjectHandle;
- HANDLE TdiConnectionObjectHandle;
-} FILE_REPLY_BIND, *PFILE_REPLY_BIND;
+ INT Status;
+ HANDLE TdiAddressObjectHandle;
+ HANDLE TdiConnectionObjectHandle;
+} __attribute__((packed)) FILE_REPLY_BIND, *PFILE_REPLY_BIND;
typedef struct _FILE_REQUEST_LISTEN {
- INT Backlog;
-} FILE_REQUEST_LISTEN, *PFILE_REQUEST_LISTEN;
+ INT Backlog;
+} __attribute__((packed)) FILE_REQUEST_LISTEN, *PFILE_REQUEST_LISTEN;
typedef struct _FILE_REPLY_LISTEN {
- INT Status;
-} FILE_REPLY_LISTEN, *PFILE_REPLY_LISTEN;
+ INT Status;
+} __attribute__((packed)) FILE_REPLY_LISTEN, *PFILE_REPLY_LISTEN;
typedef struct _FILE_REQUEST_SENDTO {
- LPWSABUF Buffers;
- DWORD BufferCount;
- DWORD Flags;
- SOCKADDR To;
- INT ToLen;
-} FILE_REQUEST_SENDTO, *PFILE_REQUEST_SENDTO;
+ LPWSABUF Buffers;
+ DWORD BufferCount;
+ DWORD Flags;
+ SOCKADDR To;
+ INT ToLen;
+} __attribute__((packed)) FILE_REQUEST_SENDTO, *PFILE_REQUEST_SENDTO;
typedef struct _FILE_REPLY_SENDTO {
- INT Status;
- DWORD NumberOfBytesSent;
-} FILE_REPLY_SENDTO, *PFILE_REPLY_SENDTO;
+ INT Status;
+ DWORD NumberOfBytesSent;
+} __attribute__((packed)) FILE_REPLY_SENDTO, *PFILE_REPLY_SENDTO;
typedef struct _FILE_REQUEST_RECVFROM {
- LPWSABUF Buffers;
- DWORD BufferCount;
- LPDWORD Flags;
- LPSOCKADDR From;
- LPINT FromLen;
-} FILE_REQUEST_RECVFROM, *PFILE_REQUEST_RECVFROM;
+ LPWSABUF Buffers;
+ DWORD BufferCount;
+ LPDWORD Flags;
+ LPSOCKADDR From;
+ LPINT FromLen;
+} __attribute__((packed)) FILE_REQUEST_RECVFROM, *PFILE_REQUEST_RECVFROM;
typedef struct _FILE_REPLY_RECVFROM {
- INT Status;
- DWORD NumberOfBytesRecvd;
-} FILE_REPLY_RECVFROM, *PFILE_REPLY_RECVFROM;
+ INT Status;
+ DWORD NumberOfBytesRecvd;
+} __attribute__((packed)) FILE_REPLY_RECVFROM, *PFILE_REPLY_RECVFROM;
typedef struct _FILE_REQUEST_SELECT {
- LPFD_SET ReadFDSet;
- LPFD_SET WriteFDSet;
- LPFD_SET ExceptFDSet;
- TIMEVAL Timeout;
-} FILE_REQUEST_SELECT, *PFILE_REQUEST_SELECT;
+ LPFD_SET ReadFDSet;
+ LPFD_SET WriteFDSet;
+ LPFD_SET ExceptFDSet;
+ TIMEVAL Timeout;
+} __attribute__((packed)) FILE_REQUEST_SELECT, *PFILE_REQUEST_SELECT;
typedef struct _FILE_REPLY_SELECT {
- INT Status;
- DWORD SocketCount;
-} FILE_REPLY_SELECT, *PFILE_REPLY_SELECT;
+ INT Status;
+ DWORD SocketCount;
+} __attribute__((packed)) FILE_REPLY_SELECT, *PFILE_REPLY_SELECT;
+
+
+typedef struct _FILE_REQUEST_EVENTSELECT {
+ WSAEVENT hEventObject;
+ LONG lNetworkEvents;
+} __attribute__((packed)) FILE_REQUEST_EVENTSELECT, *PFILE_REQUEST_EVENTSELECT;
+
+typedef struct _FILE_REPLY_EVENTSELECT {
+ INT Status;
+} __attribute__((packed)) FILE_REPLY_EVENTSELECT, *PFILE_REPLY_EVENTSELECT;
+
+
+typedef struct _FILE_REQUEST_ENUMNETWORKEVENTS {
+ WSAEVENT hEventObject;
+} __attribute__((packed)) FILE_REQUEST_ENUMNETWORKEVENTS, *PFILE_REQUEST_ENUMNETWORKEVENTS;
+
+typedef struct _FILE_REPLY_ENUMNETWORKEVENTS {
+ INT Status;
+ WSANETWORKEVENTS NetworkEvents;
+} __attribute__((packed)) FILE_REPLY_ENUMNETWORKEVENTS, *PFILE_REPLY_ENUMNETWORKEVENTS;
+
+
+typedef struct _FILE_REQUEST_RECV {
+ LPWSABUF Buffers;
+ DWORD BufferCount;
+ LPDWORD Flags;
+} __attribute__((packed)) FILE_REQUEST_RECV, *PFILE_REQUEST_RECV;
+
+typedef struct _FILE_REPLY_RECV {
+ INT Status;
+ DWORD NumberOfBytesRecvd;
+} __attribute__((packed)) FILE_REPLY_RECV, *PFILE_REPLY_RECV;
+
+
+typedef struct _FILE_REQUEST_SEND {
+ LPWSABUF Buffers;
+ DWORD BufferCount;
+ DWORD Flags;
+} __attribute__((packed)) FILE_REQUEST_SEND, *PFILE_REQUEST_SEND;
+
+typedef struct _FILE_REPLY_SEND {
+ INT Status;
+ DWORD NumberOfBytesSent;
+} __attribute__((packed)) FILE_REPLY_SEND, *PFILE_REPLY_SEND;
+
+
+typedef struct _FILE_REQUEST_ACCEPT {
+ LPSOCKADDR addr;
+ INT addrlen;
+ LPCONDITIONPROC lpfnCondition;
+ DWORD dwCallbackData;
+} __attribute__((packed)) FILE_REQUEST_ACCEPT, *PFILE_REQUEST_ACCEPT;
+
+typedef struct _FILE_REPLY_ACCEPT {
+ INT Status;
+ INT addrlen;
+ SOCKET Socket;
+} __attribute__((packed)) FILE_REPLY_ACCEPT, *PFILE_REPLY_ACCEPT;
+
+
+typedef struct _FILE_REQUEST_CONNECT {
+ LPSOCKADDR name;
+ INT namelen;
+ LPWSABUF lpCallerData;
+ LPWSABUF lpCalleeData;
+ LPQOS lpSQOS;
+ LPQOS lpGQOS;
+} __attribute__((packed)) FILE_REQUEST_CONNECT, *PFILE_REQUEST_CONNECT;
+
+typedef struct _FILE_REPLY_CONNECT {
+ INT Status;
+} __attribute__((packed)) FILE_REPLY_CONNECT, *PFILE_REPLY_CONNECT;
#endif /*__AFD_SHARED_H */
BOOLEAN Wait
);
-/*
- * PVOID
- * ExAllocateFromNPagedLookasideList (
- * PNPAGED_LOOKASIDE_LIST LookSide
- * );
- *
- * FUNCTION:
- * Removes (pops) the first entry from the specified nonpaged
- * lookaside list.
- *
- * ARGUMENTS:
- * Lookaside = Pointer to a nonpaged lookaside list
- *
- * RETURNS:
- * Address of the allocated list entry
- */
-static
-inline
-PVOID
-ExAllocateFromNPagedLookasideList (
- IN PNPAGED_LOOKASIDE_LIST Lookaside
- )
-{
-#if 0
- PVOID Entry;
-
- Lookaside->TotalAllocates++;
- Entry = ExInterlockedPopEntrySList (&Lookaside->ListHead,
- &Lookaside->Lock);
- if (Entry == NULL)
- {
- Lookaside->AllocateMisses++;
- Entry = (Lookaside->Allocate)(Lookaside->Type,
- Lookaside->Size,
- Lookaside->Tag);
- }
-
- return Entry;
-#endif
- return NULL;
-}
-
-PVOID
-STDCALL
-ExAllocateFromPagedLookasideList (
- PPAGED_LOOKASIDE_LIST LookSide
- );
PVOID
STDCALL
ExAllocateFromZone (
IN BOOLEAN AllowMultipleCallbacks
);
-VOID
-STDCALL
-ExDeleteNPagedLookasideList (
- PNPAGED_LOOKASIDE_LIST Lookaside
- );
-VOID
-STDCALL
-ExDeletePagedLookasideList (
- PPAGED_LOOKASIDE_LIST Lookaside
- );
NTSTATUS
STDCALL
ExDeleteResource (
PVOID block
);
-/*
- * VOID
- * ExFreeToNPagedLookasideList (
- * PNPAGED_LOOKASIDE_LIST Lookaside,
- * PVOID Entry
- * );
- *
- * FUNCTION:
- * Inserts (pushes) the specified entry into the specified
- * nonpaged lookaside list.
- *
- * ARGUMENTS:
- * Lookaside = Pointer to the nonpaged lookaside list
- * Entry = Pointer to the entry that is inserted in the lookaside list
- */
-static
-inline
-VOID
-ExFreeToNPagedLookasideList (
- IN PNPAGED_LOOKASIDE_LIST Lookaside,
- IN PVOID Entry
- )
-{
-#if 0
- Lookaside->TotalFrees++;
- if (ExQueryDepthSList (&Lookaside->ListHead) >= Lookaside->Depth)
- {
- Lookaside->FreeMisses++;
- (Lookaside->Free)(Entry);
- }
- else
- {
- ExInterlockedPushEntrySList (&Lookaside->ListHead,
- (PSINGLE_LIST_ENTRY)Entry,
- &Lookaside->Lock);
- }
-#endif
-}
-
-VOID
-STDCALL
-ExFreeToPagedLookasideList (
- PPAGED_LOOKASIDE_LIST Lookaside,
- PVOID Entry
- );
-
/*
* PVOID
* ExFreeToZone (
* );
*/
#define ExInitializeFastMutex(_FastMutex) \
- (_FastMutex)->Count = 1; \
- (_FastMutex)->Owner = NULL; \
- (_FastMutex)->Contention = 0; \
- KeInitializeEvent(&(_FastMutex)->Event, \
+ ((PFAST_MUTEX)_FastMutex)->Count = 1; \
+ ((PFAST_MUTEX)_FastMutex)->Owner = NULL; \
+ ((PFAST_MUTEX)_FastMutex)->Contention = 0; \
+ KeInitializeEvent(&((PFAST_MUTEX)_FastMutex)->Event, \
SynchronizationEvent, \
FALSE);
-VOID
-STDCALL
-ExInitializeNPagedLookasideList (
- PNPAGED_LOOKASIDE_LIST Lookaside,
- PALLOCATE_FUNCTION Allocate,
- PFREE_FUNCTION Free,
- ULONG Flags,
- ULONG Size,
- ULONG Tag,
- USHORT Depth
- );
-VOID
-STDCALL
-ExInitializePagedLookasideList (
- PPAGED_LOOKASIDE_LIST Lookaside,
- PALLOCATE_FUNCTION Allocate,
- PFREE_FUNCTION Free,
- ULONG Flags,
- ULONG Size,
- ULONG Tag,
- USHORT Depth
- );
NTSTATUS
STDCALL
ExInitializeResource (
/*
* USHORT
- * ExQueryDepthSListHead (
+ * ExQueryDepthSList (
* PSLIST_HEADER SListHead
* );
-*/
-#define ExQueryDepthSListHead(ListHead) \
- (USHORT)(ListHead)->Depth
+ */
+#define ExQueryDepthSList(ListHead) \
+ (USHORT)(ListHead)->s.Depth
VOID
STDCALL
IN PVOID CallbackRegistration
);
+
+/*
+ * PVOID
+ * ExAllocateFromNPagedLookasideList (
+ * PNPAGED_LOOKASIDE_LIST LookSide
+ * );
+ *
+ * FUNCTION:
+ * Removes (pops) the first entry from the specified nonpaged
+ * lookaside list.
+ *
+ * ARGUMENTS:
+ * Lookaside = Pointer to a nonpaged lookaside list
+ *
+ * RETURNS:
+ * Address of the allocated list entry
+ */
+static
+inline
+PVOID
+ExAllocateFromNPagedLookasideList (
+ IN PNPAGED_LOOKASIDE_LIST Lookaside
+ )
+{
+ PVOID Entry;
+
+ Lookaside->TotalAllocates++;
+ Entry = ExInterlockedPopEntrySList (&Lookaside->ListHead,
+ &Lookaside->Lock);
+ if (Entry == NULL)
+ {
+ Lookaside->AllocateMisses++;
+ Entry = (Lookaside->Allocate)(Lookaside->Type,
+ Lookaside->Size,
+ Lookaside->Tag);
+ }
+
+ return Entry;
+}
+
+PVOID
+STDCALL
+ExAllocateFromPagedLookasideList (
+ PPAGED_LOOKASIDE_LIST LookSide
+ );
+
+VOID
+STDCALL
+ExDeleteNPagedLookasideList (
+ PNPAGED_LOOKASIDE_LIST Lookaside
+ );
+
+VOID
+STDCALL
+ExDeletePagedLookasideList (
+ PPAGED_LOOKASIDE_LIST Lookaside
+ );
+
+
+/*
+ * VOID
+ * ExFreeToNPagedLookasideList (
+ * PNPAGED_LOOKASIDE_LIST Lookaside,
+ * PVOID Entry
+ * );
+ *
+ * FUNCTION:
+ * Inserts (pushes) the specified entry into the specified
+ * nonpaged lookaside list.
+ *
+ * ARGUMENTS:
+ * Lookaside = Pointer to the nonpaged lookaside list
+ * Entry = Pointer to the entry that is inserted in the lookaside list
+ */
+static
+inline
+VOID
+ExFreeToNPagedLookasideList (
+ IN PNPAGED_LOOKASIDE_LIST Lookaside,
+ IN PVOID Entry
+ )
+{
+ Lookaside->TotalFrees++;
+ if (ExQueryDepthSList (&Lookaside->ListHead) >= Lookaside->MinimumDepth)
+ {
+ Lookaside->FreeMisses++;
+ (Lookaside->Free)(Entry);
+ }
+ else
+ {
+ ExInterlockedPushEntrySList (&Lookaside->ListHead,
+ (PSINGLE_LIST_ENTRY)Entry,
+ &Lookaside->Lock);
+ }
+}
+
+VOID
+STDCALL
+ExFreeToPagedLookasideList (
+ PPAGED_LOOKASIDE_LIST Lookaside,
+ PVOID Entry
+ );
+
+VOID
+STDCALL
+ExInitializeNPagedLookasideList (
+ PNPAGED_LOOKASIDE_LIST Lookaside,
+ PALLOCATE_FUNCTION Allocate,
+ PFREE_FUNCTION Free,
+ ULONG Flags,
+ ULONG Size,
+ ULONG Tag,
+ USHORT Depth
+ );
+VOID
+STDCALL
+ExInitializePagedLookasideList (
+ PPAGED_LOOKASIDE_LIST Lookaside,
+ PALLOCATE_FUNCTION Allocate,
+ PFREE_FUNCTION Free,
+ ULONG Flags,
+ ULONG Size,
+ ULONG Tag,
+ USHORT Depth
+ );
+
+
/*
LONG
FASTCALL
-/* $Id: extypes.h,v 1.4 2000/07/04 01:25:27 ekohl Exp $ */
+/* $Id: extypes.h,v 1.5 2001/07/04 20:40:18 chorns Exp $ */
#ifndef __INCLUDE_DDK_EXTYPES_H
#define __INCLUDE_DDK_EXTYPES_H
} s;
} SLIST_HEADER, *PSLIST_HEADER;
-typedef struct
+typedef struct _NPAGED_LOOKASIDE_LIST
{
SLIST_HEADER ListHead;
- USHORT Depth;
- USHORT Pad;
+ USHORT MinimumDepth;
+ USHORT MaximumDepth;
ULONG TotalAllocates;
ULONG AllocateMisses;
ULONG TotalFrees;
- ULONG TotalMisses;
+ ULONG FreeMisses;
POOL_TYPE Type;
ULONG Tag;
ULONG Size;
PALLOCATE_FUNCTION Allocate;
PFREE_FUNCTION Free;
LIST_ENTRY ListEntry;
+ ULONG LastTotalAllocates;
+ ULONG LastAllocateMisses;
+ ULONG Pad[2];
KSPIN_LOCK Lock;
} NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST;
-typedef struct
+typedef struct _PAGED_LOOKASIDE_LIST
{
SLIST_HEADER ListHead;
- USHORT Depth;
- USHORT Pad;
+ USHORT MinimumDepth;
+ USHORT MaximumDepth;
ULONG TotalAllocates;
ULONG AllocateMisses;
ULONG TotalFrees;
- ULONG TotalMisses;
+ ULONG FreeMisses;
POOL_TYPE Type;
ULONG Tag;
ULONG Size;
PALLOCATE_FUNCTION Allocate;
PFREE_FUNCTION Free;
LIST_ENTRY ListEntry;
+ ULONG LastTotalAllocates;
+ ULONG LastAllocateMisses;
FAST_MUTEX Lock;
} PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST;
-/* $Id: rtl.h,v 1.54 2001/06/25 12:31:00 ekohl Exp $
+/* $Id: rtl.h,v 1.55 2001/07/04 20:40:18 chorns Exp $
*
*/
static
inline
PSINGLE_LIST_ENTRY
-PopEntryList (
+ PopEntryList(
PSINGLE_LIST_ENTRY ListHead
)
{
return ListEntry;
}
-
/*
VOID
PushEntryList (
}
+/*
+ * An ReactOS extension
+ */
+static
+inline
+PSINGLE_LIST_ENTRY
+ PopEntrySList(
+ PSLIST_HEADER ListHead
+ )
+{
+ PSINGLE_LIST_ENTRY ListEntry;
+
+ ListEntry = ListHead->s.Next.Next;
+ if (ListEntry!=NULL)
+ {
+ ListHead->s.Next.Next = ListEntry->Next;
+ ListHead->s.Depth++;
+ ListHead->s.Sequence++;
+ }
+ return ListEntry;
+}
+
+
+/*
+ * An ReactOS extension
+ */
+static
+inline
+VOID
+PushEntrySList (
+ PSLIST_HEADER ListHead,
+ PSINGLE_LIST_ENTRY Entry
+ )
+{
+ Entry->Next = ListHead->s.Next.Next;
+ ListHead->s.Next.Next = Entry;
+ ListHead->s.Depth++;
+ ListHead->s.Sequence++;
+}
+
+
/*
*VOID
*RemoveEntryList (
ULONG ImageSubSystemMajorVersion; // B8h
ULONG ImageSubSystemMinorVersion; // C0h
ULONG GdiHandleBuffer[0x22]; // C4h
-
- PVOID ProcessWindowStation; // ???
} PEB, *PPEB;
PVOID StackCommit; // F88h
PVOID StackCommitMax; // F8Ch
PVOID StackReserve; // F90h
-
- PVOID MessageQueue; // ???
} NT_TEB, *PNT_TEB;
#define PEB_STARTUPINFO (0xb0003000)
copy services\fs\vfat\vfatfs.sys %ROS_INSTALL%
copy services\fs\ms\msfs.sys %ROS_INSTALL%\system32\drivers
copy services\fs\np\npfs.sys %ROS_INSTALL%\system32\drivers
-copy services\bus\acpi\acpi.sys %ROS_INSTALL%
-copy services\bus\isapnp\isapnp.sys %ROS_INSTALL%
+copy services\bus\acpi\acpi.sys %ROS_INSTALL%\system32\drivers
+copy services\bus\isapnp\isapnp.sys %ROS_INSTALL%\system32\drivers
copy services\dd\ide\ide.sys %ROS_INSTALL%
copy services\dd\floppy\floppy.sys %ROS_INSTALL%\system32\drivers
copy services\input\keyboard\keyboard.sys %ROS_INSTALL%\system32\drivers
copy services\dd\vga\miniport\vgamp.sys %ROS_INSTALL%\system32\drivers
copy services\dd\vga\display\vgaddi.dll %ROS_INSTALL%\system32\drivers
copy services\dd\vidport\vidport.sys %ROS_INSTALL%\system32\drivers
+copy services\net\afd\afd.sys %ROS_INSTALL%\system32\drivers
+copy services\net\dd\ne2000\ne2000.sys %ROS_INSTALL%\system32\drivers
+copy services\net\ndis\ndis.sys %ROS_INSTALL%\system32\drivers
+copy services\net\tcpip\tcpip.sys %ROS_INSTALL%\system32\drivers
+copy services\net\wshtcpip\wshtcpip.dll %ROS_INSTALL%\system32
copy apps\system\shell\shell.exe %ROS_INSTALL%\system32
copy apps\system\winlogon\winlogon.exe %ROS_INSTALL%\system32
copy apps\system\services\services.exe %ROS_INSTALL%\system32
-copy lib\ntdll\ntdll.dll %ROS_INSTALL%\system32
-copy lib\kernel32\kernel32.dll %ROS_INSTALL%\system32
+copy lib\advapi32\advapi32.dll %ROS_INSTALL%\system32
copy lib\crtdll\crtdll.dll %ROS_INSTALL%\system32
copy lib\fmifs\fmifs.dll %ROS_INSTALL%\system32
copy lib\gdi32\gdi32.dll %ROS_INSTALL%\system32
-copy lib\advapi32\advapi32.dll %ROS_INSTALL%\system32
+copy lib\kernel32\kernel32.dll %ROS_INSTALL%\system32
+copy lib\msafd\msafd.dll %ROS_INSTALL%\system32
copy lib\msvcrt\msvcrt.dll %ROS_INSTALL%\system32
+copy lib\ntdll\ntdll.dll %ROS_INSTALL%\system32
+copy lib\secur32\secur32.dll %ROS_INSTALL%\system32
copy lib\user32\user32.dll %ROS_INSTALL%\system32
+copy lib\ws2_32\ws2_32.dll %ROS_INSTALL%\system32
copy apps\hello\hello.exe %ROS_INSTALL%\bin
copy apps\args\args.exe %ROS_INSTALL%\bin
copy apps\cat\cat.exe %ROS_INSTALL%\bin
copy apps\nptest\npserver.exe %ROS_INSTALL%\bin
copy apps\nptest\npclient.exe %ROS_INSTALL%\bin
copy apps\atomtest\atomtest.exe %ROS_INSTALL%\bin
+copy apps\net\ping\ping.exe %ROS_INSTALL%\bin
+copy apps\net\roshttpd\roshttpd.exe %ROS_INSTALL%\bin
+copy apps\net\telnet\telnet.exe %ROS_INSTALL%\bin
copy media\fonts\helb____.ttf %ROS_INSTALL%\media\fonts
copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts
TARGETNAME=msafd
-MISC_OBJECTS = misc/dllmain.o misc/helpers.o misc/sndrcv.o misc/stubs.o
+MISC_OBJECTS = misc/dllmain.o misc/event.o misc/helpers.o \
+ misc/sndrcv.o misc/stubs.o
RESOURCE_OBJECT = $(TARGETNAME).coff
AFD_SOCKET_LENGTH);
EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION);
- SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + AFD_SOCKET_LENGTH);
+ SocketInfo = (PAFD_SOCKET_INFORMATION)((ULONG_PTR)EaInfo->EaName + AFD_SOCKET_LENGTH);
SocketInfo->CommandChannel = FALSE;
SocketInfo->AddressFamily = AddressFamily;
SocketInfo->SocketType = SocketType;
&HelperContext,
&NotificationEvents);
if (Status != NO_ERROR) {
+ AFD_DbgPrint(MAX_TRACE, ("WinSock Helper DLL failed (0x%X).\n", Status));
*lpErrno = Status;
return INVALID_SOCKET;
}
* 0, or SOCKET_ERROR if the socket could not be bound
*/
{
- AFD_DbgPrint(MAX_TRACE, ("s (0x%X) name (0x%X) namelen (%d).\n", s, name, namelen));
-
-#if 0
FILE_REQUEST_BIND Request;
FILE_REPLY_BIND Reply;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
+ AFD_DbgPrint(MAX_TRACE, ("s (0x%X) name (0x%X) namelen (%d).\n", s, name, namelen));
+
RtlCopyMemory(&Request.Name, name, sizeof(SOCKADDR));
Status = NtDeviceIoControlFile(
sizeof(FILE_REQUEST_BIND),
&Reply,
sizeof(FILE_REPLY_BIND));
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
- if (Status == STATUS_PENDING) {
- if (!NT_SUCCESS(NtWaitForSingleObject((HANDLE)s, FALSE, NULL))) {
- /* FIXME: What error code should be returned? */
- *lpErrno = WSAENOBUFS;
- return SOCKET_ERROR;
- }
+ if (!NT_SUCCESS(Status)) {
+ *lpErrno = Reply.Status;
+ return SOCKET_ERROR;
+ }
+
+ return 0;
+}
+
+INT
+WSPAPI
+WSPListen(
+ IN SOCKET s,
+ IN INT backlog,
+ OUT LPINT lpErrno)
+/*
+ * FUNCTION: Listens for incoming connections
+ * ARGUMENTS:
+ * s = Socket descriptor
+ * backlog = Maximum number of pending connection requests
+ * lpErrno = Address of buffer for error information
+ * RETURNS:
+ * 0, or SOCKET_ERROR if the socket could not be bound
+ */
+{
+ FILE_REQUEST_LISTEN Request;
+ FILE_REPLY_LISTEN Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+
+ AFD_DbgPrint(MAX_TRACE, ("s (0x%X) backlog (%d).\n", s, backlog));
+
+ Request.Backlog = backlog;
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_LISTEN,
+ &Request,
+ sizeof(FILE_REQUEST_LISTEN),
+ &Reply,
+ sizeof(FILE_REPLY_LISTEN));
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
}
if (!NT_SUCCESS(Status)) {
- *lpErrno = WSAENOBUFS;
+ *lpErrno = Reply.Status;
return SOCKET_ERROR;
}
-#endif
- return 0;
+
+ return 0;
}
return Reply.SocketCount;
}
+SOCKET
+WSPAPI
+WSPAccept(
+ IN SOCKET s,
+ OUT LPSOCKADDR addr,
+ IN OUT LPINT addrlen,
+ IN LPCONDITIONPROC lpfnCondition,
+ IN DWORD dwCallbackData,
+ OUT LPINT lpErrno)
+{
+ FILE_REQUEST_ACCEPT Request;
+ FILE_REPLY_ACCEPT Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+
+ AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
+
+ Request.addr = addr;
+ Request.addrlen = *addrlen;
+ Request.lpfnCondition = lpfnCondition;
+ Request.dwCallbackData = dwCallbackData;
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_ACCEPT,
+ &Request,
+ sizeof(FILE_REQUEST_ACCEPT),
+ &Reply,
+ sizeof(FILE_REPLY_ACCEPT));
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ *lpErrno = Reply.Status;
+ return INVALID_SOCKET;
+ }
+
+ *addrlen = Reply.addrlen;
+
+ return Reply.Socket;
+}
+
+
+INT
+WSPAPI
+WSPConnect(
+ IN SOCKET s,
+ IN CONST LPSOCKADDR name,
+ IN INT namelen,
+ IN LPWSABUF lpCallerData,
+ OUT LPWSABUF lpCalleeData,
+ IN LPQOS lpSQOS,
+ IN LPQOS lpGQOS,
+ OUT LPINT lpErrno)
+{
+ FILE_REQUEST_CONNECT Request;
+ FILE_REPLY_CONNECT Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+
+ AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
+
+ Request.name = name;
+ Request.namelen = namelen;
+ Request.lpCallerData = lpCallerData;
+ Request.lpCalleeData = lpCalleeData;
+ Request.lpSQOS = lpSQOS;
+ Request.lpGQOS = lpGQOS;
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_CONNECT,
+ &Request,
+ sizeof(FILE_REQUEST_CONNECT),
+ &Reply,
+ sizeof(FILE_REPLY_CONNECT));
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ *lpErrno = Reply.Status;
+ return INVALID_SOCKET;
+ }
+
+ return 0;
+}
+
NTSTATUS OpenCommandChannel(
VOID)
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
- EaShort = sizeof(FILE_FULL_EA_INFORMATION) +
+ EaShort = sizeof(FILE_FULL_EA_INFORMATION) +
AFD_SOCKET_LENGTH +
sizeof(AFD_SOCKET_INFORMATION);
AFD_SOCKET_LENGTH);
EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION);
- SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + AFD_SOCKET_LENGTH);
+ SocketInfo = (PAFD_SOCKET_INFORMATION)((ULONG_PTR)EaInfo->EaName + AFD_SOCKET_LENGTH);
SocketInfo->CommandChannel = TRUE;
RtlInitUnicodeString(&DeviceName, L"\\Device\\Afd");
if (StartupCount == 0) {
/* First time called */
- Status = WSAVERNOTSUPPORTED;
-
Status = OpenCommandChannel();
if (NT_SUCCESS(Status)) {
hWS2_32 = GetModuleHandle(L"ws2_32.dll");
LeaveCriticalSection(&InitCriticalSection);
+ AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
*lpErrno = NO_ERROR;
return 0;
break;
case DLL_PROCESS_DETACH:
+
DestroyHelperDLLDatabase();
DeleteCriticalSection(&InitCriticalSection);
+
break;
}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Ancillary Function Driver DLL
+ * FILE: misc/event.c
+ * PURPOSE: Event handling
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISIONS:
+ * CSH 15/06-2001 Created
+ */
+#include <msafd.h>
+
+INT
+WSPAPI
+WSPEventSelect(
+ IN SOCKET s,
+ IN WSAEVENT hEventObject,
+ IN LONG lNetworkEvents,
+ OUT LPINT lpErrno)
+{
+ FILE_REQUEST_EVENTSELECT Request;
+ FILE_REPLY_EVENTSELECT Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+
+ Request.hEventObject = hEventObject;
+ Request.lNetworkEvents = lNetworkEvents;
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_EVENTSELECT,
+ &Request,
+ sizeof(FILE_REQUEST_EVENTSELECT),
+ &Reply,
+ sizeof(FILE_REPLY_EVENTSELECT));
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+ *lpErrno = WSAENOBUFS;
+ return SOCKET_ERROR;
+ }
+
+ AFD_DbgPrint(MAX_TRACE, ("Event select successful. Status (0x%X).\n",
+ Reply.Status));
+
+ *lpErrno = Reply.Status;
+
+ return 0;
+}
+
+INT
+WSPAPI
+WSPEnumNetworkEvents(
+ IN SOCKET s,
+ IN WSAEVENT hEventObject,
+ OUT LPWSANETWORKEVENTS lpNetworkEvents,
+ OUT LPINT lpErrno)
+{
+ FILE_REQUEST_ENUMNETWORKEVENTS Request;
+ FILE_REPLY_ENUMNETWORKEVENTS Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+
+ Request.hEventObject = hEventObject;
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_ENUMNETWORKEVENTS,
+ &Request,
+ sizeof(FILE_REQUEST_ENUMNETWORKEVENTS),
+ &Reply,
+ sizeof(FILE_REPLY_ENUMNETWORKEVENTS));
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+ *lpErrno = WSAENOBUFS;
+ return SOCKET_ERROR;
+ }
+
+ AFD_DbgPrint(MAX_TRACE, ("EnumNetworkEvents successful. Status (0x%X).\n",
+ Reply.Status));
+
+ *lpErrno = Reply.Status;
+
+ return 0;
+}
+
+/* EOF */
if (HelperDLL->hModule) {
if (!FreeLibrary(HelperDLL->hModule)) {
- CP
Status = GetLastError();
}
-
HelperDLL->hModule = NULL;
}
if (!HelperDLL)
return;
- HelperDLL->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
+ HelperDLL->Mapping = HeapAlloc(
+ GlobalHeap,
+ 0,
+ 3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
if (!HelperDLL->Mapping)
return;
- HelperDLL->Mapping->Rows = 1;
+ HelperDLL->Mapping->Rows = 3;
HelperDLL->Mapping->Columns = 3;
+
HelperDLL->Mapping->Mapping[0].AddressFamily = AF_INET;
- HelperDLL->Mapping->Mapping[0].SocketType = SOCK_RAW;
- HelperDLL->Mapping->Mapping[0].Protocol = 0;
+ HelperDLL->Mapping->Mapping[0].SocketType = SOCK_STREAM;
+ HelperDLL->Mapping->Mapping[0].Protocol = IPPROTO_TCP;
+
+ HelperDLL->Mapping->Mapping[1].AddressFamily = AF_INET;
+ HelperDLL->Mapping->Mapping[1].SocketType = SOCK_DGRAM;
+ HelperDLL->Mapping->Mapping[1].Protocol = IPPROTO_UDP;
+
+ HelperDLL->Mapping->Mapping[2].AddressFamily = AF_INET;
+ HelperDLL->Mapping->Mapping[2].SocketType = SOCK_RAW;
+ HelperDLL->Mapping->Mapping[2].Protocol = 0;
LoadHelperDLL(HelperDLL);
}
CurrentEntry = HelperDLLDatabaseListHead.Flink;
while (CurrentEntry != &HelperDLLDatabaseListHead) {
NextEntry = CurrentEntry->Flink;
- HelperDLL = CONTAINING_RECORD(CurrentEntry,
+
+ HelperDLL = CONTAINING_RECORD(CurrentEntry,
WSHELPER_DLL,
ListEntry);
IN LPWSATHREADID lpThreadId,
OUT LPINT lpErrno)
{
- UNIMPLEMENTED
+ PFILE_REQUEST_RECV Request;
+ FILE_REPLY_RECV Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ DWORD Size;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ Size = dwBufferCount * sizeof(WSABUF);
+
+ Request = (PFILE_REQUEST_RECV)HeapAlloc(
+ GlobalHeap, 0, sizeof(FILE_REQUEST_RECV) + Size);
+ if (!Request) {
+ AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+ *lpErrno = WSAENOBUFS;
+ return SOCKET_ERROR;
+ }
+
+ /* Put buffer pointers after request structure */
+ Request->Buffers = (LPWSABUF)(Request + 1);
+ Request->BufferCount = dwBufferCount;
+ Request->Flags = lpFlags;
+
+ RtlCopyMemory(Request->Buffers, lpBuffers, Size);
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_RECV,
+ Request,
+ sizeof(FILE_REQUEST_RECV) + Size,
+ &Reply,
+ sizeof(FILE_REPLY_RECV));
+
+ HeapFree(GlobalHeap, 0, Request);
+
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+ *lpErrno = WSAENOBUFS;
+ return SOCKET_ERROR;
+ }
+
+ AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
+ Reply.NumberOfBytesRecvd));
+
+ *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
+ //*lpFlags = 0;
return 0;
}
}
/* Put buffer pointers after request structure */
- Request->Buffers = (LPWSABUF)(Request + sizeof(FILE_REQUEST_RECVFROM));
+ Request->Buffers = (LPWSABUF)(Request + 1);
Request->BufferCount = dwBufferCount;
Request->Flags = lpFlags;
Request->From = lpFrom;
RtlCopyMemory(Request->Buffers, lpBuffers, Size);
- Status = NtDeviceIoControlFile((HANDLE)s,
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
NULL,
NULL,
NULL,
AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
Reply.NumberOfBytesRecvd));
- AFD_DbgPrint(MAX_TRACE, ("lpNumberOfBytesRecvd (0x%X).\n",
- lpNumberOfBytesRecvd));
-
*lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
//*lpFlags = 0;
((PSOCKADDR_IN)lpFrom)->sin_family = AF_INET;
IN LPWSATHREADID lpThreadId,
OUT LPINT lpErrno)
{
- UNIMPLEMENTED
+ PFILE_REQUEST_SENDTO Request;
+ FILE_REPLY_SENDTO Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ DWORD Size;
+
+ AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ Size = dwBufferCount * sizeof(WSABUF);
+
+ Request = (PFILE_REQUEST_SENDTO)HeapAlloc(
+ GlobalHeap, 0, sizeof(FILE_REQUEST_SEND) + Size);
+ if (!Request) {
+ *lpErrno = WSAENOBUFS;
+ return SOCKET_ERROR;
+ }
+
+ /* Put buffer pointers after request structure */
+ Request->Buffers = (LPWSABUF)(Request + 1);
+ Request->BufferCount = dwBufferCount;
+ Request->Flags = dwFlags;
+
+ RtlCopyMemory(Request->Buffers, lpBuffers, Size);
+
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_AFD_SEND,
+ Request,
+ sizeof(FILE_REQUEST_SEND) + Size,
+ &Reply,
+ sizeof(FILE_REPLY_SEND));
+
+ HeapFree(GlobalHeap, 0, Request);
+
+ if (Status == STATUS_PENDING) {
+ AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+ /* FIXME: Wait only for blocking sockets */
+ Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+ }
+
+ if (!NT_SUCCESS(Status)) {
+ AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+ *lpErrno = WSAENOBUFS;
+ return SOCKET_ERROR;
+ }
+
+ AFD_DbgPrint(MAX_TRACE, ("Send successful.\n"));
return 0;
}
}
/* Put buffer pointers after request structure */
- Request->Buffers = (LPWSABUF)(Request + sizeof(FILE_REQUEST_SENDTO));
+ Request->Buffers = (LPWSABUF)(Request + 1);
Request->BufferCount = dwBufferCount;
Request->Flags = dwFlags;
Request->ToLen = iToLen;
RtlCopyMemory(Request->Buffers, lpBuffers, Size);
- Status = NtDeviceIoControlFile((HANDLE)s,
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
NULL,
NULL,
NULL,
#include <msafd.h>
-SOCKET
-WSPAPI
-WSPAccept(
- IN SOCKET s,
- OUT LPSOCKADDR addr,
- IN OUT LPINT addrlen,
- IN LPCONDITIONPROC lpfnCondition,
- IN DWORD dwCallbackData,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
-
- return INVALID_SOCKET;
-}
-
-
INT
WSPAPI
WSPAddressToString(
}
-INT
-WSPAPI
-WSPConnect(
- IN SOCKET s,
- IN CONST LPSOCKADDR name,
- IN INT namelen,
- IN LPWSABUF lpCallerData,
- OUT LPWSABUF lpCalleeData,
- IN LPQOS lpSQOS,
- IN LPQOS lpGQOS,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
INT
WSPAPI
WSPDuplicateSocket(
}
-INT
-WSPAPI
-WSPEnumNetworkEvents(
- IN SOCKET s,
- IN WSAEVENT hEventObject,
- OUT LPWSANETWORKEVENTS lpNetworkEvents,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
-INT
-WSPAPI
-WSPEventSelect(
- IN SOCKET s,
- IN WSAEVENT hEventObject,
- IN LONG lNetworkEvents,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
BOOL
WSPAPI
WSPGetOverlappedResult(
}
-INT
-WSPAPI
-WSPListen(
- IN SOCKET s,
- IN INT backlog,
- OUT LPINT lpErrno)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-
INT
WSPAPI
WSPSetSockOpt(
-# $Id: Makefile,v 1.13 2001/07/04 16:39:36 ekohl Exp $
+# $Id: Makefile,v 1.14 2001/07/04 20:40:19 chorns Exp $
#
# ReactOS Operating System
#
conio\*.o \
ctype\*.o \
direct\*.o \
+ except\*.o \
float\*.o \
io\*.o \
math\*.o \
conio/*.o \
ctype/*.o \
direct/*.o \
+ except/*.o \
float/*.o \
io/*.o \
math/*.o \
-/* $Id: utils.c,v 1.45 2001/07/02 20:27:41 phreak Exp $
+/* $Id: utils.c,v 1.46 2001/07/04 20:40:19 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
- while (Entry != ModuleListHead);
+ while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
if (Module->BaseAddress == BaseAddress)
PCATALOG_ENTRY Provider;
} PROVIDER_HANDLE, *PPROVIDER_HANDLE;
-#define HANDLE_BLOCK_ENTRIES ((PAGESIZE-sizeof(LIST_ENTRY))/sizeof(PROVIDER_HANDLE))
+#define HANDLE_BLOCK_ENTRIES ((1024-sizeof(LIST_ENTRY))/sizeof(PROVIDER_HANDLE))
typedef struct _PROVIDER_HANDLE_BLOCK {
LIST_ENTRY Entry;
#define WSASETINITIALIZED (((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Initialized = TRUE)
+
+#ifdef LE
+
+/* DWORD network to host byte order conversion for little endian machines */
+#define DN2H(dw) \
+ ((((dw) & 0xFF000000L) >> 24) | \
+ (((dw) & 0x00FF0000L) >> 8) | \
+ (((dw) & 0x0000FF00L) << 8) | \
+ (((dw) & 0x000000FFL) << 24))
+
+/* DWORD host to network byte order conversion for little endian machines */
+#define DH2N(dw) \
+ ((((dw) & 0xFF000000L) >> 24) | \
+ (((dw) & 0x00FF0000L) >> 8) | \
+ (((dw) & 0x0000FF00L) << 8) | \
+ (((dw) & 0x000000FFL) << 24))
+
+/* WORD network to host order conversion for little endian machines */
+#define WN2H(w) \
+ ((((w) & 0xFF00) >> 8) | \
+ (((w) & 0x00FF) << 8))
+
+/* WORD host to network byte order conversion for little endian machines */
+#define WH2N(w) \
+ ((((w) & 0xFF00) >> 8) | \
+ (((w) & 0x00FF) << 8))
+
+#else /* LE */
+
+/* DWORD network to host byte order conversion for big endian machines */
+#define DN2H(dw) \
+ (dw)
+
+/* DWORD host to network byte order conversion big endian machines */
+#define DH2N(dw) \
+ (dw)
+
+/* WORD network to host order conversion for big endian machines */
+#define WN2H(w) \
+ (w)
+
+/* WORD host to network byte order conversion for big endian machines */
+#define WH2N(w) \
+ (w)
+
+#endif /* LE */
+
#endif /* __WS2_32_H */
/* EOF */
PATH_TO_TOP = ../..
-CFLAGS = -Iinclude -DUNICODE -DDBG
+CFLAGS = -Iinclude -DUNICODE -DDBG -DLE
TARGETNAME=ws2_32
-MISC_OBJECTS = misc/dllmain.o misc/catalog.o misc/event.o misc/handle.o \
- misc/ns.o misc/sndrcv.o misc/stubs.o misc/upcall.o
+MISC_OBJECTS = misc/bsd.o misc/catalog.o misc/dllmain.o \
+ misc/event.o misc/handle.o misc/ns.o \
+ misc/sndrcv.o misc/stubs.o misc/upcall.o
RESOURCE_OBJECT = $(TARGETNAME).coff
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS WinSock 2 DLL
+ * FILE: misc/bsd.c
+ * PURPOSE: Legacy BSD sockets APIs
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISIONS:
+ * CSH 15/06-2001 Created
+ */
+#include <ws2_32.h>
+
+ULONG
+EXPORT
+htonl(
+ IN ULONG hostlong)
+{
+ return DH2N(hostlong);
+}
+
+USHORT
+EXPORT
+htons(
+ IN USHORT hostshort)
+{
+ return WH2N(hostshort);
+}
+
+ULONG
+EXPORT
+ntohl(
+ IN ULONG netlong)
+{
+ return DN2H(netlong);
+}
+
+USHORT
+EXPORT
+ntohs(
+ IN USHORT netshort)
+{
+ return WN2H(netshort);
+}
+
+/* EOF */
CurrentEntry = CurrentEntry->Flink;
}
- LeaveCriticalSection(&CatalogLock);
+ //LeaveCriticalSection(&CatalogLock);
return NULL;
}
&Provider->ProcTable);
/* FIXME: Validate the procedure table */
-
- WS_DbgPrint(MAX_TRACE, ("OFFSET2 (0x%X)\n",
- FIELD_OFFSET(WSPPROC_TABLE, lpWSPSocket)));
-
- assert(Provider->ProcTable.lpWSPSocket);
-
} else
Status = ERROR_BAD_PROVIDER;
} else
Provider->ProcTable.lpWSPCleanup));
Provider->ProcTable.lpWSPCleanup(&Status);
+ WS_DbgPrint(MAX_TRACE, ("Calling FreeLibrary(0x%X).\n", Provider->hModule));
if (!FreeLibrary(Provider->hModule)) {
- WS_DbgPrint(MIN_TRACE, ("Could not free library.\n"));
+ WS_DbgPrint(MIN_TRACE, ("Could not free library at (0x%X).\n", Provider->hModule));
Status = GetLastError();
}
/* Assume one Service Provider with id 1 */
Provider->ProtocolInfo.dwCatalogEntryId = 1;
- Provider->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
- if (!Provider->Mapping) {
- WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
+ Provider->Mapping = HeapAlloc(GlobalHeap,
+ 0,
+ 3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
+ if (!Provider->Mapping)
return;
- }
- Provider->Mapping->Rows = 1;
+ Provider->Mapping->Rows = 3;
Provider->Mapping->Columns = 3;
+
Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
- Provider->Mapping->Mapping[0].SocketType = SOCK_RAW;
- Provider->Mapping->Mapping[0].Protocol = 0;
+ Provider->Mapping->Mapping[0].SocketType = SOCK_STREAM;
+ Provider->Mapping->Mapping[0].Protocol = IPPROTO_TCP;
+
+ Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
+ Provider->Mapping->Mapping[1].SocketType = SOCK_DGRAM;
+ Provider->Mapping->Mapping[1].Protocol = IPPROTO_UDP;
+
+ Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
+ Provider->Mapping->Mapping[2].SocketType = SOCK_RAW;
+ Provider->Mapping->Mapping[2].Protocol = 0;
#endif
}
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
-//DWORD DebugTraceLevel = MAX_TRACE;
+//DWORD DebugTraceLevel = DEBUG_ULTRA;
#endif /* DBG */
}
+SOCKET
+EXPORT
+socket(
+ IN INT af,
+ IN INT type,
+ IN INT protocol)
+{
+ return WSASocketA(af, type, protocol, NULL, 0, 0);
+}
+
+
SOCKET
EXPORT
WSASocketA(
*/
{
PCATALOG_ENTRY Provider;
+ INT Status;
INT Errno;
- INT Code;
WS_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
DereferenceProviderByPointer(Provider);
- Code = Provider->ProcTable.lpWSPCloseSocket(s, &Errno);
- if (Code == SOCKET_ERROR)
+ Status = Provider->ProcTable.lpWSPCloseSocket(s, &Errno);
+ if (Status == SOCKET_ERROR)
WSASetLastError(Errno);
return 0;
DereferenceProviderByPointer(Provider);
- WSASetLastError(Errno);
-
- if (Errno != NO_ERROR)
+ if (Errno != NO_ERROR) {
+ WSASetLastError(Errno);
return SOCKET_ERROR;
+ }
return Count;
}
+INT
+EXPORT
+bind(
+ IN SOCKET s,
+ IN CONST LPSOCKADDR name,
+ IN INT namelen)
+{
+ PCATALOG_ENTRY Provider;
+ INT Status;
+ INT Errno;
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return SOCKET_ERROR;
+ }
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ Status = Provider->ProcTable.lpWSPBind(
+ s, name, namelen, &Errno);
+
+ DereferenceProviderByPointer(Provider);
+
+ if (Status == SOCKET_ERROR) {
+ WSASetLastError(Errno);
+ }
+
+ return Status;
+}
+
+
+INT
+EXPORT
+listen(
+ IN SOCKET s,
+ IN INT backlog)
+{
+ PCATALOG_ENTRY Provider;
+ INT Status;
+ INT Errno;
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return SOCKET_ERROR;
+ }
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ Status = Provider->ProcTable.lpWSPListen(
+ s, backlog, &Errno);
+
+ DereferenceProviderByPointer(Provider);
+
+ if (Status == SOCKET_ERROR) {
+ WSASetLastError(Errno);
+ }
+
+ return Status;
+}
+
+
+SOCKET
+EXPORT
+accept(
+ IN SOCKET s,
+ OUT LPSOCKADDR addr,
+ OUT INT FAR* addrlen)
+{
+ return WSAAccept(s, addr, addrlen, NULL, 0);
+}
+
+
+SOCKET
+EXPORT
+WSAAccept(
+ IN SOCKET s,
+ OUT LPSOCKADDR addr,
+ IN OUT LPINT addrlen,
+ IN LPCONDITIONPROC lpfnCondition,
+ IN DWORD dwCallbackData)
+{
+ PCATALOG_ENTRY Provider;
+ SOCKET Socket;
+ INT Errno;
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return SOCKET_ERROR;
+ }
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ Socket = Provider->ProcTable.lpWSPAccept(
+ s, addr, addrlen, lpfnCondition, dwCallbackData, &Errno);
+
+ DereferenceProviderByPointer(Provider);
+
+ if (Socket == INVALID_SOCKET) {
+ WSASetLastError(Errno);
+ }
+
+ return Socket;
+}
+
+
+INT
+EXPORT
+connect(
+ IN SOCKET s,
+ IN CONST LPSOCKADDR name,
+ IN INT namelen)
+{
+ return WSAConnect(s, name, namelen, NULL, NULL, NULL, NULL);
+}
+
+
+INT
+EXPORT
+WSAConnect(
+ IN SOCKET s,
+ IN CONST LPSOCKADDR name,
+ IN INT namelen,
+ IN LPWSABUF lpCallerData,
+ OUT LPWSABUF lpCalleeData,
+ IN LPQOS lpSQOS,
+ IN LPQOS lpGQOS)
+{
+ PCATALOG_ENTRY Provider;
+ INT Status;
+ INT Errno;
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return SOCKET_ERROR;
+ }
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ Status = Provider->ProcTable.lpWSPConnect(
+ s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, &Errno);
+
+ DereferenceProviderByPointer(Provider);
+
+ if (Status == SOCKET_ERROR) {
+ WSASetLastError(Errno);
+ }
+
+ return Status;
+}
+
+
BOOL
STDCALL
DllMain(HANDLE hInstDll,
* CSH 01/09-2000 Created
*/
#include <ws2_32.h>
+#include <handle.h>
+
BOOL
EXPORT
WSACloseEvent(
- IN WSAEVENT hEvent)
+ IN WSAEVENT hEvent)
{
- BOOL Success;
+ BOOL Success;
- if (!WSAINITIALIZED) {
- WSASetLastError(WSANOTINITIALISED);
- return FALSE;
- }
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return FALSE;
+ }
- Success = CloseHandle((HANDLE)hEvent);
+ Success = CloseHandle((HANDLE)hEvent);
- if (!Success)
- WSASetLastError(WSA_INVALID_HANDLE);
+ if (!Success)
+ WSASetLastError(WSA_INVALID_HANDLE);
- return Success;
+ return Success;
}
EXPORT
WSACreateEvent(VOID)
{
- HANDLE Event;
+ HANDLE Event;
- if (!WSAINITIALIZED) {
- WSASetLastError(WSANOTINITIALISED);
- return FALSE;
- }
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return FALSE;
+ }
- Event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ Event = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (Event == INVALID_HANDLE_VALUE)
- WSASetLastError(WSA_INVALID_HANDLE);
-
- return (WSAEVENT)Event;
+ if (Event == INVALID_HANDLE_VALUE)
+ WSASetLastError(WSA_INVALID_HANDLE);
+
+ return (WSAEVENT)Event;
}
BOOL
EXPORT
WSAResetEvent(
- IN WSAEVENT hEvent)
+ IN WSAEVENT hEvent)
{
- BOOL Success;
+ BOOL Success;
- if (!WSAINITIALIZED) {
- WSASetLastError(WSANOTINITIALISED);
- return FALSE;
- }
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return FALSE;
+ }
- Success = ResetEvent((HANDLE)hEvent);
+ Success = ResetEvent((HANDLE)hEvent);
- if (!Success)
- WSASetLastError(WSA_INVALID_HANDLE);
+ if (!Success)
+ WSASetLastError(WSA_INVALID_HANDLE);
- return Success;
+ return Success;
}
BOOL
EXPORT
WSASetEvent(
- IN WSAEVENT hEvent)
+ IN WSAEVENT hEvent)
{
- BOOL Success;
+ BOOL Success;
- if (!WSAINITIALIZED) {
- WSASetLastError(WSANOTINITIALISED);
- return FALSE;
- }
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return FALSE;
+ }
- Success = SetEvent((HANDLE)hEvent);
+ Success = SetEvent((HANDLE)hEvent);
- if (!Success)
- WSASetLastError(WSA_INVALID_HANDLE);
+ if (!Success)
+ WSASetLastError(WSA_INVALID_HANDLE);
- return Success;
+ return Success;
}
DWORD
EXPORT
WSAWaitForMultipleEvents(
- IN DWORD cEvents,
- IN CONST WSAEVENT FAR* lphEvents,
- IN BOOL fWaitAll,
- IN DWORD dwTimeout,
- IN BOOL fAlertable)
+ IN DWORD cEvents,
+ IN CONST WSAEVENT FAR* lphEvents,
+ IN BOOL fWaitAll,
+ IN DWORD dwTimeout,
+ IN BOOL fAlertable)
+{
+ DWORD Status;
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return FALSE;
+ }
+
+ Status = WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
+ if (Status == WAIT_FAILED) {
+ Status = GetLastError();
+
+ if (Status == ERROR_NOT_ENOUGH_MEMORY)
+ WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
+ else if (Status == ERROR_INVALID_HANDLE)
+ WSASetLastError(WSA_INVALID_HANDLE);
+ else
+ WSASetLastError(WSA_INVALID_PARAMETER);
+
+ return WSA_WAIT_FAILED;
+ }
+
+ return Status;
+}
+
+
+INT
+EXPORT
+WSAEnumNetworkEvents(
+ IN SOCKET s,
+ IN WSAEVENT hEventObject,
+ OUT LPWSANETWORKEVENTS lpNetworkEvents)
+{
+ PCATALOG_ENTRY Provider;
+ INT Status;
+ INT Errno;
+
+ if (!lpNetworkEvents) {
+ WSASetLastError(WSAEINVAL);
+ return SOCKET_ERROR;
+ }
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return SOCKET_ERROR;
+ }
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ Status = Provider->ProcTable.lpWSPEnumNetworkEvents(
+ s, hEventObject, lpNetworkEvents, &Errno);
+
+ DereferenceProviderByPointer(Provider);
+
+ if (Status == SOCKET_ERROR)
+ WSASetLastError(Errno);
+
+ return Status;
+}
+
+
+INT
+EXPORT
+WSAEventSelect(
+ IN SOCKET s,
+ IN WSAEVENT hEventObject,
+ IN LONG lNetworkEvents)
{
- DWORD Status;
+ PCATALOG_ENTRY Provider;
+ INT Status;
+ INT Errno;
+ LONG i;
+
+ if (!WSAINITIALIZED) {
+ WSASetLastError(WSANOTINITIALISED);
+ return SOCKET_ERROR;
+ }
- if (!WSAINITIALIZED) {
- WSASetLastError(WSANOTINITIALISED);
- return FALSE;
- }
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
- Status = WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
- if (Status == WAIT_FAILED) {
- Status = GetLastError();
+ Status = Provider->ProcTable.lpWSPEventSelect(
+ s, hEventObject, lNetworkEvents, &Errno);
- if (Status == ERROR_NOT_ENOUGH_MEMORY)
- WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
- else if (Status == ERROR_INVALID_HANDLE)
- WSASetLastError(WSA_INVALID_HANDLE);
- else
- WSASetLastError(WSA_INVALID_PARAMETER);
+ DereferenceProviderByPointer(Provider);
- return WSA_WAIT_FAILED;
- }
+ if (Status == SOCKET_ERROR)
+ WSASetLastError(Errno);
- return Status;
+ return Status;
}
/* EOF */
* NULL on failure
*/
{
- PPROVIDER_HANDLE_BLOCK Current;
- PLIST_ENTRY CurrentEntry;
- ULONG i;
-
- WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
-
- CurrentEntry = HandleTable->Entry.Flink;
-
- while (CurrentEntry != &HandleTable->Entry) {
- Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
-
- for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
- if ((Current->Handles[i].Provider != NULL) &&
- (Current->Handles[i].Handle == Handle)) {
-
- return &Current->Handles[i];
- }
- }
- CurrentEntry = CurrentEntry->Flink;
+ PPROVIDER_HANDLE_BLOCK Current;
+ PLIST_ENTRY CurrentEntry;
+ ULONG i;
+
+ WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
+
+ CurrentEntry = HandleTable->Entry.Flink;
+
+ while (CurrentEntry != &HandleTable->Entry) {
+ Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
+
+ for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
+ if ((Current->Handles[i].Provider != NULL) &&
+ (Current->Handles[i].Handle == Handle)) {
+ return &Current->Handles[i];
+ }
}
+ CurrentEntry = CurrentEntry->Flink;
+ }
- return NULL;
+ return NULL;
}
VOID
-CloseAllHandles(PPROVIDER_HANDLE_BLOCK HandleTable)
+CloseAllHandles(
+ PPROVIDER_HANDLE_BLOCK HandleTable)
{
- PPROVIDER_HANDLE_BLOCK Current;
- PLIST_ENTRY CurrentEntry;
- PCATALOG_ENTRY Provider;
- ULONG i;
-
- WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable));
-
- CurrentEntry = HandleTable->Entry.Flink;
-
- while (CurrentEntry != &HandleTable->Entry) {
- Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
-
- for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
- Provider = Current->Handles[i].Provider;
-
- if (Provider != NULL) {
- DereferenceProviderByPointer(Provider);
- Current->Handles[i].Handle = (HANDLE)0;
- Current->Handles[i].Provider = NULL;
- break;
- }
+ PPROVIDER_HANDLE_BLOCK Current;
+ PLIST_ENTRY CurrentEntry;
+ PCATALOG_ENTRY Provider;
+ ULONG i;
+
+ WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable));
+
+ CurrentEntry = HandleTable->Entry.Flink;
+
+ while (CurrentEntry != &HandleTable->Entry) {
+ Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
+
+ for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
+ Provider = Current->Handles[i].Provider;
+ if (Provider != NULL) {
+ DereferenceProviderByPointer(Provider);
+ Current->Handles[i].Handle = (HANDLE)0;
+ Current->Handles[i].Provider = NULL;
}
- CurrentEntry = CurrentEntry->Flink;
- }
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
}
VOID
-DeleteHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable)
+DeleteHandleTable(
+ PPROVIDER_HANDLE_BLOCK HandleTable)
{
- PPROVIDER_HANDLE_BLOCK Current;
- PLIST_ENTRY CurrentEntry;
-
- CloseAllHandles(HandleTable);
-
- CurrentEntry = RemoveHeadList(&HandleTable->Entry);
-
- while (CurrentEntry != &HandleTable->Entry) {
- Current = CONTAINING_RECORD(CurrentEntry,
- PROVIDER_HANDLE_BLOCK,
- Entry);
-
- HeapFree(GlobalHeap, 0, Current);
-
- CurrentEntry = RemoveHeadList(&HandleTable->Entry);
- }
+ PPROVIDER_HANDLE_BLOCK Current;
+ PLIST_ENTRY CurrentEntry;
+
+ CloseAllHandles(HandleTable);
+
+ CurrentEntry = RemoveHeadList(&HandleTable->Entry);
+
+ while (CurrentEntry != &HandleTable->Entry) {
+ Current = CONTAINING_RECORD(
+ CurrentEntry,
+ PROVIDER_HANDLE_BLOCK,
+ Entry);
+
+ HeapFree(GlobalHeap, 0, Current);
+
+ CurrentEntry = RemoveHeadList(&HandleTable->Entry);
+ }
}
DeleteProviderHandle(PPROVIDER_HANDLE_BLOCK HandleTable,
HANDLE Handle)
{
- PPROVIDER_HANDLE Entry;
- PCATALOG_ENTRY Provider;
+ PPROVIDER_HANDLE Entry;
+ PCATALOG_ENTRY Provider;
- WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
-
- Entry = GetProviderByHandle(HandleTable, Handle);
- if (!Entry) {
- return NULL;
- }
+ WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
- Provider = Entry->Provider;
+ Entry = GetProviderByHandle(HandleTable, Handle);
+ if (!Entry)
+ return NULL;
- if (Provider != NULL) {
- Entry->Handle = (HANDLE)0;
- Entry->Provider = NULL;
- }
+ Provider = Entry->Provider;
+ Entry->Handle = (HANDLE)0;
+ Entry->Provider = NULL;
- return Provider;
+ return Provider;
}
HANDLE
-CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable,
- HANDLE Handle,
- PCATALOG_ENTRY Provider)
+CreateProviderHandleTable(
+ PPROVIDER_HANDLE_BLOCK HandleTable,
+ HANDLE Handle,
+ PCATALOG_ENTRY Provider)
{
- PPROVIDER_HANDLE_BLOCK NewBlock;
- PLIST_ENTRY CurrentEntry;
- ULONG i;
-
- WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X) Provider (0x%X).\n", HandleTable, Handle, Provider));
-
- /* Scan through the currently allocated handle blocks looking for a free slot */
- CurrentEntry = HandleTable->Entry.Flink;
- while (CurrentEntry != &HandleTable->Entry) {
- PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(
- CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
-
- for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
- WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n", i, Block->Handles[i].Provider));
- if (!Block->Handles[i].Provider) {
- Block->Handles[i].Handle = Handle;
- Block->Handles[i].Provider = Provider;
- return Handle;
- }
+ PPROVIDER_HANDLE_BLOCK NewBlock;
+ PLIST_ENTRY CurrentEntry;
+ ULONG i;
+
+ WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X) Provider (0x%X).\n",
+ HandleTable, Handle, Provider));
+
+ /* Scan through the currently allocated handle blocks looking for a free slot */
+ CurrentEntry = HandleTable->Entry.Flink;
+ while (CurrentEntry != &HandleTable->Entry) {
+ PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(
+ CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
+
+ for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
+ WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n",
+ i, Block->Handles[i].Provider));
+ if (Block->Handles[i].Provider == NULL) {
+ Block->Handles[i].Handle = Handle;
+ Block->Handles[i].Provider = Provider;
+ return Handle;
}
- CurrentEntry = CurrentEntry->Flink;
- }
-
- /* Add a new handle block to the end of the list */
- NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(
- GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
-
- if (!NewBlock) {
- return NULL;
}
+ CurrentEntry = CurrentEntry->Flink;
+ }
+
+ /* Add a new handle block to the end of the list */
+ NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(
+ GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
+
+ if (!NewBlock)
+ return (HANDLE)0;
- ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK));
- InsertTailList(&HandleTable->Entry, &NewBlock->Entry);
+ ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK));
+ InsertTailList(&HandleTable->Entry, &NewBlock->Entry);
- NewBlock->Handles[0].Handle = Handle;
- NewBlock->Handles[0].Provider = Provider;
+ NewBlock->Handles[0].Handle = Handle;
+ NewBlock->Handles[0].Provider = Provider;
- return Handle;
+ return Handle;
}
HANDLE
-CreateProviderHandle(HANDLE Handle,
- PCATALOG_ENTRY Provider)
+CreateProviderHandle(
+ HANDLE Handle,
+ PCATALOG_ENTRY Provider)
{
- HANDLE h;
+ HANDLE h;
- //EnterCriticalSection(&ProviderHandleTableLock);
+ EnterCriticalSection(&ProviderHandleTableLock);
- h = CreateProviderHandleTable(ProviderHandleTable, Handle, Provider);
+ h = CreateProviderHandleTable(ProviderHandleTable, Handle, Provider);
- //LeaveCriticalSection(&ProviderHandleTableLock);
+ LeaveCriticalSection(&ProviderHandleTableLock);
- if (h != NULL) {
- ReferenceProviderByPointer(Provider);
- }
+ if (h != NULL)
+ ReferenceProviderByPointer(Provider);
- return h;
+ return h;
}
BOOL
-ReferenceProviderByHandle(HANDLE Handle,
- PCATALOG_ENTRY* Provider)
+ReferenceProviderByHandle(
+ HANDLE Handle,
+ PCATALOG_ENTRY* Provider)
/*
* FUNCTION: Increments the reference count for a provider and returns a pointer to it
* ARGUMENTS:
* TRUE if handle was valid, FALSE if not
*/
{
- PPROVIDER_HANDLE ProviderHandle;
+ PPROVIDER_HANDLE ProviderHandle;
WS_DbgPrint(MAX_TRACE, ("Handle (0x%X) Provider (0x%X).\n", Handle, Provider));
- //EnterCriticalSection(&ProviderHandleTableLock);
+ EnterCriticalSection(&ProviderHandleTableLock);
- ProviderHandle = GetProviderByHandle(ProviderHandleTable, Handle);
+ ProviderHandle = GetProviderByHandle(ProviderHandleTable, Handle);
- //LeaveCriticalSection(&ProviderHandleTableLock);
+ LeaveCriticalSection(&ProviderHandleTableLock);
- if (ProviderHandle) {
- ReferenceProviderByPointer(ProviderHandle->Provider);
- *Provider = ProviderHandle->Provider;
- }
+ if (ProviderHandle) {
+ ReferenceProviderByPointer(ProviderHandle->Provider);
+ *Provider = ProviderHandle->Provider;
+ }
- return (ProviderHandle != NULL);
+ return (ProviderHandle != NULL);
}
BOOL
-CloseProviderHandle(HANDLE Handle)
+CloseProviderHandle(
+ HANDLE Handle)
{
- PCATALOG_ENTRY Provider;
-
- WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle));
+ PCATALOG_ENTRY Provider;
+
+ WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle));
- //EnterCriticalSection(&ProviderHandleTableLock);
+ EnterCriticalSection(&ProviderHandleTableLock);
- Provider = DeleteProviderHandle(ProviderHandleTable, Handle);
- if (!Provider) {
- return FALSE;
- }
+ Provider = DeleteProviderHandle(ProviderHandleTable, Handle);
+ if (!Provider)
+ return FALSE;
- //LeaveCriticalSection(&ProviderHandleTableLock);
+ LeaveCriticalSection(&ProviderHandleTableLock);
- DereferenceProviderByPointer(Provider);
+ DereferenceProviderByPointer(Provider);
- return TRUE;
+ return TRUE;
}
BOOL
InitProviderHandleTable(VOID)
{
- ProviderHandleTable = (PPROVIDER_HANDLE_BLOCK)
- HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
- if (!ProviderHandleTable) {
- return FALSE;
- }
+ ProviderHandleTable = (PPROVIDER_HANDLE_BLOCK)
+ HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
+ if (!ProviderHandleTable)
+ return FALSE;
- ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK));
+ ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK));
- InitializeListHead(&ProviderHandleTable->Entry);
+ InitializeListHead(&ProviderHandleTable->Entry);
- //InitializeCriticalSection(&ProviderHandleTableLock);
+ InitializeCriticalSection(&ProviderHandleTableLock);
- return TRUE;
+ return TRUE;
}
VOID
FreeProviderHandleTable(VOID)
{
- DeleteHandleTable(ProviderHandleTable);
+ DeleteHandleTable(ProviderHandleTable);
- //DeleteCriticalSection(&ProviderHandleTableLock);
+ DeleteCriticalSection(&ProviderHandleTableLock);
}
/* EOF */
INT
EXPORT
recv(
- IN SOCKET s,
- OUT CHAR FAR* buf,
- IN INT len,
- IN INT flags)
+ IN SOCKET s,
+ OUT CHAR FAR* buf,
+ IN INT len,
+ IN INT flags)
{
- UNIMPLEMENTED
+ DWORD BytesReceived;
+ WSABUF WSABuf;
- return 0;
+ WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n",
+ s, buf, len, flags));
+
+ WSABuf.len = len;
+ WSABuf.buf = (CHAR FAR*)buf;
+
+ WSARecv(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, NULL, NULL);
+
+ return BytesReceived;
}
INT
EXPORT
recvfrom(
- IN SOCKET s,
- OUT CHAR FAR* buf,
- IN INT len,
- IN INT flags,
- OUT LPSOCKADDR from,
- IN OUT INT FAR* fromlen)
+ IN SOCKET s,
+ OUT CHAR FAR* buf,
+ IN INT len,
+ IN INT flags,
+ OUT LPSOCKADDR from,
+ IN OUT INT FAR* fromlen)
{
- DWORD BytesReceived;
- WSABUF WSABuf;
+ DWORD BytesReceived;
+ WSABUF WSABuf;
- WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n",
- s, buf, len, flags));
+ WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n",
+ s, buf, len, flags));
- WSABuf.len = len;
- WSABuf.buf = (CHAR FAR*)buf;
+ WSABuf.len = len;
+ WSABuf.buf = (CHAR FAR*)buf;
- WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL);
+ WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL);
- return BytesReceived;
+ return BytesReceived;
}
INT
EXPORT
send(
- IN SOCKET s,
- IN CONST CHAR FAR* buf,
- IN INT len,
- IN INT flags)
+ IN SOCKET s,
+ IN CONST CHAR FAR* buf,
+ IN INT len,
+ IN INT flags)
{
- UNIMPLEMENTED
+ DWORD BytesSent;
+ WSABUF WSABuf;
+
+ WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n",
+ s, buf, len, flags));
+
+ WSABuf.len = len;
+ WSABuf.buf = (CHAR FAR*)buf;
- return 0;
+ return WSASend(s, &WSABuf, 1, &BytesSent, flags, NULL, NULL);
}
INT
EXPORT
sendto(
- IN SOCKET s,
- IN CONST CHAR FAR* buf,
- IN INT len,
- IN INT flags,
- IN CONST LPSOCKADDR to,
- IN INT tolen)
+ IN SOCKET s,
+ IN CONST CHAR FAR* buf,
+ IN INT len,
+ IN INT flags,
+ IN CONST LPSOCKADDR to,
+ IN INT tolen)
{
- DWORD BytesSent;
- WSABUF WSABuf;
+ DWORD BytesSent;
+ WSABUF WSABuf;
- WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n",
- s, buf, len, flags));
+ WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n",
+ s, buf, len, flags));
- WSABuf.len = len;
- WSABuf.buf = (CHAR FAR*)buf;
+ WSABuf.len = len;
+ WSABuf.buf = (CHAR FAR*)buf;
- return WSASendTo(s, &WSABuf, 1, &BytesSent, flags, to, tolen, NULL, NULL);
+ return WSASendTo(s, &WSABuf, 1, &BytesSent, flags, to, tolen, NULL, NULL);
}
INT
EXPORT
WSARecv(
- IN SOCKET s,
- IN OUT LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesRecvd,
- IN OUT LPDWORD lpFlags,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
+ IN SOCKET s,
+ IN OUT LPWSABUF lpBuffers,
+ IN DWORD dwBufferCount,
+ OUT LPDWORD lpNumberOfBytesRecvd,
+ IN OUT LPDWORD lpFlags,
+ IN LPWSAOVERLAPPED lpOverlapped,
+ IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
- UNIMPLEMENTED
+ PCATALOG_ENTRY Provider;
+ INT Errno;
+ INT Code;
+
+ WS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ assert(Provider->ProcTable.lpWSPRecv);
+
+ Code = Provider->ProcTable.lpWSPRecv(s, lpBuffers, dwBufferCount,
+ lpNumberOfBytesRecvd, lpFlags, lpOverlapped,
+ lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
- return 0;
+ DereferenceProviderByPointer(Provider);
+
+ if (Code == SOCKET_ERROR)
+ WSASetLastError(Errno);
+
+ return Code;
}
INT
EXPORT
WSARecvDisconnect(
- IN SOCKET s,
- OUT LPWSABUF lpInboundDisconnectData)
+ IN SOCKET s,
+ OUT LPWSABUF lpInboundDisconnectData)
{
- UNIMPLEMENTED
+ UNIMPLEMENTED
- return 0;
+ return 0;
}
INT
EXPORT
WSARecvFrom(
- IN SOCKET s,
- IN OUT LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesRecvd,
- IN OUT LPDWORD lpFlags,
- OUT LPSOCKADDR lpFrom,
- IN OUT LPINT lpFromlen,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
+ IN SOCKET s,
+ IN OUT LPWSABUF lpBuffers,
+ IN DWORD dwBufferCount,
+ OUT LPDWORD lpNumberOfBytesRecvd,
+ IN OUT LPDWORD lpFlags,
+ OUT LPSOCKADDR lpFrom,
+ IN OUT LPINT lpFromlen,
+ IN LPWSAOVERLAPPED lpOverlapped,
+ IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
- PCATALOG_ENTRY Provider;
- INT Errno;
- INT Code;
+ PCATALOG_ENTRY Provider;
+ INT Errno;
+ INT Code;
- WS_DbgPrint(MAX_TRACE, ("Called.\n"));
+ WS_DbgPrint(MAX_TRACE, ("Called.\n"));
- if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
- WSASetLastError(WSAENOTSOCK);
- return SOCKET_ERROR;
- }
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
- assert(Provider->ProcTable.lpWSPRecvFrom);
+ assert(Provider->ProcTable.lpWSPRecvFrom);
- Code = Provider->ProcTable.lpWSPRecvFrom(s, lpBuffers, dwBufferCount,
- lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped,
- lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
+ Code = Provider->ProcTable.lpWSPRecvFrom(s, lpBuffers, dwBufferCount,
+ lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped,
+ lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
- DereferenceProviderByPointer(Provider);
+ DereferenceProviderByPointer(Provider);
- if (Code == SOCKET_ERROR)
- WSASetLastError(Errno);
+ if (Code == SOCKET_ERROR)
+ WSASetLastError(Errno);
- return Code;
+ return Code;
}
INT
EXPORT
WSASend(
- IN SOCKET s,
- IN LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesSent,
- IN DWORD dwFlags,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
+ IN SOCKET s,
+ IN LPWSABUF lpBuffers,
+ IN DWORD dwBufferCount,
+ OUT LPDWORD lpNumberOfBytesSent,
+ IN DWORD dwFlags,
+ IN LPWSAOVERLAPPED lpOverlapped,
+ IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
- UNIMPLEMENTED
+ PCATALOG_ENTRY Provider;
+ INT Errno;
+ INT Code;
+
+ WS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
+
+ assert(Provider->ProcTable.lpWSPSend);
+
+ Code = Provider->ProcTable.lpWSPSend(s, lpBuffers, dwBufferCount,
+ lpNumberOfBytesSent, dwFlags, lpOverlapped,
+ lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
+
+ DereferenceProviderByPointer(Provider);
+
+ if (Code == SOCKET_ERROR)
+ WSASetLastError(Errno);
- return 0;
+ return Code;
}
INT
EXPORT
WSASendDisconnect(
- IN SOCKET s,
- IN LPWSABUF lpOutboundDisconnectData)
+ IN SOCKET s,
+ IN LPWSABUF lpOutboundDisconnectData)
{
- UNIMPLEMENTED
+ UNIMPLEMENTED
- return 0;
+ return 0;
}
INT
EXPORT
WSASendTo(
- IN SOCKET s,
- IN LPWSABUF lpBuffers,
- IN DWORD dwBufferCount,
- OUT LPDWORD lpNumberOfBytesSent,
- IN DWORD dwFlags,
- IN CONST LPSOCKADDR lpTo,
- IN INT iToLen,
- IN LPWSAOVERLAPPED lpOverlapped,
- IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
+ IN SOCKET s,
+ IN LPWSABUF lpBuffers,
+ IN DWORD dwBufferCount,
+ OUT LPDWORD lpNumberOfBytesSent,
+ IN DWORD dwFlags,
+ IN CONST LPSOCKADDR lpTo,
+ IN INT iToLen,
+ IN LPWSAOVERLAPPED lpOverlapped,
+ IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
- PCATALOG_ENTRY Provider;
- INT Errno;
- INT Code;
+ PCATALOG_ENTRY Provider;
+ INT Errno;
+ INT Code;
- WS_DbgPrint(MAX_TRACE, ("Called.\n"));
+ WS_DbgPrint(MAX_TRACE, ("Called.\n"));
- if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
- WSASetLastError(WSAENOTSOCK);
- return SOCKET_ERROR;
- }
+ if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
+ WSASetLastError(WSAENOTSOCK);
+ return SOCKET_ERROR;
+ }
- assert(Provider->ProcTable.lpWSPSendTo);
+ assert(Provider->ProcTable.lpWSPSendTo);
- Code = Provider->ProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount,
- lpNumberOfBytesSent, dwFlags, lpTo, iToLen, lpOverlapped,
- lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
+ Code = Provider->ProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount,
+ lpNumberOfBytesSent, dwFlags, lpTo, iToLen, lpOverlapped,
+ lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
- DereferenceProviderByPointer(Provider);
+ DereferenceProviderByPointer(Provider);
- if (Code == SOCKET_ERROR)
- WSASetLastError(Errno);
+ if (Code == SOCKET_ERROR)
+ WSASetLastError(Errno);
- return Code;
+ return Code;
}
/* EOF */
*/
#include <ws2_32.h>
-SOCKET
-EXPORT
-accept(
- IN SOCKET s,
- OUT LPSOCKADDR addr,
- OUT INT FAR* addrlen)
-{
- UNIMPLEMENTED
-
- return INVALID_SOCKET;
-}
-
-INT
-EXPORT
-bind(
- IN SOCKET s,
- IN CONST LPSOCKADDR name,
- IN INT namelen)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-INT
-EXPORT
-connect(
- IN SOCKET s,
- IN CONST LPSOCKADDR name,
- IN INT namelen)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
INT
EXPORT
getpeername(
return 0;
}
-ULONG
-EXPORT
-htonl(
- IN ULONG hostlong)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-USHORT
-EXPORT
-htons(
- IN USHORT hostshort)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
INT
EXPORT
ioctlsocket(
return 0;
}
-INT
-EXPORT
-listen(
- IN SOCKET s,
- IN INT backlog)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-ULONG
-EXPORT
-ntohl(
- IN ULONG netlong)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
-USHORT
-EXPORT
-ntohs(
- IN USHORT netshort)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
INT
EXPORT
setsockopt(
return 0;
}
-SOCKET
-EXPORT
-socket(
- IN INT af,
- IN INT type,
- IN INT protocol)
-{
- UNIMPLEMENTED
-
- return INVALID_SOCKET;
-}
-
-SOCKET
-EXPORT
-WSAAccept(
- IN SOCKET s,
- OUT LPSOCKADDR addr,
- IN OUT LPINT addrlen,
- IN LPCONDITIONPROC lpfnCondition,
- IN DWORD dwCallbackData)
-{
- UNIMPLEMENTED
-
- return INVALID_SOCKET;
-}
-
INT
EXPORT
WSAAsyncSelect(
return 0;
}
-INT
-EXPORT
-WSAConnect(
- IN SOCKET s,
- IN CONST LPSOCKADDR name,
- IN INT namelen,
- IN LPWSABUF lpCallerData,
- OUT LPWSABUF lpCalleeData,
- IN LPQOS lpSQOS,
- IN LPQOS lpGQOS)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
INT
EXPORT
WSADuplicateSocketA(
return 0;
}
-INT
-EXPORT
-WSAEnumNetworkEvents(
- IN SOCKET s,
- IN WSAEVENT hEventObject,
- OUT LPWSANETWORKEVENTS lpNetworkEvents)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
INT
EXPORT
WSAEnumProtocolsA(
return 0;
}
-INT
-EXPORT
-WSAEventSelect(
- IN SOCKET s,
- IN WSAEVENT hEventObject,
- IN LONG lNetworkEvents)
-{
- UNIMPLEMENTED
-
- return 0;
-}
-
BOOL
EXPORT
WSAGetOverlappedResult(
IN SOCKET ProposedHandle,
OUT LPINT lpErrno)
{
- PCATALOG_ENTRY Provider;
- SOCKET Socket;
+ PCATALOG_ENTRY Provider;
+ SOCKET Socket;
- WS_DbgPrint(MAX_TRACE, ("dwCatalogEntryId (%d) ProposedHandle (0x%X).\n",
- dwCatalogEntryId, ProposedHandle));
+ WS_DbgPrint(MAX_TRACE, ("dwCatalogEntryId (%d) ProposedHandle (0x%X).\n",
+ dwCatalogEntryId, ProposedHandle));
- Provider = LocateProviderById(dwCatalogEntryId);
- if (!Provider) {
- WS_DbgPrint(MIN_TRACE, ("Provider with catalog entry id (%d) was not found.\n",
- dwCatalogEntryId));
- *lpErrno = WSAEINVAL;
- return INVALID_SOCKET;
- }
+ Provider = LocateProviderById(dwCatalogEntryId);
+ if (!Provider) {
+ WS_DbgPrint(MIN_TRACE, ("Provider with catalog entry id (%d) was not found.\n",
+ dwCatalogEntryId));
+ *lpErrno = WSAEINVAL;
+ return INVALID_SOCKET;
+ }
- Socket = (SOCKET)CreateProviderHandle(ProposedHandle, Provider);
+ Socket = (SOCKET)CreateProviderHandle(
+ ProposedHandle,
+ Provider);
- *lpErrno = NO_ERROR;
+ *lpErrno = NO_ERROR;
- return Socket;
+ return Socket;
}
-# $Id: Makefile,v 1.44 2001/06/14 21:05:07 jfilby Exp $
+# $Id: Makefile,v 1.45 2001/07/04 20:40:20 chorns Exp $
#
# ReactOS Operating System
#
ifeq ($(DOSCLI),yes)
-CLEAN_FILES = $(OBJECTS_PATH)\*.o cc\*.o cm\*.o dbg\*.o ex\*.o hal\x86\*.o io\*.o \
+CLEAN_FILES = $(OBJECTS_PATH)\*.o cc\*.o cm\*.o dbg\*.o dbg\i386\*.o ex\*.o hal\x86\*.o io\*.o \
ke\*.o ldr\*.o mm\*.o nt\*.o ob\*.o ps\*.o rtl\*.o se\*.o \
ke\i386\*.o mm\i386\*.o fs\*.o po\*.o nls\*.o lpc\*.o \
kd\*.o $(TARGETNAME).o $(TARGETNAME).a junk.tmp base.tmp temp.exp \
$(TARGETNAME).exe $(TARGETNAME).nostrip.exe $(TARGETNAME).sym $(TARGETNAME).coff $(D1_FILES)
else
-CLEAN_FILES = $(OBJECTS_PATH)/*.o cc/*.o cm/*.o dbg/*.o ex/*.o hal/x86/*.o io/*.o \
+CLEAN_FILES = $(OBJECTS_PATH)/*.o cc/*.o cm/*.o dbg/*.o dbg/i386/*.o ex/*.o hal/x86/*.o io/*.o \
ke/*.o ldr/*.o mm/*.o nt/*.o ob/*.o ps/*.o rtl/*.o se/*.o \
ke/i386/*.o mm/i386/*.o fs/*.o po/*.o nls/*.o lpc/*.o \
kd/*.o $(TARGETNAME).o $(TARGETNAME).a junk.tmp base.tmp temp.exp \
{
ExInitTimeZoneInfo();
ExInitializeWorkerThreads();
+ ExpInitLookasideLists();
ExpWin32kInit();
}
-/* $Id: list.c,v 1.3 2001/06/20 19:59:35 ekohl Exp $
+/* $Id: list.c,v 1.4 2001/07/04 20:40:20 chorns Exp $
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ex/list.c
- * PURPOSE: Manages double linked lists, single linked lists and
- * sequenced lists
- * PROGRAMMER: David Welch (welch@mcmail.com)
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ex/list.c
+ * PURPOSE: Manages double linked lists, single linked lists and
+ * sequenced lists
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * 02-07-2001 CSH Implemented sequenced lists
*/
/* INCLUDES *****************************************************************/
/*
* FUNCTION: Inserts an entry at the head of a doubly linked list
* ARGUMENTS:
- * ListHead = Points to the head of the list
+ * ListHead = Points to the head of the list
* ListEntry = Points to the entry to be inserted
- * Lock = Caller supplied spinlock used to synchronise access
+ * Lock = Caller supplied spinlock used to synchronize access
* RETURNS: The previous head of the list
*/
{
/*
* FUNCTION: Removes the head of a double linked list
* ARGUMENTS:
- * Head = List head
+ * Head = Points to the head of the list
* Lock = Lock for synchronizing access to the list
* RETURNS: The removed entry
*/
/*
* FUNCTION: Removes the tail of a double linked list
* ARGUMENTS:
- * Head = List head
+ * Head = Points to the head of the list
* Lock = Lock for synchronizing access to the list
* RETURNS: The removed entry
*/
PSINGLE_LIST_ENTRY FASTCALL
-ExInterlockedPopEntrySList(PSLIST_HEADER ListHead,
- PKSPIN_LOCK Lock)
+ExInterlockedPopEntrySList(
+ PSLIST_HEADER ListHead,
+ PKSPIN_LOCK Lock)
+/*
+ * FUNCTION: Removes (pops) an entry from a sequenced list
+ * ARGUMENTS:
+ * ListHead = Points to the head of the list
+ * Lock = Lock for synchronizing access to the list
+ * RETURNS: The removed entry
+ */
{
- UNIMPLEMENTED;
+ PSINGLE_LIST_ENTRY ret;
+ KIRQL oldlvl;
+
+ KeAcquireSpinLock(Lock,&oldlvl);
+ ret = PopEntryList(&ListHead->s.Next);
+ if (ret)
+ {
+ ListHead->s.Depth--;
+ ListHead->s.Sequence++;
+ }
+ KeReleaseSpinLock(Lock,oldlvl);
+ return(ret);
}
PSINGLE_LIST_ENTRY FASTCALL
-ExInterlockedPushEntrySList(PSLIST_HEADER ListHead,
- PSINGLE_LIST_ENTRY ListEntry,
- PKSPIN_LOCK Lock)
+ExInterlockedPushEntrySList(
+ PSLIST_HEADER ListHead,
+ PSINGLE_LIST_ENTRY ListEntry,
+ PKSPIN_LOCK Lock)
+/*
+ * FUNCTION: Inserts (pushes) an entry into a sequenced list
+ * ARGUMENTS:
+ * ListHead = Points to the head of the list
+ * ListEntry = Points to the entry to be inserted
+ * Lock = Caller supplied spinlock used to synchronize access
+ * RETURNS: The previous head of the list
+ */
{
- UNIMPLEMENTED;
+ KIRQL oldlvl;
+ PSINGLE_LIST_ENTRY ret;
+
+ KeAcquireSpinLock(Lock,&oldlvl);
+ ret=ListHead->s.Next.Next;
+ PushEntryList(&ListHead->s.Next,ListEntry);
+ ListHead->s.Depth++;
+ ListHead->s.Sequence++;
+ KeReleaseSpinLock(Lock,oldlvl);
+ return(ret);
}
PSINGLE_LIST_ENTRY ListHead,
PKSPIN_LOCK Lock
)
+/*
+ * FUNCTION: Removes (pops) an entry from a singly list
+ * ARGUMENTS:
+ * ListHead = Points to the head of the list
+ * Lock = Lock for synchronizing access to the list
+ * RETURNS: The removed entry
+ */
{
PSINGLE_LIST_ENTRY ret;
KIRQL oldlvl;
PSINGLE_LIST_ENTRY ListEntry,
PKSPIN_LOCK Lock
)
+/*
+ * FUNCTION: Inserts (pushes) an entry into a singly linked list
+ * ARGUMENTS:
+ * ListHead = Points to the head of the list
+ * ListEntry = Points to the entry to be inserted
+ * Lock = Caller supplied spinlock used to synchronize access
+ * RETURNS: The previous head of the list
+ */
{
KIRQL oldlvl;
PSINGLE_LIST_ENTRY ret;
-/* $Id: lookas.c,v 1.2 2000/07/02 17:31:49 ekohl Exp $
+/* $Id: lookas.c,v 1.3 2001/07/04 20:40:20 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/lookas.c
* PURPOSE: Lookaside lists
- * PROGRAMMER: David Welch (welch@mcmail.com)
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
- * Created 22/05/98
+ * 22-05-1998 DW Created
+ * 02-07-2001 CSH Implemented lookaside lists
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
-
+#include <internal/ex.h>
+#define NDEBUG
#include <internal/debug.h>
+/* GLOBALS *******************************************************************/
+
+LIST_ENTRY ExpNonPagedLookasideListHead;
+KSPIN_LOCK ExpNonPagedLookasideListLock;
+
+LIST_ENTRY ExpPagedLookasideListHead;
+KSPIN_LOCK ExpPagedLookasideListLock;
+
+PLOOKASIDE_MINMAX_ROUTINE ExpMinMaxRoutine;
+
/* FUNCTIONS *****************************************************************/
+VOID ExpDefaultMinMax(
+ POOL_TYPE PoolType,
+ ULONG Size,
+ PUSHORT MinimumDepth,
+ PUSHORT MaximumDepth)
+/*
+ * FUNCTION: Determines the minimum and maximum depth of a new lookaside list
+ * ARGUMENTS:
+ * Type = Type of executive pool
+ * Size = Size in bytes of each element in the new lookaside list
+ * MinimumDepth = Buffer to store minimum depth of the new lookaside list in
+ * MaximumDepth = Buffer to store maximum depth of the new lookaside list in
+ */
+{
+ /* FIXME: Could probably do some serious computing here */
+ if ((PoolType == NonPagedPool) ||
+ (PoolType == NonPagedPoolMustSucceed))
+ {
+ *MinimumDepth = 10;
+ *MaximumDepth = 100;
+ }
+ else
+ {
+ *MinimumDepth = 20;
+ *MaximumDepth = 200;
+ }
+}
+
+
+PVOID ExpDefaultAllocate(
+ POOL_TYPE PoolType,
+ ULONG NumberOfBytes,
+ ULONG Tag)
+/*
+ * FUNCTION: Default allocate function for lookaside lists
+ * ARGUMENTS:
+ * Type = Type of executive pool
+ * NumberOfBytes = Number of bytes to allocate
+ * Tag = Tag to use
+ * RETURNS:
+ * Pointer to allocated memory, or NULL if there is not enough free resources
+ */
+{
+ return ExAllocatePool(PoolType, NumberOfBytes);
+}
+
+
+VOID ExpDefaultFree(
+ PVOID Buffer)
+/*
+ * FUNCTION: Default free function for lookaside lists
+ * ARGUMENTS:
+ * Buffer = Pointer to memory to free
+ */
+{
+ return ExFreePool(Buffer);
+}
+
+
+VOID
+ExpInitLookasideLists()
+{
+ InitializeListHead(&ExpNonPagedLookasideListHead);
+ KeInitializeSpinLock(&ExpNonPagedLookasideListLock);
+
+ InitializeListHead(&ExpPagedLookasideListHead);
+ KeInitializeSpinLock(&ExpPagedLookasideListLock);
+
+ /* FIXME: Possibly configure the algorithm using the registry */
+ ExpMinMaxRoutine = ExpDefaultMinMax;
+}
+
PVOID
STDCALL
ExAllocateFromPagedLookasideList (
PPAGED_LOOKASIDE_LIST Lookaside
)
{
- UNIMPLEMENTED;
+ PVOID Entry;
+
+ /* Try to obtain an entry from the lookaside list. If that fails, try to
+ allocate a new entry with the allocate method for the lookaside list */
+
+ Lookaside->TotalAllocates++;
+
+// ExAcquireFastMutex(&Lookaside->Lock);
+
+ Entry = PopEntrySList(&Lookaside->ListHead);
+
+// ExReleaseFastMutex(&Lookaside->Lock);
+
+ if (Entry)
+ return Entry;
+
+ Lookaside->AllocateMisses++;
+
+ Entry = (*Lookaside->Allocate)(Lookaside->Type,
+ Lookaside->Size,
+ Lookaside->Tag);
+
+ return Entry;
}
VOID
PNPAGED_LOOKASIDE_LIST Lookaside
)
{
- UNIMPLEMENTED;
+ KIRQL OldIrql;
+ PVOID Entry;
+
+ /* Pop all entries off the stack and release the resources allocated
+ for them */
+ while ((Entry = ExInterlockedPopEntrySList(
+ &Lookaside->ListHead,
+ &Lookaside->Lock)) != NULL)
+ {
+ (*Lookaside->Free)(Entry);
+ }
+
+ KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql);
+ RemoveEntryList(&Lookaside->ListEntry);
+ KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql);
}
VOID
PPAGED_LOOKASIDE_LIST Lookaside
)
{
- UNIMPLEMENTED;
+ KIRQL OldIrql;
+ PVOID Entry;
+
+ /* Pop all entries off the stack and release the resources allocated
+ for them */
+ for (;;)
+ {
+
+// ExAcquireFastMutex(&Lookaside->Lock);
+
+ Entry = PopEntrySList(&Lookaside->ListHead);
+ if (!Entry)
+ break;
+
+// ExReleaseFastMutex(&Lookaside->Lock);
+
+ (*Lookaside->Free)(Entry);
+ }
+
+ KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql);
+ RemoveEntryList(&Lookaside->ListEntry);
+ KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql);
}
VOID
PVOID Entry
)
{
- UNIMPLEMENTED;
+ Lookaside->TotalFrees++;
+
+ if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->MinimumDepth)
+ {
+ Lookaside->FreeMisses++;
+ (*Lookaside->Free)(Entry);
+ }
+ else
+ {
+// ExAcquireFastMutex(&Lookaside->Lock);
+ PushEntrySList(&Lookaside->ListHead, (PSINGLE_LIST_ENTRY)Entry);
+// ExReleaseFastMutex(&Lookaside->Lock);
+ }
}
VOID
ULONG Tag,
USHORT Depth)
{
- UNIMPLEMENTED
+ DPRINT("Initializing nonpaged lookaside list at 0x%X\n", Lookaside);
+
+ Lookaside->TotalAllocates = 0;
+ Lookaside->AllocateMisses = 0;
+ Lookaside->TotalFrees = 0;
+ Lookaside->FreeMisses = 0;
+ Lookaside->Type = NonPagedPool;
+ Lookaside->Tag = Tag;
+
+ /* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in
+ the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */
+ if (Size < sizeof(SINGLE_LIST_ENTRY))
+ Lookaside->Size = sizeof(SINGLE_LIST_ENTRY);
+ else
+ Lookaside->Size = Size;
+
+ if (Allocate)
+ Lookaside->Allocate = Allocate;
+ else
+ Lookaside->Allocate = ExpDefaultAllocate;
+
+ if (Free)
+ Lookaside->Free = Free;
+ else
+ Lookaside->Free = ExpDefaultFree;
+
+ ExInitializeSListHead(&Lookaside->ListHead);
+ KeInitializeSpinLock(&Lookaside->Lock);
+
+ /* Determine minimum and maximum number of entries on the lookaside list
+ using the configured algorithm */
+ (*ExpMinMaxRoutine)(
+ NonPagedPool,
+ Lookaside->Size,
+ &Lookaside->MinimumDepth,
+ &Lookaside->MaximumDepth);
+
+ ExInterlockedInsertTailList(
+ &ExpNonPagedLookasideListHead,
+ &Lookaside->ListEntry,
+ &ExpNonPagedLookasideListLock);
}
VOID
USHORT Depth
)
{
- UNIMPLEMENTED
+ DPRINT("Initializing paged lookaside list at 0x%X\n", Lookaside);
+
+ Lookaside->TotalAllocates = 0;
+ Lookaside->AllocateMisses = 0;
+ Lookaside->TotalFrees = 0;
+ Lookaside->FreeMisses = 0;
+ Lookaside->Type = PagedPool;
+ Lookaside->Tag = Tag;
+
+ /* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in
+ the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */
+ if (Size < sizeof(SINGLE_LIST_ENTRY))
+ Lookaside->Size = sizeof(SINGLE_LIST_ENTRY);
+ else
+ Lookaside->Size = Size;
+
+ if (Allocate)
+ Lookaside->Allocate = Allocate;
+ else
+ Lookaside->Allocate = ExpDefaultAllocate;
+
+ if (Free)
+ Lookaside->Free = Free;
+ else
+ Lookaside->Free = ExpDefaultFree;
+
+ ExInitializeSListHead(&Lookaside->ListHead);
+ //ExInitializeFastMutex(&Lookaside->Lock);
+
+ /* Determine minimum and maximum number of entries on the lookaside list
+ using the configured algorithm */
+ (*ExpMinMaxRoutine)(
+ PagedPool,
+ Lookaside->Size,
+ &Lookaside->MinimumDepth,
+ &Lookaside->MaximumDepth);
+
+ ExInterlockedInsertTailList(
+ &ExpPagedLookasideListHead,
+ &Lookaside->ListEntry,
+ &ExpPagedLookasideListLock);
}
/* EOF */
typedef struct _WINSTATION_OBJECT
{
- CSHORT Type;
- CSHORT Size;
-
- KSPIN_LOCK Lock;
- UNICODE_STRING Name;
- LIST_ENTRY DesktopListHead;
- PRTL_ATOM_TABLE AtomTable;
- PVOID HandleTable;
- /* FIXME: Clipboard */
+ CSHORT Type;
+ CSHORT Size;
+
+ KSPIN_LOCK Lock;
+ UNICODE_STRING Name;
+ LIST_ENTRY DesktopListHead;
+ PRTL_ATOM_TABLE AtomTable;
+ PVOID HandleTable;
+ /* FIXME: Clipboard */
} WINSTATION_OBJECT, *PWINSTATION_OBJECT;
typedef struct _DESKTOP_OBJECT
{
- CSHORT Type;
- CSHORT Size;
+ CSHORT Type;
+ CSHORT Size;
- LIST_ENTRY ListEntry;
- KSPIN_LOCK Lock;
- UNICODE_STRING Name;
- struct _WINSTATION_OBJECT *WindowStation;
+ LIST_ENTRY ListEntry;
+ KSPIN_LOCK Lock;
+ UNICODE_STRING Name;
+ struct _WINSTATION_OBJECT *WindowStation;
} DESKTOP_OBJECT, *PDESKTOP_OBJECT;
+
+typedef VOID (*PLOOKASIDE_MINMAX_ROUTINE)(
+ POOL_TYPE PoolType,
+ ULONG Size,
+ PUSHORT MinimumDepth,
+ PUSHORT MaximumDepth);
+
/* GLOBAL VARIABLES *********************************************************/
TIME_ZONE_INFORMATION SystemTimeZoneInfo;
ExInitTimeZoneInfo (VOID);
VOID
ExInitializeWorkerThreads(VOID);
+VOID
+ExpInitLookasideLists(VOID);
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_EXECUTIVE_H */
-
-
SECURITY_IMPERSONATION_LEVEL Level; // 0x8
} PS_IMPERSONATION_INFO, *PPS_IMPERSONATION_INFO;
-struct _WIN32THREADDATA;
+
+typedef struct _W32THREAD
+{
+ PVOID MessageQueue;
+} __attribute__((packed)) W32THREAD, *PW32THREAD;
+
typedef struct _ETHREAD
{
*/
struct _EPROCESS* OldProcess; /* 240/26C */
- /* Pointer to win32 private thread data */
- struct _WIN32THREADDATA *Win32ThreadData;
+ PW32THREAD Win32Thread;
} __attribute__((packed)) ETHREAD, *PETHREAD;
UCHAR DisableBoost; /* 067 */
} KPROCESS, *PKPROCESS;
-struct _WIN32PROCESSDATA;
+
+typedef struct _W32PROCESS
+{
+} __attribute__((packed)) W32PROCESS, *PW32PROCESS;
+
struct _EPROCESS
{
UCHAR SubSystemMinorVersion;
UCHAR SubSystemMajorVersion;
USHORT SubSystemVersion;
- struct _WIN32PROCESSDATA *Win32Process;
+ PW32PROCESS Win32Process;
+ HANDLE Win32WindowStation;
/*
* Added by David Welch (welch@mcmail.com)
-/* $Id: create.c,v 1.45 2001/06/16 14:07:30 ekohl Exp $
+/* $Id: create.c,v 1.46 2001/07/04 20:40:21 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
FileObject->FileName.Buffer =
ExAllocatePoolWithTag(NonPagedPool,
- (ObjectAttributes->ObjectName->Length+1)*2,
+ (ObjectAttributes->ObjectName->Length+1)*sizeof(WCHAR),
TAG_FILE_NAME);
FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
FileObject->FileName.MaximumLength =
(PVOID*)&FileObject);
if (!NT_SUCCESS(Status))
{
- DPRINT1("ObCreateObject() failed!\n");
+ DPRINT("ObCreateObject() failed!\n");
return (Status);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
if (Irp == NULL)
{
+ ZwClose(*FileHandle);
return (STATUS_UNSUCCESSFUL);
}
{
DPRINT("Failing create request with status %x\n", Status);
ZwClose(*FileHandle);
- (*FileHandle) = 0;
}
assert_irql(PASSIVE_LEVEL);
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: catch.c,v 1.14 2001/03/20 16:09:44 dwelch Exp $
+/* $Id: catch.c,v 1.15 2001/07/04 20:40:21 chorns Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/catch.c
ExRaiseStatus (IN NTSTATUS Status)
{
DbgPrint("ExRaiseStatus(%x)\n",Status);
- for(;;);
+ KeBugCheck(0);
}
-; $Id: ntoskrnl.def,v 1.108 2001/06/16 14:05:29 ekohl Exp $
+; $Id: ntoskrnl.def,v 1.109 2001/07/04 20:40:20 chorns Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
ExGetExclusiveWaiterCount@4
ExGetPreviousMode@0
ExGetSharedWaiterCount@4
-ExInitializeNPagedLookasideList
-ExInitializePagedLookasideList
+ExInitializeNPagedLookasideList@28
+ExInitializePagedLookasideList@28
ExInitializeResource@4
ExInitializeResourceLite@4
ExInitializeZone@16
-/* $Id: create.c,v 1.33 2001/06/16 14:11:15 ekohl Exp $
+/* $Id: create.c,v 1.34 2001/07/04 20:40:21 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
&PiNextThreadUniqueId);
Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId;
Thread->DeadThread = 0;
- Thread->Win32ThreadData = 0;
+ Thread->Win32Thread = 0;
DPRINT("Thread->Cid.UniqueThread %d\n",Thread->Cid.UniqueThread);
*ThreadPtr = Thread;
#include <windows.h>
#include <ddk/ntddk.h>
-#include <../ntoskrnl/include/internal/ex.h>
+#include <internal/ex.h>
+#include <internal/ps.h>
-/*
-* FIXME: NtCurrentPeb() does not work (returns 0)
#define PROCESS_WINDOW_STATION() \
- (HWINSTA)(NtCurrentPeb()->ProcessWindowStation);
+ ((HWINSTA)(IoGetCurrentProcess()->Win32WindowStation))
#define SET_PROCESS_WINDOW_STATION(WinSta) \
- (NtCurrentPeb()->ProcessWindowStation = (PVOID)(WinSta));
-*/
-
-#define PROCESS_WINDOW_STATION() \
- ((HWINSTA)(((PPEB)PEB_BASE)->ProcessWindowStation))
-
-#define SET_PROCESS_WINDOW_STATION(WinSta) \
- (((PPEB)PEB_BASE)->ProcessWindowStation = (PVOID)(WinSta))
+ ((IoGetCurrentProcess()->Win32WindowStation) = (PVOID)(WinSta))
NTSTATUS
-# $Id: makefile,v 1.34 2001/06/22 12:17:24 ekohl Exp $
+# $Id: makefile,v 1.35 2001/07/04 20:40:24 chorns Exp $
#
# WIN32K.SYS build spec
#
# from atheos appserver makefile
COPTS = -pipe -O3 -I./freetype/include -c -Wall
-CFLAGS = -D__NTDRIVER__ -I. -DUNICODE
+CFLAGS = -D__NTDRIVER__ -I. -I$(PATH_TO_TOP)/ntoskrnl/include -DUNICODE
#define FT_FLAT_COMPILE
-/* $Id: guicheck.c,v 1.1 2001/06/12 17:50:29 chorns Exp $
+/* $Id: guicheck.c,v 1.2 2001/07/04 20:40:24 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
VOID
GuiCheck(VOID)
{
- if (NtCurrentTeb()->MessageQueue)
+/* if (NtCurrentTeb()->MessageQueue)
return;
- NtCurrentTeb()->MessageQueue = MsqCreateMessageQueue();
+ NtCurrentTeb()->MessageQueue = MsqCreateMessageQueue();*/
}
/* EOF */