Updated clean rules.

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
This commit is contained in:
Casper Hornstrup 2001-07-04 20:40:24 +00:00
parent df84ec15d8
commit 3a9de284ad
78 changed files with 6492 additions and 3339 deletions

View file

@ -61,7 +61,7 @@ APPS = args hello test cat bench apc shm lpc thread event file gditest \
pteb consume dump_shared_data vmtest regtest alive mstest nptest \
objdir atomtest
#NET_APPS = ping roshttpd
#NET_APPS = ping roshttpd telnet
NET_APPS = ping
@ -71,8 +71,9 @@ all: buildno $(COMPONENTS) $(BUS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES
.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
@ -104,7 +105,7 @@ install: rcopy$(EXE_POSTFIX) rmkdir$(EXE_POSTFIX) make_install_dirs autoexec_ins
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

View file

@ -1,4 +1,4 @@
# $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
@ -14,7 +14,7 @@ all: $(TARGET).sys
.phony: all
clean:
- $(RM) $(TARGET).o
- $(RM) *.o
- $(RM) $(TARGET).coff
- $(RM) junk.tmp
- $(RM) base.tmp

View file

@ -81,6 +81,26 @@ AfdDispatch(
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));

View file

@ -9,6 +9,74 @@
*/
#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)
@ -27,6 +95,7 @@ NTSTATUS AfdDispBind(
PFILE_REQUEST_BIND Request;
PFILE_REPLY_BIND Reply;
PAFDFCB FCB;
INT Errno;
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
@ -39,21 +108,19 @@ NTSTATUS AfdDispBind(
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;
@ -87,14 +154,41 @@ NTSTATUS AfdDispListen(
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));
@ -140,6 +234,9 @@ NTSTATUS AfdDispSendTo(
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);
@ -274,9 +371,7 @@ NTSTATUS AfdDispRecvFrom(
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"));
@ -291,48 +386,14 @@ NTSTATUS AfdDispRecvFrom(
Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
/* Since we're using bufferred I/O */
Request->Buffers = (LPWSABUF)(Request + 1);
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));
}
Status = AfdpDispRecv(
Irp,
FCB,
Request,
Reply);
} else {
Status = STATUS_INVALID_PARAMETER;
}
@ -350,10 +411,11 @@ typedef enum {
} SelectOperation;
DWORD AfdDispSelectEx(
DWORD AfdpDispSelectEx(
LPFD_SET FDSet,
SelectOperation Operation)
{
PFILE_OBJECT FileObject;
NTSTATUS Status;
PAFDFCB Current;
KIRQL OldIrql;
@ -367,14 +429,20 @@ DWORD AfdDispSelectEx(
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:
@ -395,7 +463,7 @@ DWORD AfdDispSelectEx(
break;
}
ObDereferenceObject(Current);
ObDereferenceObject(FileObject);
}
}
@ -407,6 +475,7 @@ NTSTATUS AfdDispSelect(
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
@ -438,16 +507,16 @@ NTSTATUS AfdDispSelect(
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));
@ -463,4 +532,312 @@ NTSTATUS AfdDispSelect(
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 */

View file

@ -96,11 +96,13 @@ NTSTATUS AfdEventReceiveDatagramHandler(
{
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"));
@ -108,9 +110,8 @@ NTSTATUS AfdEventReceiveDatagramHandler(
BytesAvailable, *(PULONG)SourceAddress));
ReceiveBuffer = ExAllocatePool(NonPagedPool, BytesAvailable);
if (!ReceiveBuffer) {
if (!ReceiveBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
}
/*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList(
&BufferLookasideList);*/
@ -134,6 +135,8 @@ NTSTATUS AfdEventReceiveDatagramHandler(
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);
@ -141,11 +144,15 @@ NTSTATUS AfdEventReceiveDatagramHandler(
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);
}

View file

@ -177,7 +177,8 @@ AfdCreate(
Status = STATUS_INSUFFICIENT_RESOURCES;
if (!NT_SUCCESS(Status)) {
/* FIXME: Cleanup */
/* FIXME: Cleanup */
AFD_DbgPrint(MAX_TRACE, ("FIXME: Cleanup.\n"));
}
Irp->IoStatus.Status = Status;
@ -252,7 +253,10 @@ AfdClose(
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;
}

View file

@ -39,7 +39,7 @@ VOID DisplayBuffer(
inline DWORD TdiAddressSizeFromName(
LPSOCKADDR Name)
LPSOCKADDR Name)
/*
* FUNCTION: Returns the size of a TDI style address equivalent to a
* WinSock style name
@ -49,19 +49,19 @@ inline DWORD TdiAddressSizeFromName(
* 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:
@ -69,122 +69,151 @@ VOID TdiBuildAddressIPv4(
* 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;
}
@ -283,44 +312,44 @@ NTSTATUS TdiOpenAddressFileIPv4(
* Status of operation
*/
{
PFILE_FULL_EA_INFORMATION EaInfo;
PTA_ADDRESS_IP Address;
NTSTATUS Status;
ULONG EaLength;
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));
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;
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;
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:
@ -332,21 +361,187 @@ NTSTATUS TdiOpenAddressFile(
* Status of operation
*/
{
NTSTATUS Status;
NTSTATUS Status;
switch (Name->sa_family) {
case AF_INET:
Status = TdiOpenAddressFileIPv4(
DeviceName,
Name,
AddressHandle,
AddressObject);
break;
default:
Status = STATUS_INVALID_PARAMETER;
}
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;
}
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;
}
@ -368,39 +563,42 @@ NTSTATUS TdiSetEventHandler(
* 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;
}
@ -428,9 +626,13 @@ NTSTATUS TdiQueryDeviceControl(
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,
@ -438,14 +640,13 @@ NTSTATUS TdiQueryDeviceControl(
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;
@ -650,6 +851,7 @@ NTSTATUS TdiSend(
DWORD TdiAddressSize;
PVOID BaseAddress;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
PMDL Mdl;
@ -681,11 +883,13 @@ NTSTATUS TdiSend(
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);
@ -737,7 +941,7 @@ DisplayBuffer(Request->Buffers->buf, Request->Buffers->len);
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);
@ -774,6 +978,7 @@ NTSTATUS TdiSendDatagram(
IO_STATUS_BLOCK Iosb;
DWORD TdiAddressSize;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
@ -801,11 +1006,13 @@ NTSTATUS TdiSendDatagram(
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);
@ -847,7 +1054,7 @@ NTSTATUS TdiSendDatagram(
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);
@ -886,6 +1093,7 @@ NTSTATUS TdiReceiveDatagram(
IO_STATUS_BLOCK Iosb;
DWORD TdiAddressSize;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
PMDL Mdl;
@ -935,11 +1143,13 @@ NTSTATUS TdiReceiveDatagram(
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);
@ -982,7 +1192,7 @@ NTSTATUS TdiReceiveDatagram(
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);

View file

@ -83,12 +83,16 @@ typedef struct _AFDFCB {
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;
@ -242,6 +246,26 @@ NTSTATUS AfdDispSelect(
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(
@ -312,60 +336,73 @@ VOID BuildIPv4Header(
/* 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 */

View file

@ -43,7 +43,6 @@ VOID RealTransmit(
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopLock);
for (;;) {
@ -52,10 +51,10 @@ VOID RealTransmit(
if (!NdisPacket)
break;
TI_DbgPrint(MAX_TRACE, ("NdisPacket (0x%X)\n", NdisPacket));
LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
KeReleaseSpinLockFromDpcLevel(&LoopLock);
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
@ -63,25 +62,16 @@ VOID RealTransmit(
&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);
}
@ -132,8 +122,8 @@ VOID LoopTransmit(
/* If LoopTransmit is not running (or scheduled), schedule it to run */
if (!LoopBusy) {
ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
LoopBusy = TRUE;
ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
}
KeReleaseSpinLock(&LoopLock, OldIrql);

View file

@ -7,7 +7,6 @@
#ifndef __ADDRESS_H
#define __ADDRESS_H
/*
* Initialize an IPv4 style address
* VOID AddrInitIPv4(
@ -16,9 +15,11 @@
*/
#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
@ -28,6 +29,9 @@ PCHAR A2S(
#endif /* DBG */
VOID IPAddressFree(
PVOID Object);
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address);
@ -37,6 +41,11 @@ NTSTATUS AddrGetAddress(
PUSHORT Port,
PIP_ADDRESS *Cache);
NTSTATUS AddrBuildAddress(
PTA_ADDRESS TdiAddress,
PIP_ADDRESS *Address,
PUSHORT Port);
BOOLEAN AddrIsEqual(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2);

View file

@ -11,44 +11,48 @@
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 */

View file

@ -28,6 +28,7 @@
#define DEBUG_ROUTER 0x00040000
#define DEBUG_RCACHE 0x00080000
#define DEBUG_NCACHE 0x00100000
#define DEBUG_CPOINT 0x00200000
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG

View file

@ -10,22 +10,31 @@
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 */

View file

@ -7,6 +7,9 @@
#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;
@ -17,12 +20,14 @@ typedef IPv6_RAW_ADDRESS *PIPv6_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 */
@ -56,7 +61,9 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)(
/* 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 */
@ -88,8 +95,10 @@ typedef struct PACKET_CONTEXT {
/* 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 */
@ -102,11 +111,13 @@ typedef struct _ADDRESS_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;
@ -133,8 +144,10 @@ typedef struct _LLIP_BIND_INFO {
/* 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 */
@ -150,6 +163,7 @@ typedef struct _IP_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 */
@ -190,6 +204,8 @@ extern KSPIN_LOCK PrefixListLock;
extern UINT MaxLLHeaderSize;
extern UINT MinLLFrameSize;
PIP_PACKET IPCreatePacket(
ULONG Type);
PNET_TABLE_ENTRY IPCreateNTE(
PIP_INTERFACE IF,

View file

@ -17,9 +17,11 @@ typedef struct NEIGHBOR_CACHE_TABLE {
/* 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 */

View file

@ -44,6 +44,9 @@ typedef struct IPDATAGRAM_REASSEMBLY {
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(

View file

@ -24,7 +24,9 @@ typedef struct ROUTE_CACHE_NODE {
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 */
@ -37,6 +39,9 @@ typedef struct ROUTE_CACHE_NODE {
#define RCN_STATE_COMPUTED 0x01 /* RCN is computed */
extern NPAGED_LOOKASIDE_LIST IPRCNList;
#define IsExternalRCN(RCN) \
(RCN == ExternalRCN)

View file

@ -14,6 +14,7 @@
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 */

View file

@ -8,6 +8,23 @@
#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);

View file

@ -7,11 +7,105 @@
#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 */

View file

@ -7,24 +7,65 @@
#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(
@ -32,10 +73,6 @@
*/
#define ReferenceObject(Object) \
{ \
DEBUG_REFCHECK(Object); \
TI_DbgPrint(DEBUG_REFCOUNT, ("Referencing object at (0x%X). RefCount (%d).\n", \
(Object), (Object)->RefCount)); \
\
InterlockedIncrement(&((Object)->RefCount)); \
}
@ -45,14 +82,19 @@
*/
#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,
@ -93,27 +135,37 @@ typedef struct _DATAGRAM_SEND_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;
#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 (TCP/UDP) endpoint context structure. The FileObject->FsContext
/* 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 */
@ -124,36 +176,49 @@ typedef struct _ADDRESS_FILE {
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;
/* 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;
/* Receive indication handler */
PTDI_IND_RECEIVE ReceiveHandler;
PVOID ReceiveHandlerContext;
BOOL RegisteredReceiveHandler;
/* Receive datagram indication handler */
PTDI_IND_RECEIVE_DATAGRAM ReceiveDatagramHandler;
PVOID ReceiveDatagramHandlerContext;
BOOL RegisteredReceiveDatagramHandler;
/* 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 */
@ -187,14 +252,93 @@ typedef struct _AF_SEARCH {
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 {
@ -203,6 +347,19 @@ 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;

View file

@ -10,58 +10,58 @@
/* 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 */

View file

@ -39,7 +39,7 @@ VOID SendICMPComplete(
TI_DbgPrint(DEBUG_ICMP, ("Freeing IP packet at %X.\n", IPPacket));
PoolFreeBuffer(IPPacket);
(*IPPacket->Free)(IPPacket);
}
@ -68,12 +68,12 @@ PIP_PACKET PrepareICMPPacket(
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;
@ -81,7 +81,7 @@ PIP_PACKET PrepareICMPPacket(
sizeof(ICMP_HEADER) + DataSize;
DataBuffer = ExAllocatePool(NonPagedPool, Size);
if (!DataBuffer) {
PoolFreeBuffer(IPPacket);
(*IPPacket->Free)(IPPacket);
return NULL;
}
@ -90,7 +90,7 @@ PIP_PACKET PrepareICMPPacket(
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(IPPacket);
(*IPPacket->Free)(IPPacket);
ExFreePool(DataBuffer);
return NULL;
}
@ -101,7 +101,7 @@ PIP_PACKET PrepareICMPPacket(
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
DataBuffer, Size);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(IPPacket);
(*IPPacket->Free)(IPPacket);
NdisFreePacket(NdisPacket);
ExFreePool(DataBuffer);
return NULL;
@ -249,7 +249,7 @@ VOID ICMPTransmit(
/* 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);
@ -261,7 +261,7 @@ VOID ICMPTransmit(
IPPacket->DstAddr.Address.IPv4Address));
/* Discard packet */
FreeNdisPacket(IPPacket->NdisPacket);
PoolFreeBuffer(IPPacket);
(*IPPacket->Free)(IPPacket);
}
}
@ -295,10 +295,8 @@ VOID ICMPReply(
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);

View file

@ -9,6 +9,7 @@
*/
#include <tcpip.h>
#include <ip.h>
#include <tcp.h>
#include <loopback.h>
#include <neighbor.h>
#include <receive.h>
@ -29,13 +30,61 @@ KSPIN_LOCK PrefixListLock;
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)
/*
@ -64,12 +113,14 @@ PADDRESS_ENTRY CreateADE(
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;
@ -116,8 +167,7 @@ VOID DestroyADE(
#endif
/* And free the ADE */
PoolFreeBuffer(ADE);
TI_DbgPrint(MIN_TRACE, ("Check.\n"));
FreeADE(ADE);
}
@ -141,7 +191,7 @@ VOID DestroyADEs(
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;
@ -149,6 +199,35 @@ VOID DestroyADEs(
}
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,
@ -174,12 +253,13 @@ PPREFIX_LIST_ENTRY CreatePLE(
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;
@ -224,7 +304,7 @@ VOID DestroyPLE(
#endif
/* And free the PLE */
PoolFreeBuffer(PLE);
ExFreePool(PLE);
}
@ -247,7 +327,7 @@ VOID DestroyPLEs(
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;
@ -283,12 +363,16 @@ PNET_TABLE_ENTRY IPCreateNTE(
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 */
@ -306,7 +390,7 @@ PNET_TABLE_ENTRY IPCreateNTE(
ADE = CreateADE(IF, NTE->Address, ADE_UNICAST, NTE);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
PoolFreeBuffer(NTE);
ExFreePool(NTE);
return NULL;
}
@ -314,7 +398,7 @@ PNET_TABLE_ENTRY IPCreateNTE(
NTE->PLE = CreatePLE(IF, NTE->Address, PrefixLength);
if (!NTE->PLE) {
DestroyADE(IF, ADE);
PoolFreeBuffer(NTE);
ExFreePool(NTE);
return NULL;
}
@ -370,7 +454,7 @@ VOID DestroyNTE(
}
#endif
/* And free the NTE */
PoolFreeBuffer(NTE);
ExFreePool(NTE);
}
@ -395,7 +479,7 @@ VOID DestroyNTEs(
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;
@ -434,7 +518,7 @@ PNET_TABLE_ENTRY IPLocateNTEOnInterface(
/* 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;
@ -480,7 +564,7 @@ PNET_TABLE_ENTRY IPLocateNTE(
/* 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);
@ -527,7 +611,7 @@ PADDRESS_ENTRY IPLocateADE(
/* 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;
@ -577,7 +661,7 @@ PADDRESS_ENTRY IPGetDefaultADE(
/* 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 */
@ -636,6 +720,9 @@ VOID IPTimeout(
/* Clean possible outdated cached neighbor addresses */
NBTimeout();
/* Call upper layer timeout routines */
TCPTimeout();
}
@ -694,21 +781,24 @@ PIP_INTERFACE IPCreateInterface(
}
#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;
@ -751,7 +841,7 @@ VOID IPDestroyInterface(
TI_DbgPrint(MIN_TRACE, ("Interface at (0x%X) has (%d) references (should be 0).\n", IF, IF->RefCount));
}
#endif
PoolFreeBuffer(IF);
ExFreePool(IF);
}
@ -930,9 +1020,46 @@ NTSTATUS IPStartup(
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();
@ -1008,6 +1135,12 @@ NTSTATUS IPShutdown(
/* Clear prefix list */
DestroyPLEs();
/* Destroy lookaside lists */
ExDeleteNPagedLookasideList(&IPHoleList);
ExDeleteNPagedLookasideList(&IPDRList);
ExDeleteNPagedLookasideList(&IPPacketList);
ExDeleteNPagedLookasideList(&IPFragmentList);
IPInitialized = FALSE;
return STATUS_SUCCESS;

View file

@ -22,6 +22,13 @@
NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
VOID FreeNCE(
PVOID Object)
{
ExFreePool(Object);
}
VOID NCETimeout(
PNEIGHBOR_CACHE_ENTRY NCE)
/*
@ -250,12 +257,17 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
"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;
@ -455,11 +467,11 @@ VOID NBRemoveNeighbor(
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);
@ -492,8 +504,8 @@ VOID NBRemoveNeighbor(
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;

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@
PROUTE_CACHE_NODE ExternalRCN;
PROUTE_CACHE_NODE RouteCache;
KSPIN_LOCK RouteCacheLock;
NPAGED_LOOKASIDE_LIST IPRCNList;
#if DBG
@ -50,6 +51,18 @@ VOID PrintTree(
#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
@ -157,12 +170,14 @@ PROUTE_CACHE_NODE ExpandExternalRCN(VOID)
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;
@ -370,12 +385,24 @@ NTSTATUS RouteStartup(
{
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;
@ -413,10 +440,12 @@ NTSTATUS RouteShutdown(
/* Clear route cache */
RemoveSubtree(RouteCache);
PoolFreeBuffer(ExternalRCN);
FreeRCN(ExternalRCN);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
ExDeleteNPagedLookasideList(&IPRCNList);
return STATUS_SUCCESS;
}
@ -589,6 +618,8 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination(
/* 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;

View file

@ -17,6 +17,18 @@ LIST_ENTRY FIBListHead;
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)
/*
@ -47,7 +59,7 @@ VOID DestroyFIBE(
#endif
/* And free the FIB entry */
PoolFreeBuffer(FIBE);
FreeFIB(FIBE);
}
@ -286,12 +298,13 @@ PFIB_ENTRY RouterAddRoute(
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;
@ -424,20 +437,20 @@ PFIB_ENTRY RouterCreateRouteIPv4(
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);
@ -464,9 +477,13 @@ PFIB_ENTRY RouterCreateRouteIPv4(
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;

View file

@ -103,7 +103,7 @@ NTSTATUS SendFragments(
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;
@ -111,7 +111,7 @@ NTSTATUS SendFragments(
it for all fragments */
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
if (!IFC->Header) {
PoolFreeBuffer(IFC);
ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -119,7 +119,7 @@ NTSTATUS SendFragments(
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(Data);
PoolFreeBuffer(IFC);
ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -129,7 +129,7 @@ NTSTATUS SendFragments(
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(IFC->NdisPacket);
ExFreePool(Data);
PoolFreeBuffer(IFC);
ExFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -206,7 +206,7 @@ VOID IPSendComplete(
/* 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);
}
}

View file

@ -54,6 +54,21 @@ PCHAR A2S(
#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)
/*
@ -108,7 +123,7 @@ NTSTATUS AddrGetAddress(
*Port = ValidAddr->sin_port;
if (*Cache) {
if ((Cache) && (*Cache)) {
if (((*Cache)->Type == IP_ADDRESS_V4) &&
((*Cache)->Address.IPv4Address == ValidAddr->in_addr)) {
*Address = *Cache;
@ -120,14 +135,16 @@ NTSTATUS AddrGetAddress(
}
}
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;
@ -144,6 +161,43 @@ NTSTATUS AddrGetAddress(
}
/*
* 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:
@ -245,11 +299,12 @@ PIP_ADDRESS AddrBuildIPv4(
{
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;

View file

@ -6,6 +6,7 @@
* 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>
@ -227,7 +228,7 @@ VOID DispDataRequestComplete(
NTSTATUS DispTdiAccept(
PIRP Irp)
PIRP Irp)
/*
* FUNCTION: TDI_ACCEPT handler
* ARGUMENTS:
@ -236,7 +237,7 @@ NTSTATUS DispTdiAccept(
* Status of operation
*/
{
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
@ -252,14 +253,94 @@ NTSTATUS DispTdiAssociateAddress(
* Status of operation
*/
{
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
PCONNECTION_ENDPOINT Connection;
PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile;
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_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:
@ -268,14 +349,49 @@ NTSTATUS DispTdiConnect(
* 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:
@ -284,14 +400,47 @@ NTSTATUS DispTdiDisassociateAddress(
* 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:
@ -300,14 +449,14 @@ NTSTATUS DispTdiDisconnect(
* 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:
@ -316,15 +465,15 @@ NTSTATUS DispTdiListen(
* 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:
@ -334,14 +483,14 @@ NTSTATUS DispTdiQueryInformation(
* 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:
@ -350,7 +499,7 @@ NTSTATUS DispTdiReceive(
* Status of operation
*/
{
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
}
@ -366,42 +515,47 @@ NTSTATUS DispTdiReceiveDatagram(
* Status of operation
*/
{
PIO_STACK_LOCATION IrpSp;
PTDI_REQUEST_KERNEL_RECEIVEDG DgramInfo;
PTRANSPORT_CONTEXT TranContext;
TDI_REQUEST Request;
NTSTATUS Status;
ULONG BytesReceived;
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"));
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
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;
}
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;
}
@ -475,7 +629,7 @@ NTSTATUS DispTdiSendDatagram(
NTSTATUS DispTdiSetEventHandler(
PIRP Irp)
PIRP Irp)
/*
* FUNCTION: TDI_SET_EVENT_HANDER handler
* ARGUMENTS:
@ -484,130 +638,158 @@ NTSTATUS DispTdiSetEventHandler(
* Status of operation
*/
{
PTDI_REQUEST_KERNEL_SET_EVENT Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
PADDRESS_FILE AddrFile;
NTSTATUS Status;
KIRQL OldIrql;
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"));
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
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;
/* 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;
}
break;
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
if (!AddrFile) {
TI_DbgPrint(MIN_TRACE, ("No address file object.\n"));
return STATUS_INVALID_PARAMETER;
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;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
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;
return Status;
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;
default:
TI_DbgPrint(MIN_TRACE, ("Unknown event type (0x%X).\n",
Parameters->EventType));
Status = STATUS_INVALID_PARAMETER;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return Status;
}

View file

@ -12,169 +12,231 @@
#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));
/* 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;
}
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);
ExFreePool(ReceiveRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
/* Dereference address entry */
DereferenceObject(AddrFile->ADE);
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
/* Dereference address cache */
if (AddrFile->AddrCache)
DereferenceObject(AddrFile->AddrCache);
/* 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--;
/* 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));
if (AddrFile->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("AddrFile->RefCount is (%d) (should be 0).\n", AddrFile->RefCount));
#endif
PoolFreeBuffer(AddrFile);
(*AddrFile->Free)(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
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;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* 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 */
Connection->RefCount--;
if (Connection->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("Connection->RefCount is (%d) (should be 0).\n",
Connection->RefCount));
#endif
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;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
(*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
return;
}
/* 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);
AF_CLR_BUSY(AddrFile);
ReferenceObject(AddrFile);
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);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
DereferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
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"));
}
AF_CLR_BUSY(AddrFile);
RtnComplete = AddrFile->Complete;
RtnContext = AddrFile->Context;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
DeleteAddress(AddrFile);
(*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
return;
}
/* 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);
AF_CLR_BUSY(AddrFile);
ReferenceObject(AddrFile);
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);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
DereferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
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"));
}
AF_CLR_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
@ -189,97 +251,106 @@ VOID RequestWorker(
* 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;
PADDRESS_FILE AddrFile;
IPv4_RAW_ADDRESS IPv4Address;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
TI_DbgPrint(MID_TRACE, ("Called.\n"));
AddrFile = PoolAllocateBuffer(sizeof(ADDRESS_FILE));
if (!AddrFile) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
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));
TI_DbgPrint(DEBUG_ADDRFILE, ("Address file object allocated at (0x%X).\n", AddrFile));
RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));
RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));
/* Make sure address is a local unicast address or 0 */
AddrFile->Free = AddrFileFree;
/* Locate address entry. If specified address is 0, a random address is chosen */
/* Make sure address is a local unicast address or 0 */
/* FIXME: IPv4 only */
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
else
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
/* Locate address entry. If specified address is 0, a random address is chosen */
if (!AddrFile->ADE) {
PoolFreeBuffer(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
/* FIXME: IPv4 only */
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
else
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
TI_DbgPrint(MID_TRACE, ("Opening address %s for communication.\n",
A2S(AddrFile->ADE->Address)));
if (!AddrFile->ADE) {
ExFreePool(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
/* 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, ("Opening address %s for communication.\n",
A2S(AddrFile->ADE->Address)));
TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
Protocol));
/* 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;
/* Set protocol */
AddrFile->Protocol = Protocol;
/* Initialize receive and transmit queues */
InitializeListHead(&AddrFile->ReceiveQueue);
InitializeListHead(&AddrFile->TransmitQueue);
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;
/* Initialize work queue item. We use this for pending requests */
ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
default:
/* Use raw IP for all other protocols */
AddrFile->Port = 0;
AddrFile->Send = RawIPSendDatagram;
break;
}
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&AddrFile->Lock);
TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
Protocol));
/* Reference the object */
AddrFile->RefCount = 1;
/* Set protocol */
AddrFile->Protocol = Protocol;
/* Initialize receive and transmit queues */
InitializeListHead(&AddrFile->ReceiveQueue);
InitializeListHead(&AddrFile->TransmitQueue);
/* Set valid flag so the address can be used */
AF_SET_VALID(AddrFile);
/* Initialize associated connection list */
InitializeListHead(&AddrFile->Connections);
/* Return address file object */
Request->Handle.AddressHandle = AddrFile;
/* Initialize work queue item. We use this for pending requests */
ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
/* Add address file to global list */
ExInterlockedInsertTailList(&AddressFileListHead, &AddrFile->ListEntry, &AddressFileListLock);
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&AddrFile->Lock);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
/* Reference the object */
AddrFile->RefCount = 1;
return STATUS_SUCCESS;
/* 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;
}
@ -291,111 +362,195 @@ NTSTATUS FileOpenAddress(
* 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 */
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);
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);
if (!AF_IS_BUSY(AddrFile)) {
/* Worker function is not running, so shedule it to run */
AF_SET_BUSY(AddrFile);
AF_CLR_VALID(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
} else
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
} else {
if (!AF_IS_PENDING(AddrFile, AFF_DELETE)) {
AddrFile->Complete = Request->RequestNotifyObject;
AddrFile->Context = Request->RequestContext;
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
/* Shedule address file for deletion */
AF_SET_PENDING(AddrFile, AFF_DELETE);
AF_CLR_VALID(AddrFile);
return STATUS_PENDING;
} else
Status = STATUS_ADDRESS_CLOSED;
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);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
}
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_PENDING;
} else
Status = STATUS_ADDRESS_CLOSED;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
}
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 */

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,89 @@
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)
/*
@ -414,6 +497,7 @@ VOID DisplayIPPacket(
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));

File diff suppressed because it is too large Load diff

View file

@ -49,31 +49,29 @@ NTSTATUS BuildRawIPPacket(
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"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Packet, sizeof(IP_PACKET));
/* FIXME: Assumes IPv4 */
Packet = IPCreatePacket(IP_ADDRESS_V4);
if (!Packet)
return STATUS_INSUFFICIENT_RESOURCES;
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;
}
@ -88,9 +86,9 @@ NTSTATUS BuildRawIPPacket(
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 */

View file

@ -8,37 +8,491 @@
* 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 */

View file

@ -21,10 +21,10 @@ BOOLEAN UDPInitialized = FALSE;
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:
@ -36,83 +36,82 @@ NTSTATUS AddUDPHeaderIPv4(
* 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);
Header = ExAllocatePool(NonPagedPool, BufferSize);
if (!Header) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
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));
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;
}
/* 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;
/* 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 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);
/* 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;
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:
@ -124,68 +123,66 @@ NTSTATUS BuildUDPPacket(
* Status of operation
*/
{
NTSTATUS Status;
PIP_PACKET Packet;
NDIS_STATUS NdisStatus;
PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
NTSTATUS Status;
PIP_PACKET Packet;
NDIS_STATUS NdisStatus;
PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
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;
}
/* Prepare packet */
RtlZeroMemory(Packet, sizeof(IP_PACKET));
Packet->RefCount = 1;
Packet->TotalSize = sizeof(IPv4_HEADER) +
sizeof(UDP_HEADER) +
SendRequest->BufferSize;
/* FIXME: Assumes IPv4 */
Packet = IPCreatePacket(IP_ADDRESS_V4);
if (!Packet)
return STATUS_INSUFFICIENT_RESOURCES;
/* 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;
}
Packet->TotalSize = sizeof(IPv4_HEADER) +
sizeof(UDP_HEADER) +
SendRequest->BufferSize;
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;
}
/* 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;
}
/* Chain data after header */
NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
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;
}
DISPLAY_IP_PACKET(Packet);
/* Chain data after header */
NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
*IPPacket = Packet;
DISPLAY_IP_PACKET(Packet);
return STATUS_SUCCESS;
*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:
@ -197,11 +194,11 @@ NTSTATUS UDPSendDatagram(
* Status of operation
*/
{
return DGSendDatagram(Request,
ConnInfo,
Buffer,
DataSize,
BuildUDPPacket);
return DGSendDatagram(Request,
ConnInfo,
Buffer,
DataSize,
BuildUDPPacket);
}
@ -229,135 +226,135 @@ NTSTATUS UDPReceiveDatagram(
* 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;
AF_SEARCH SearchContext;
PIPv4_HEADER IPv4Header;
PADDRESS_FILE AddrFile;
PUDP_HEADER UDPHeader;
PIP_ADDRESS DstAddress;
UINT DataSize, i;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
switch (IPPacket->Type) {
/* IPv4 packet */
case IP_ADDRESS_V4:
IPv4Header = IPPacket->Header;
DstAddress = &IPPacket->DstAddr;
break;
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));
/* 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;
/* FIXME: IPv6 is not supported */
return;
default:
return;
}
default:
return;
}
UDPHeader = (PUDP_HEADER)IPPacket->Data;
UDPHeader = (PUDP_HEADER)IPPacket->Data;
/* FIXME: Calculate and validate UDP checksum */
/* 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;
}
/* 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);
DataSize = i - sizeof(UDP_HEADER);
/* Go to UDP data area */
(ULONG_PTR)IPPacket->Data += 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 */
/* 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)));
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"));
/* 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 */

View file

@ -35,16 +35,13 @@ extern DWORD DebugTraceLevel;
#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 */

View file

@ -290,13 +290,25 @@ WSHOpenSocket2(
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)
case SOCK_DGRAM:
RtlInitUnicodeString(&String, DD_UDP_DEVICE_NAME);
break;
case SOCK_RAW:
if ((*Protocol < 0) || (*Protocol > 255))
return WSAEINVAL;
RtlInitUnicodeString(&String, DD_RAW_IP_DEVICE_NAME);
break;
default:
return WSAEINVAL;
RtlInitUnicodeString(&String, DD_RAW_IP_DEVICE_NAME);
}
RtlInitUnicodeString(TransportDeviceName, NULL);
@ -315,19 +327,21 @@ WSHOpenSocket2(
/* 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 */

View file

@ -11,15 +11,15 @@
#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 */
@ -27,81 +27,172 @@ typedef struct _AFD_SOCKET_INFORMATION {
#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 */

View file

@ -46,53 +46,6 @@ ExAcquireSharedWaitForExclusive (
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 (
@ -170,16 +123,6 @@ ExCreateCallback (
IN BOOLEAN AllowMultipleCallbacks
);
VOID
STDCALL
ExDeleteNPagedLookasideList (
PNPAGED_LOOKASIDE_LIST Lookaside
);
VOID
STDCALL
ExDeletePagedLookasideList (
PPAGED_LOOKASIDE_LIST Lookaside
);
NTSTATUS
STDCALL
ExDeleteResource (
@ -216,52 +159,6 @@ ExFreePool (
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 (
@ -315,35 +212,13 @@ ExGetSharedWaiterCount (
* );
*/
#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 (
@ -597,12 +472,12 @@ ExPostSystemEvent (
/*
* USHORT
* ExQueryDepthSListHead (
* ExQueryDepthSList (
* PSLIST_HEADER SListHead
* );
*/
#define ExQueryDepthSListHead(ListHead) \
(USHORT)(ListHead)->Depth
*/
#define ExQueryDepthSList(ListHead) \
(USHORT)(ListHead)->s.Depth
VOID
STDCALL
@ -711,6 +586,133 @@ ExUnregisterCallback (
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

View file

@ -1,4 +1,4 @@
/* $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
@ -103,39 +103,44 @@ typedef union _SLIST_HEADER
} 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;

View file

@ -1,4 +1,4 @@
/* $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 $
*
*/
@ -380,7 +380,7 @@ extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG;
static
inline
PSINGLE_LIST_ENTRY
PopEntryList (
PopEntryList(
PSINGLE_LIST_ENTRY ListHead
)
{
@ -394,7 +394,6 @@ PopEntryList (
return ListEntry;
}
/*
VOID
PushEntryList (
@ -420,6 +419,47 @@ 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 (

View file

@ -131,8 +131,6 @@ typedef struct _PEB
ULONG ImageSubSystemMajorVersion; // B8h
ULONG ImageSubSystemMinorVersion; // C0h
ULONG GdiHandleBuffer[0x22]; // C4h
PVOID ProcessWindowStation; // ???
} PEB, *PPEB;
@ -217,8 +215,6 @@ typedef struct _NT_TEB
PVOID StackCommit; // F88h
PVOID StackCommitMax; // F8Ch
PVOID StackReserve; // F90h
PVOID MessageQueue; // ???
} NT_TEB, *PNT_TEB;
#define PEB_STARTUPINFO (0xb0003000)

View file

@ -22,8 +22,8 @@ copy ntoskrnl\ntoskrnl.exe %ROS_INSTALL%
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
@ -33,17 +33,25 @@ copy services\dd\blue\blue.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
@ -67,5 +75,8 @@ copy apps\mstest\msclient.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

View file

@ -6,7 +6,8 @@ CFLAGS = -I./include -DUNICODE -DDBG
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

View file

@ -86,7 +86,7 @@ NTSTATUS OpenSocket(
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;
@ -207,6 +207,7 @@ WSPSocket(
&HelperContext,
&NotificationEvents);
if (Status != NO_ERROR) {
AFD_DbgPrint(MAX_TRACE, ("WinSock Helper DLL failed (0x%X).\n", Status));
*lpErrno = Status;
return INVALID_SOCKET;
}
@ -290,14 +291,13 @@ WSPBind(
* 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(
@ -311,21 +311,68 @@ WSPBind(
sizeof(FILE_REQUEST_BIND),
&Reply,
sizeof(FILE_REPLY_BIND));
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 (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;
}
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 = Reply.Status;
return SOCKET_ERROR;
}
return 0;
}
@ -466,6 +513,107 @@ WSPSelect(
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)
@ -489,7 +637,7 @@ NTSTATUS OpenCommandChannel(
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);
@ -507,7 +655,7 @@ NTSTATUS OpenCommandChannel(
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");
@ -591,8 +739,6 @@ WSPStartup(
if (StartupCount == 0) {
/* First time called */
Status = WSAVERNOTSUPPORTED;
Status = OpenCommandChannel();
if (NT_SUCCESS(Status)) {
hWS2_32 = GetModuleHandle(L"ws2_32.dll");
@ -686,6 +832,8 @@ WSPCleanup(
LeaveCriticalSection(&InitCriticalSection);
AFD_DbgPrint(MAX_TRACE, ("Leaving.\n"));
*lpErrno = NO_ERROR;
return 0;
@ -720,9 +868,11 @@ DllMain(HANDLE hInstDll,
break;
case DLL_PROCESS_DETACH:
DestroyHelperDLLDatabase();
DeleteCriticalSection(&InitCriticalSection);
break;
}

View file

@ -0,0 +1,105 @@
/*
* 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 */

View file

@ -169,10 +169,8 @@ INT UnloadHelperDLL(
if (HelperDLL->hModule) {
if (!FreeLibrary(HelperDLL->hModule)) {
CP
Status = GetLastError();
}
HelperDLL->hModule = NULL;
}
@ -193,15 +191,27 @@ VOID CreateHelperDLLDatabase(VOID)
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);
}
@ -216,7 +226,8 @@ VOID DestroyHelperDLLDatabase(VOID)
CurrentEntry = HelperDLLDatabaseListHead.Flink;
while (CurrentEntry != &HelperDLLDatabaseListHead) {
NextEntry = CurrentEntry->Flink;
HelperDLL = CONTAINING_RECORD(CurrentEntry,
HelperDLL = CONTAINING_RECORD(CurrentEntry,
WSHELPER_DLL,
ListEntry);

View file

@ -37,7 +37,62 @@ WSPRecv(
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;
}
@ -89,7 +144,7 @@ WSPRecvFrom(
}
/* 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;
@ -97,7 +152,8 @@ WSPRecvFrom(
RtlCopyMemory(Request->Buffers, lpBuffers, Size);
Status = NtDeviceIoControlFile((HANDLE)s,
Status = NtDeviceIoControlFile(
(HANDLE)s,
NULL,
NULL,
NULL,
@ -125,9 +181,6 @@ WSPRecvFrom(
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;
@ -152,7 +205,57 @@ WSPSend(
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;
}
@ -204,7 +307,7 @@ WSPSendTo(
}
/* 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;
@ -213,7 +316,8 @@ WSPSendTo(
RtlCopyMemory(Request->Buffers, lpBuffers, Size);
Status = NtDeviceIoControlFile((HANDLE)s,
Status = NtDeviceIoControlFile(
(HANDLE)s,
NULL,
NULL,
NULL,

View file

@ -10,22 +10,6 @@
#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(
@ -53,24 +37,6 @@ WSPCancelBlockingCall(
}
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(
@ -85,34 +51,6 @@ 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(
@ -227,19 +165,6 @@ WSPJoinLeaf(
}
INT
WSPAPI
WSPListen(
IN SOCKET s,
IN INT backlog,
OUT LPINT lpErrno)
{
UNIMPLEMENTED
return 0;
}
INT
WSPAPI
WSPSetSockOpt(

View file

@ -1,4 +1,4 @@
# $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
#
@ -295,6 +295,7 @@ CLEAN_FILES = \
conio\*.o \
ctype\*.o \
direct\*.o \
except\*.o \
float\*.o \
io\*.o \
math\*.o \
@ -318,6 +319,7 @@ CLEAN_FILES = \
conio/*.o \
ctype/*.o \
direct/*.o \
except/*.o \
float/*.o \
io/*.o \
math/*.o \

View file

@ -1,4 +1,4 @@
/* $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
@ -1096,7 +1096,7 @@ LdrUnloadDll (IN PVOID BaseAddress)
ModuleListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead);
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_MODULE, InLoadOrderModuleList);
if (Module->BaseAddress == BaseAddress)

View file

@ -15,7 +15,7 @@ typedef struct _PROVIDER_HANDLE {
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;

View file

@ -36,6 +36,53 @@ typedef struct _WINSOCK_THREAD_BLOCK {
#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 */

View file

@ -2,12 +2,13 @@
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

View file

@ -0,0 +1,44 @@
/*
* 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 */

View file

@ -144,7 +144,7 @@ PCATALOG_ENTRY LocateProvider(
CurrentEntry = CurrentEntry->Flink;
}
LeaveCriticalSection(&CatalogLock);
//LeaveCriticalSection(&CatalogLock);
return NULL;
}
@ -210,12 +210,6 @@ INT LoadProvider(
&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
@ -241,8 +235,9 @@ INT UnloadProvider(
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();
}
@ -274,17 +269,26 @@ VOID CreateCatalog(VOID)
/* 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
}

View file

@ -16,7 +16,7 @@
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
//DWORD DebugTraceLevel = MAX_TRACE;
//DWORD DebugTraceLevel = DEBUG_ULTRA;
#endif /* DBG */
@ -92,6 +92,17 @@ WSACleanup(VOID)
}
SOCKET
EXPORT
socket(
IN INT af,
IN INT type,
IN INT protocol)
{
return WSASocketA(af, type, protocol, NULL, 0, 0);
}
SOCKET
EXPORT
WSASocketA(
@ -226,8 +237,8 @@ closesocket(
*/
{
PCATALOG_ENTRY Provider;
INT Status;
INT Errno;
INT Code;
WS_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
@ -245,8 +256,8 @@ closesocket(
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;
@ -317,15 +328,178 @@ select(
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,

View file

@ -8,25 +8,27 @@
* 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;
}
@ -34,95 +36,167 @@ WSAEVENT
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;
DWORD Status;
if (!WSAINITIALIZED) {
WSASetLastError(WSANOTINITIALISED);
return FALSE;
}
if (!WSAINITIALIZED) {
WSASetLastError(WSANOTINITIALISED);
return FALSE;
}
Status = WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
if (Status == WAIT_FAILED) {
Status = GetLastError();
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);
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 WSA_WAIT_FAILED;
}
return Status;
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)
{
PCATALOG_ENTRY Provider;
INT Status;
INT Errno;
LONG i;
if (!WSAINITIALIZED) {
WSASetLastError(WSANOTINITIALISED);
return SOCKET_ERROR;
}
if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
WSASetLastError(WSAENOTSOCK);
return SOCKET_ERROR;
}
Status = Provider->ProcTable.lpWSPEventSelect(
s, hEventObject, lNetworkEvents, &Errno);
DereferenceProviderByPointer(Provider);
if (Status == SOCKET_ERROR)
WSASetLastError(Errno);
return Status;
}
/* EOF */

View file

@ -28,80 +28,80 @@ GetProviderByHandle(
* 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));
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);
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;
}
VOID
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;
}
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;
}
CurrentEntry = CurrentEntry->Flink;
}
return NULL;
}
VOID
DeleteHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable)
CloseAllHandles(
PPROVIDER_HANDLE_BLOCK HandleTable)
{
PPROVIDER_HANDLE_BLOCK Current;
PLIST_ENTRY CurrentEntry;
PPROVIDER_HANDLE_BLOCK Current;
PLIST_ENTRY CurrentEntry;
PCATALOG_ENTRY Provider;
ULONG i;
WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable));
CloseAllHandles(HandleTable);
CurrentEntry = RemoveHeadList(&HandleTable->Entry);
while (CurrentEntry != &HandleTable->Entry) {
Current = CONTAINING_RECORD(CurrentEntry,
PROVIDER_HANDLE_BLOCK,
Entry);
CurrentEntry = HandleTable->Entry.Flink;
HeapFree(GlobalHeap, 0, Current);
while (CurrentEntry != &HandleTable->Entry) {
Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
CurrentEntry = RemoveHeadList(&HandleTable->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;
}
}
VOID
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);
}
}
@ -109,96 +109,95 @@ PCATALOG_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));
WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
Entry = GetProviderByHandle(HandleTable, Handle);
if (!Entry) {
return NULL;
}
Entry = GetProviderByHandle(HandleTable, Handle);
if (!Entry)
return NULL;
Provider = Entry->Provider;
Provider = Entry->Provider;
Entry->Handle = (HANDLE)0;
Entry->Provider = NULL;
if (Provider != NULL) {
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;
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));
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);
/* 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;
}
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;
}
ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK));
InsertTailList(&HandleTable->Entry, &NewBlock->Entry);
/* Add a new handle block to the end of the list */
NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(
GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
NewBlock->Handles[0].Handle = Handle;
NewBlock->Handles[0].Provider = Provider;
if (!NewBlock)
return (HANDLE)0;
return Handle;
ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK));
InsertTailList(&HandleTable->Entry, &NewBlock->Entry);
NewBlock->Handles[0].Handle = Handle;
NewBlock->Handles[0].Provider = Provider;
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:
@ -208,72 +207,71 @@ ReferenceProviderByHandle(HANDLE Handle,
* 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 */

View file

@ -13,212 +13,268 @@
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;
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;
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;
return 0;
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);
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;
return 0;
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 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 */

View file

@ -9,42 +9,6 @@
*/
#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(
@ -83,26 +47,6 @@ getsockopt(
return 0;
}
ULONG
EXPORT
htonl(
IN ULONG hostlong)
{
UNIMPLEMENTED
return 0;
}
USHORT
EXPORT
htons(
IN USHORT hostshort)
{
UNIMPLEMENTED
return 0;
}
INT
EXPORT
ioctlsocket(
@ -115,37 +59,6 @@ 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(
@ -171,32 +84,6 @@ shutdown(
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(
@ -219,22 +106,6 @@ WSACancelBlockingCall(VOID)
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(
@ -259,18 +130,6 @@ WSADuplicateSocketW(
return 0;
}
INT
EXPORT
WSAEnumNetworkEvents(
IN SOCKET s,
IN WSAEVENT hEventObject,
OUT LPWSANETWORKEVENTS lpNetworkEvents)
{
UNIMPLEMENTED
return 0;
}
INT
EXPORT
WSAEnumProtocolsA(
@ -295,18 +154,6 @@ WSAEnumProtocolsW(
return 0;
}
INT
EXPORT
WSAEventSelect(
IN SOCKET s,
IN WSAEVENT hEventObject,
IN LONG lNetworkEvents)
{
UNIMPLEMENTED
return 0;
}
BOOL
EXPORT
WSAGetOverlappedResult(

View file

@ -103,25 +103,27 @@ WPUModifyIFSHandle(
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;
}

View file

@ -1,4 +1,4 @@
# $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
#
@ -492,13 +492,13 @@ OBJECTS := \
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 \

View file

@ -41,6 +41,7 @@ ExInit (VOID)
{
ExInitTimeZoneInfo();
ExInitializeWorkerThreads();
ExpInitLookasideLists();
ExpWin32kInit();
}

View file

@ -1,11 +1,14 @@
/* $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 *****************************************************************/
@ -27,9 +30,9 @@ ExInterlockedInsertHeadList (
/*
* 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
*/
{
@ -86,7 +89,7 @@ ExInterlockedRemoveHeadList (
/*
* 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
*/
@ -115,7 +118,7 @@ ExInterlockedRemoveTailList (
/*
* 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
*/
@ -138,19 +141,56 @@ ExInterlockedRemoveTailList (
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);
}
@ -160,6 +200,13 @@ ExInterlockedPopEntryList (
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;
@ -178,6 +225,14 @@ ExInterlockedPushEntryList (
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;

View file

@ -1,29 +1,136 @@
/* $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
@ -32,7 +139,21 @@ ExDeleteNPagedLookasideList (
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
@ -41,7 +162,28 @@ ExDeletePagedLookasideList (
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
@ -51,7 +193,19 @@ ExFreeToPagedLookasideList (
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
@ -65,7 +219,47 @@ ExInitializeNPagedLookasideList (
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
@ -80,7 +274,47 @@ ExInitializePagedLookasideList (
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 */

View file

@ -10,28 +10,35 @@
typedef struct _WINSTATION_OBJECT
{
CSHORT Type;
CSHORT Size;
CSHORT Type;
CSHORT Size;
KSPIN_LOCK Lock;
UNICODE_STRING Name;
LIST_ENTRY DesktopListHead;
PRTL_ATOM_TABLE AtomTable;
PVOID HandleTable;
/* FIXME: Clipboard */
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;
@ -47,7 +54,7 @@ VOID
ExInitTimeZoneInfo (VOID);
VOID
ExInitializeWorkerThreads(VOID);
VOID
ExpInitLookasideLists(VOID);
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_EXECUTIVE_H */

View file

@ -229,7 +229,12 @@ typedef struct
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
{
@ -279,8 +284,7 @@ typedef struct _ETHREAD
*/
struct _EPROCESS* OldProcess; /* 240/26C */
/* Pointer to win32 private thread data */
struct _WIN32THREADDATA *Win32ThreadData;
PW32THREAD Win32Thread;
} __attribute__((packed)) ETHREAD, *PETHREAD;
@ -349,7 +353,11 @@ typedef struct _KPROCESS
UCHAR DisableBoost; /* 067 */
} KPROCESS, *PKPROCESS;
struct _WIN32PROCESSDATA;
typedef struct _W32PROCESS
{
} __attribute__((packed)) W32PROCESS, *PW32PROCESS;
struct _EPROCESS
{
@ -450,7 +458,8 @@ struct _EPROCESS
UCHAR SubSystemMinorVersion;
UCHAR SubSystemMajorVersion;
USHORT SubSystemVersion;
struct _WIN32PROCESSDATA *Win32Process;
PW32PROCESS Win32Process;
HANDLE Win32WindowStation;
/*
* Added by David Welch (welch@mcmail.com)

View file

@ -1,4 +1,4 @@
/* $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
@ -108,7 +108,7 @@ IopCreateFile (PVOID ObjectBody,
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 =
@ -333,7 +333,7 @@ IoCreateFile(
(PVOID*)&FileObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("ObCreateObject() failed!\n");
DPRINT("ObCreateObject() failed!\n");
return (Status);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
@ -357,6 +357,7 @@ IoCreateFile(
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
if (Irp == NULL)
{
ZwClose(*FileHandle);
return (STATUS_UNSUCCESSFUL);
}
@ -413,7 +414,6 @@ IoCreateFile(
{
DPRINT("Failing create request with status %x\n", Status);
ZwClose(*FileHandle);
(*FileHandle) = 0;
}
assert_irql(PASSIVE_LEVEL);

View file

@ -16,7 +16,7 @@
* 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
@ -130,7 +130,7 @@ VOID STDCALL
ExRaiseStatus (IN NTSTATUS Status)
{
DbgPrint("ExRaiseStatus(%x)\n",Status);
for(;;);
KeBugCheck(0);
}

View file

@ -1,4 +1,4 @@
; $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
;
@ -41,8 +41,8 @@ ExFreeToPagedLookasideList@8
ExGetExclusiveWaiterCount@4
ExGetPreviousMode@0
ExGetSharedWaiterCount@4
ExInitializeNPagedLookasideList
ExInitializePagedLookasideList
ExInitializeNPagedLookasideList@28
ExInitializePagedLookasideList@28
ExInitializeResource@4
ExInitializeResourceLite@4
ExInitializeZone@16

View file

@ -1,4 +1,4 @@
/* $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
@ -390,7 +390,7 @@ PsInitializeThread(HANDLE ProcessHandle,
&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;

View file

@ -3,22 +3,14 @@
#include <windows.h>
#include <ddk/ntddk.h>
#include <../ntoskrnl/include/internal/ex.h>
/*
* FIXME: NtCurrentPeb() does not work (returns 0)
#define PROCESS_WINDOW_STATION() \
(HWINSTA)(NtCurrentPeb()->ProcessWindowStation);
#define SET_PROCESS_WINDOW_STATION(WinSta) \
(NtCurrentPeb()->ProcessWindowStation = (PVOID)(WinSta));
*/
#include <internal/ex.h>
#include <internal/ps.h>
#define PROCESS_WINDOW_STATION() \
((HWINSTA)(((PPEB)PEB_BASE)->ProcessWindowStation))
((HWINSTA)(IoGetCurrentProcess()->Win32WindowStation))
#define SET_PROCESS_WINDOW_STATION(WinSta) \
(((PPEB)PEB_BASE)->ProcessWindowStation = (PVOID)(WinSta))
((IoGetCurrentProcess()->Win32WindowStation) = (PVOID)(WinSta))
NTSTATUS

View file

@ -1,4 +1,4 @@
# $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
#
@ -9,7 +9,7 @@ TARGET=win32k
# 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

View file

@ -1,4 +1,4 @@
/* $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
@ -24,10 +24,10 @@
VOID
GuiCheck(VOID)
{
if (NtCurrentTeb()->MessageQueue)
/* if (NtCurrentTeb()->MessageQueue)
return;
NtCurrentTeb()->MessageQueue = MsqCreateMessageQueue();
NtCurrentTeb()->MessageQueue = MsqCreateMessageQueue();*/
}
/* EOF */