mirror of
https://github.com/reactos/reactos.git
synced 2024-06-01 18:21:50 +00:00
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:
parent
df84ec15d8
commit
3a9de284ad
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
105
reactos/lib/msafd/misc/event.c
Normal file
105
reactos/lib/msafd/misc/event.c
Normal 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 */
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
44
reactos/lib/ws2_32/misc/bsd.c
Normal file
44
reactos/lib/ws2_32/misc/bsd.c
Normal 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 */
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -41,6 +41,7 @@ ExInit (VOID)
|
|||
{
|
||||
ExInitTimeZoneInfo();
|
||||
ExInitializeWorkerThreads();
|
||||
ExpInitLookasideLists();
|
||||
ExpWin32kInit();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue