2003-12-25 Casper S. Hornstrup <chorns@users.sourceforge.net>

* apps/utils/net/roshttpd/error.cpp (ReportErrorStr): Cast to wchar_t*,
	not __wchar_t*.
	* apps/utils/net/roshttpd/makefile (TARGET_CPPFLAGS): Add -Wno-deprecated.
	(TARGET_GCCLIBS): Add stdc++.
	* apps/utils/net/roshttpd/common/socket.cpp: Include <string.h>.
	* apps/utils/net/roshttpd/common/thread.cpp (CThread::CThread): Fix
	warning.
	* drivers/net/afd/afd/afd.c (ListenRequestLookasideList): New variable.
	(DriverEntry): Initialize ListenRequestLookasideList.
	* drivers/net/afd/afd/dispatch.c (AfdDispCompleteListen): New function.
	(AfdDispListen): Partial implement.
	* drivers/net/afd/afd/opnclose.c (AfdInitializeFCB): Initialize
	NewFCB->ListenRequestQueue.
	(AfdKillListenRequests): New function.
	(AfdClose): Call AfdKillListenRequests.
	* drivers/net/afd/afd/routines.c (DumpName): New function.
	* drivers/net/afd/afd/tdi.c (TdiAddressSizeFromType): New function.
	(TdiBuildConnectionInfo): Initialize ConnInfo->OptionsLength.
	(TdiBuildNullConnectionInfo): New function.
	(TdiOpenAddressFileIPv4, TdiOpenConnectionEndpointFile): EaName is
	0-terminated.
	(TdiListen): New function.
	* drivers/net/afd/include/afd.h (AFDFCB): Add ListenRequestQueue.
	(AFD_LISTEN_REQUEST): New structure.
	(ListenRequestLookasideList): Declare.
	(DumpName, TdiListen): Add prototypes.
	* drivers/net/tcpip/datalink/lan.c (BindAdapter): Initialize
	AnsiAddress.Length and AnsiAddress.MaximumLength.
	* drivers/net/tcpip/include/debug.h: Define DEBUG_TCP.
	* drivers/net/tcpip/include/routines.h (DisplayTCPPacket): Add
	prototype.
	(DISPLAY_TCP_PACKET): Define.
	* drivers/net/tcpip/include/tcp.h (TCPListen): Add prototype.
	* drivers/net/tcpip/include/titypes.h (ADDRESS_FILE): Add Connection.
	* drivers/net/tcpip/network/ip.c (IPLocateNTEOnInterface): Cleanup.
	* drivers/net/tcpip/tcpip/address.c (AddrSearchNext): Port is in
	network byte order.
	* drivers/net/tcpip/tcpip/dispatch.c (DispTdiAssociateAddress):
	Initialize AddrFile->Connection.
	(DispTdiListen): Implement.
	* drivers/net/tcpip/tcpip/fileobjs.c (FileOpenAddress): Don't
	initialize AddrFile->Connections.
	* drivers/net/tcpip/tcpip/routines.c: Include <tcp.h>.
	(DisplayIPPacket): Enable.
	(DisplayTCPHeader, DisplayTCPPacket): New functions.
	* drivers/net/tcpip/transport/tcp/tcp.c: Include <routines.h>.
	(TCPListen, TCPiReceive): New functions.
	(TCPReceive): Partial implement.
	* lib/msafd/misc/helpers.c (CreateHelperDLLDatabase): Add
	{SOCK_STREAM,IPPROTO_TCP,0} and {SOCK_DGRAM,IPPROTO_UDP,0} mappings.
	* lib/ntdll/ldr/utils.c (LdrLoadDll): Print name of DLL if not found.
	* lib/ws2_32/include/ws2_32.h (Initialized): Declare.
	(WINSOCK_THREAD_BLOCK): Remove Initialized member.
	* (WSAINITIALIZED, WSASETINITIALIZED): Update.
	* lib/ws2_32/misc/catalog.c (CreateCatalog): Add
	{SOCK_STREAM,IPPROTO_TCP,0} and {SOCK_DGRAM,IPPROTO_UDP,0} mappings.
	(Initialized): New variable.
	(DllMain): Don't initialize p->Initialized.
	* ntoskrnl/dbg/kdb.c: Include <ctype.h>.
	* subsys/win32k/ntuser/message.c (NtUserDispatchMessage): Kill noisy
	message.

svn path=/trunk/; revision=7232
This commit is contained in:
Casper Hornstrup 2003-12-25 14:06:15 +00:00
parent 9aa489b9bf
commit 08ba5babf3
29 changed files with 1191 additions and 96 deletions

View file

@ -1,3 +1,67 @@
2003-12-25 Casper S. Hornstrup <chorns@users.sourceforge.net>
* apps/utils/net/roshttpd/error.cpp (ReportErrorStr): Cast to wchar_t*,
not __wchar_t*.
* apps/utils/net/roshttpd/makefile (TARGET_CPPFLAGS): Add -Wno-deprecated.
(TARGET_GCCLIBS): Add stdc++.
* apps/utils/net/roshttpd/common/socket.cpp: Include <string.h>.
* apps/utils/net/roshttpd/common/thread.cpp (CThread::CThread): Fix
warning.
* drivers/net/afd/afd/afd.c (ListenRequestLookasideList): New variable.
(DriverEntry): Initialize ListenRequestLookasideList.
* drivers/net/afd/afd/dispatch.c (AfdDispCompleteListen): New function.
(AfdDispListen): Partial implement.
* drivers/net/afd/afd/opnclose.c (AfdInitializeFCB): Initialize
NewFCB->ListenRequestQueue.
(AfdKillListenRequests): New function.
(AfdClose): Call AfdKillListenRequests.
* drivers/net/afd/afd/routines.c (DumpName): New function.
* drivers/net/afd/afd/tdi.c (TdiAddressSizeFromType): New function.
(TdiBuildConnectionInfo): Initialize ConnInfo->OptionsLength.
(TdiBuildNullConnectionInfo): New function.
(TdiOpenAddressFileIPv4, TdiOpenConnectionEndpointFile): EaName is
0-terminated.
(TdiListen): New function.
* drivers/net/afd/include/afd.h (AFDFCB): Add ListenRequestQueue.
(AFD_LISTEN_REQUEST): New structure.
(ListenRequestLookasideList): Declare.
(DumpName, TdiListen): Add prototypes.
* drivers/net/tcpip/datalink/lan.c (BindAdapter): Initialize
AnsiAddress.Length and AnsiAddress.MaximumLength.
* drivers/net/tcpip/include/debug.h: Define DEBUG_TCP.
* drivers/net/tcpip/include/routines.h (DisplayTCPPacket): Add
prototype.
(DISPLAY_TCP_PACKET): Define.
* drivers/net/tcpip/include/tcp.h (TCPListen): Add prototype.
* drivers/net/tcpip/include/titypes.h (ADDRESS_FILE): Add Connection.
* drivers/net/tcpip/network/ip.c (IPLocateNTEOnInterface): Cleanup.
* drivers/net/tcpip/tcpip/address.c (AddrSearchNext): Port is in
network byte order.
* drivers/net/tcpip/tcpip/dispatch.c (DispTdiAssociateAddress):
Initialize AddrFile->Connection.
(DispTdiListen): Implement.
* drivers/net/tcpip/tcpip/fileobjs.c (FileOpenAddress): Don't
initialize AddrFile->Connections.
* drivers/net/tcpip/tcpip/routines.c: Include <tcp.h>.
(DisplayIPPacket): Enable.
(DisplayTCPHeader, DisplayTCPPacket): New functions.
* drivers/net/tcpip/transport/tcp/tcp.c: Include <routines.h>.
(TCPListen, TCPiReceive): New functions.
(TCPReceive): Partial implement.
* lib/msafd/misc/helpers.c (CreateHelperDLLDatabase): Add
{SOCK_STREAM,IPPROTO_TCP,0} and {SOCK_DGRAM,IPPROTO_UDP,0} mappings.
* lib/ntdll/ldr/utils.c (LdrLoadDll): Print name of DLL if not found.
* lib/ws2_32/include/ws2_32.h (Initialized): Declare.
(WINSOCK_THREAD_BLOCK): Remove Initialized member.
* (WSAINITIALIZED, WSASETINITIALIZED): Update.
* lib/ws2_32/misc/catalog.c (CreateCatalog): Add
{SOCK_STREAM,IPPROTO_TCP,0} and {SOCK_DGRAM,IPPROTO_UDP,0} mappings.
(Initialized): New variable.
(DllMain): Don't initialize p->Initialized.
* ntoskrnl/dbg/kdb.c: Include <ctype.h>.
* subsys/win32k/ntuser/message.c (NtUserDispatchMessage): Kill noisy
message.
2003-12-10 Casper S. Hornstrup <chorns@users.sourceforge.net>
* tools/wine2ros: New directory.

View file

@ -7,6 +7,7 @@
* REVISIONS:
* CSH 01/09/2000 Created
*/
#include <string.h>
#include <error.h>
#include <socket.h>
#include <iterator.h>

View file

@ -36,7 +36,7 @@ CThread::CThread()
assert(Data.hFinished != NULL);
// Create thread
hThread = CreateThread(NULL, 0, ThreadEntry, &Data, 0, &dwThreadId);
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadEntry, &Data, 0, &dwThreadId);
// FIXME: Do some error handling
assert(hThread != NULL);

View file

@ -12,5 +12,5 @@
void ReportErrorStr(LPTSTR lpsText)
{
wprintf((__wchar_t*)lpsText);
wprintf((wchar_t*)lpsText);
}

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.6 2002/06/07 22:57:51 ekohl Exp $
# $Id: makefile,v 1.7 2003/12/25 14:06:14 chorns Exp $
PATH_TO_TOP = ../../../..
@ -10,7 +10,9 @@ TARGET_APPTYPE = console
TARGET_NAME = roshttpd
TARGET_CPPFLAGS = -I./include -DUNICODE -D_UNICODE -DDBG
TARGET_CPPFLAGS = -I./include -DUNICODE -D_UNICODE -DDBG -Wno-deprecated
TARGET_GCCLIBS = stdc++
TARGET_SDKLIBS = kernel32.a ws2_32.a user32.a

View file

@ -21,6 +21,7 @@ DWORD DebugTraceLevel = MID_TRACE;
NPAGED_LOOKASIDE_LIST BufferLookasideList;
NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
NPAGED_LOOKASIDE_LIST ListenRequestLookasideList;
NTSTATUS
@ -196,7 +197,15 @@ DriverEntry(
TAG('A', 'F', 'D', 'R'),
0);*/
ExInitializeNPagedLookasideList(
&ListenRequestLookasideList,
NULL,
NULL,
0,
sizeof(AFD_LISTEN_REQUEST),
TAG('A', 'F', 'D', 'L'),
0);
return STATUS_SUCCESS;
}

View file

@ -130,6 +130,23 @@ NTSTATUS AfdDispBind(
}
NTSTATUS
STDCALL
AfdDispCompleteListen(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
PAFD_LISTEN_REQUEST ListenRequest = (PAFD_LISTEN_REQUEST) Context;
AFD_DbgPrint(MAX_TRACE, ("Called. ListenRequest (0x%X).\n", ListenRequest));
AFD_DbgPrint(MAX_TRACE, ("Fcb (0x%X).\n", ListenRequest->Fcb));
return STATUS_SUCCESS;
}
NTSTATUS AfdDispListen(
PIRP Irp,
PIO_STACK_LOCATION IrpSp)
@ -148,6 +165,7 @@ NTSTATUS AfdDispListen(
PFILE_REQUEST_LISTEN Request;
PFILE_REPLY_LISTEN Reply;
PAFDFCB FCB;
PAFD_LISTEN_REQUEST ListenRequest;
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
@ -161,32 +179,71 @@ NTSTATUS AfdDispListen(
Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
Reply = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
if (FCB->State == SOCKET_STATE_BOUND) {
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 */
/* 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);
Status = TdiOpenConnectionEndpointFile(
&FCB->TdiDeviceName,
&FCB->TdiConnectionObjectHandle,
&FCB->TdiConnectionObject);
if (NT_SUCCESS(Status))
{
Status = TdiAssociateAddressFile(
FCB->TdiAddressObjectHandle,
FCB->TdiConnectionObject);
if (NT_SUCCESS(Status)) {
Status = TdiAssociateAddressFile(
FCB->TdiAddressObjectHandle,
FCB->TdiConnectionObject);
if (NT_SUCCESS(Status))
{
ListenRequest = ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList);
if (ListenRequest != NULL)
{
ListenRequest->Fcb = FCB;
/* FIXME: Protect ListenRequestQueue */
InsertTailList(&FCB->ListenRequestQueue, &ListenRequest->ListEntry);
Status = TdiListen(FCB->TdiConnectionObject, AfdDispCompleteListen, ListenRequest);
if ((Status == STATUS_PENDING) || NT_SUCCESS(Status))
{
if (Status != STATUS_PENDING)
{
AFD_DbgPrint(MIN_TRACE, ("FIXME: Status (0x%X).\n", Status));
}
}
else
{
/* FIXME: Cleanup ListenRequest */
/* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
}
}
else
{
/* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
Status = STATUS_NO_MEMORY;
}
}
else
{
/* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
}
}
if (NT_SUCCESS(Status)) {
Reply->Status = NO_ERROR;
} else {
Reply->Status = WSAEINVAL;
}
}
if (NT_SUCCESS(Status)) {
Reply->Status = NO_ERROR;
} else {
else if (FCB->State == SOCKET_STATE_CONNECTED)
{
Reply->Status = WSAEISCONN;
}
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));

View file

@ -44,6 +44,8 @@ PAFDFCB AfdInitializeFCB(
InitializeListHead(&NewFCB->ReadRequestQueue);
KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock);
InitializeListHead(&NewFCB->ListenRequestQueue);
if (FileObject)
FileObject->FsContext = (PVOID)NewFCB;
@ -191,6 +193,17 @@ AfdCreate(
}
VOID
AfdKillListenRequests(PAFDFCB FCB)
{
/* FIXME: Implement */
AFD_DbgPrint(MIN_TRACE, ("Unimplemented.\n"));
/*ExFreeToNPagedLookasideList(&ListenRequestLookasideList,
(PVOID)ListenRequest);*/
}
NTSTATUS
STDCALL
AfdClose(
@ -217,6 +230,9 @@ AfdClose(
FCB->ReferenceCount--;
if (FCB->ReferenceCount < 1) {
if (!FCB->CommandChannel) {
/* Kill outstanding listen requests */
AfdKillListenRequests(FCB);
/* Close TDI connection file object */
if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);

View file

@ -11,6 +11,16 @@
#include <debug.h>
VOID DumpName(
LPSOCKADDR Name)
{
AFD_DbgPrint(MIN_TRACE, ("DumpName:\n"));
AFD_DbgPrint(MIN_TRACE, (" sa_family: %d\n", Name->sa_family));
AFD_DbgPrint(MIN_TRACE, (" sin_port: %d\n", WN2H(((LPSOCKADDR_IN)Name)->sin_port)));
AFD_DbgPrint(MIN_TRACE, (" in_addr: 0x%x\n", WN2H(((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr)));
}
ULONG WSABufferSize(
LPWSABUF Buffers,
DWORD BufferCount)

View file

@ -38,6 +38,25 @@ VOID DisplayBuffer(
#endif /* DBG */
inline DWORD TdiAddressSizeFromType(
ULONG Type)
/*
* FUNCTION: Returns the size of a TDI style address of given address type
* ARGUMENTS:
* Type = TDI style address type
* RETURNS:
* Size of TDI style address, 0 if Type is not valid
*/
{
switch (Type) {
case TDI_ADDRESS_TYPE_IP:
return sizeof(TA_IP_ADDRESS);
/* FIXME: More to come */
}
AFD_DbgPrint(MIN_TRACE, ("Unknown TDI address type (%d).\n", Type));
return 0;
}
inline DWORD TdiAddressSizeFromName(
LPSOCKADDR Name)
/*
@ -166,6 +185,7 @@ NTSTATUS TdiBuildConnectionInfo(
sizeof(TDI_CONNECTION_INFORMATION) +
TdiAddressSize);
ConnInfo->OptionsLength = sizeof(ULONG);
ConnInfo->RemoteAddressLength = TdiAddressSize;
ConnInfo->RemoteAddress = (PVOID)
(ConnInfo + sizeof(TDI_CONNECTION_INFORMATION));
@ -178,6 +198,44 @@ NTSTATUS TdiBuildConnectionInfo(
}
NTSTATUS TdiBuildNullConnectionInfo(
PTDI_CONNECTION_INFORMATION *ConnectionInfo,
ULONG Type)
/*
* FUNCTION: Builds a NULL TDI connection information structure
* ARGUMENTS:
* ConnectionInfo = Address of buffer to place connection information
* Type = TDI style address type (TDI_ADDRESS_TYPE_XXX).
* RETURNS:
* Status of operation
*/
{
PTDI_CONNECTION_INFORMATION ConnInfo;
ULONG TdiAddressSize;
TdiAddressSize = TdiAddressSizeFromType(Type);
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->OptionsLength = sizeof(ULONG);
ConnInfo->RemoteAddressLength = 0;
ConnInfo->RemoteAddress = NULL;
*ConnectionInfo = ConnInfo;
return STATUS_SUCCESS;
}
NTSTATUS TdiCall(
PIRP Irp,
PDEVICE_OBJECT DeviceObject,
@ -320,20 +378,22 @@ NTSTATUS TdiOpenAddressFileIPv4(
AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (0x%X)\n",
DeviceName, Name));
/* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
TDI_TRANSPORT_ADDRESS_LENGTH +
sizeof(TA_IP_ADDRESS);
sizeof(TA_IP_ADDRESS) + 1;
EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
if (!EaInfo)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(EaInfo, EaLength);
EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
/* Don't copy the terminating 0; we have already zeroed it */
RtlCopyMemory(EaInfo->EaName,
TdiTransportAddress,
TDI_TRANSPORT_ADDRESS_LENGTH);
EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS);
Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH);
Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */
TdiBuildAddressIPv4(Address, Name);
Status = TdiOpenDevice(DeviceName,
EaLength,
@ -403,9 +463,10 @@ NTSTATUS TdiOpenConnectionEndpointFile(
AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ)\n", DeviceName));
/* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
TDI_CONNECTION_CONTEXT_LENGTH +
sizeof(PVOID);
sizeof(PVOID) + 1;
EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
if (!EaInfo)
@ -413,11 +474,12 @@ NTSTATUS TdiOpenConnectionEndpointFile(
RtlZeroMemory(EaInfo, EaLength);
EaInfo->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH;
/* Don't copy the terminating 0; we have already zeroed it */
RtlCopyMemory(EaInfo->EaName,
TdiConnectionContext,
TDI_CONNECTION_CONTEXT_LENGTH);
EaInfo->EaValueLength = sizeof(PVOID);
ContextArea = (PVOID*)(EaInfo->EaName + TDI_CONNECTION_CONTEXT_LENGTH);
ContextArea = (PVOID*)(EaInfo->EaName + TDI_CONNECTION_CONTEXT_LENGTH + 1); /* 0-terminated */
/* FIXME: Allocate context area */
*ContextArea = NULL;
Status = TdiOpenDevice(DeviceName,
@ -464,6 +526,7 @@ NTSTATUS TdiConnect(
Status = TdiBuildConnectionInfo(&ReturnConnectionInfo, RemoteAddress);
if (!NT_SUCCESS(Status)) {
ExFreePool(RequestConnectionInfo);
ExFreePool(ReturnConnectionInfo);
return Status;
}
@ -476,6 +539,7 @@ NTSTATUS TdiConnect(
&Iosb); /* Status */
if (!Irp) {
ExFreePool(RequestConnectionInfo);
ExFreePool(ReturnConnectionInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -545,6 +609,69 @@ NTSTATUS TdiAssociateAddressFile(
}
NTSTATUS TdiListen(
PFILE_OBJECT ConnectionObject,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
* FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
* ARGUMENTS:
* ConnectionObject = Pointer to connection endpoint file object
* CompletionRoutine = Routine to be called when IRP is completed
* CompletionContext = Context for CompletionRoutine
* RETURNS:
* Status of operation
* May return STATUS_PENDING
*/
{
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 = TdiBuildNullConnectionInfo(&RequestConnectionInfo, TDI_ADDRESS_TYPE_IP);
if (!NT_SUCCESS(Status))
return Status;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN, /* Sub function */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
&Event, /* Event */
&Iosb); /* Status */
if (!Irp) {
ExFreePool(RequestConnectionInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
TdiBuildListen(Irp, /* IRP */
DeviceObject, /* Device object */
ConnectionObject, /* File object */
CompletionRoutine, /* Completion routine */
CompletionContext, /* Completion routine context */
0, /* Flags */
RequestConnectionInfo, /* Request connection information */
NULL /* ReturnConnectionInfo */); /* Return connection information */
Status = TdiCall(Irp, DeviceObject, NULL /* Don't wait for completion */, &Iosb);
ExFreePool(RequestConnectionInfo);
//ExFreePool(ReturnConnectionInfo);
return Status;
}
NTSTATUS TdiSetEventHandler(
PFILE_OBJECT FileObject,
LONG EventType,

View file

@ -68,6 +68,7 @@ typedef struct _AFDFCB {
KSPIN_LOCK ReceiveQueueLock;
LIST_ENTRY ReadRequestQueue;
KSPIN_LOCK ReadRequestQueueLock;
LIST_ENTRY ListenRequestQueue;
/* For WSAEventSelect() */
WSANETWORKEVENTS NetworkEvents;
WSAEVENT EventObjects[FD_MAX_EVENTS];
@ -91,6 +92,11 @@ typedef struct _AFD_READ_REQUEST {
PFILE_REPLY_RECVFROM RecvFromReply;
} AFD_READ_REQUEST, *PAFD_READ_REQUEST;
typedef struct _AFD_LISTEN_REQUEST {
LIST_ENTRY ListEntry;
PAFDFCB Fcb;
} AFD_LISTEN_REQUEST, *PAFD_LISTEN_REQUEST;
typedef struct IPSNMP_INFO {
ULONG Forwarding;
ULONG DefaultTTL;
@ -207,7 +213,7 @@ typedef struct IPv4_HEADER {
extern NPAGED_LOOKASIDE_LIST BufferLookasideList;
extern NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
extern NPAGED_LOOKASIDE_LIST ListenRequestLookasideList;
/* Prototypes from dispatch.c */
@ -294,6 +300,9 @@ NTSTATUS STDCALL AfdWrite(
/* Prototypes from routines.c */
VOID DumpName(
LPSOCKADDR Name);
ULONG WSABufferSize(
LPWSABUF Buffers,
DWORD BufferCount);
@ -349,6 +358,11 @@ NTSTATUS TdiAssociateAddressFile(
HANDLE AddressHandle,
PFILE_OBJECT ConnectionObject);
NTSTATUS TdiListen(
PFILE_OBJECT ConnectionObject,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);
NTSTATUS TdiSetEventHandler(
PFILE_OBJECT FileObject,
LONG EventType,

View file

@ -701,7 +701,6 @@ VOID BindAdapter(
UnicodeAddress.MaximumLength = Information->DataLength;
AnsiLen = RtlUnicodeStringToAnsiSize(&UnicodeAddress);
if(!AnsiLen)
{
TI_DbgPrint(MIN_TRACE, ("Unable to calculate address length\n"));
@ -711,34 +710,40 @@ VOID BindAdapter(
}
AnsiAddress.Buffer = ExAllocatePoolWithTag(PagedPool, AnsiLen, 0x01020304);
if(!AnsiAddress.Buffer)
{
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
TI_DbgPrint(MIN_TRACE, ("ExAllocatePoolWithTag() failed.\n"));
FreeTDPackets(Adapter);
IPDestroyInterface(Adapter->Context);
return;
}
AnsiAddress.Length = AnsiLen;
AnsiAddress.MaximumLength = AnsiLen;
Status = RtlUnicodeStringToAnsiString(&AnsiAddress, &UnicodeAddress, FALSE);
if (!NT_SUCCESS(Status))
{
TI_DbgPrint(MIN_TRACE, ("RtlUnicodeStringToAnsiString() failed with Status 0x%lx.\n", Status));
FreeTDPackets(Adapter);
IPDestroyInterface(Adapter->Context);
return;
}
RtlUnicodeStringToAnsiString(&AnsiAddress, &UnicodeAddress, FALSE);
AnsiAddress.Buffer[AnsiAddress.Length] = 0;
Address = AddrBuildIPv4(inet_addr(AnsiAddress.Buffer));
if (!Address) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
TI_DbgPrint(MIN_TRACE, ("AddrBuildIPv4() failed.\n"));
FreeTDPackets(Adapter);
IPDestroyInterface(Adapter->Context);
return;
}
TI_DbgPrint(MID_TRACE, ("--> Our IP address on this interface: 0x%x\n", inet_addr(AnsiAddress.Buffer)));
TI_DbgPrint(MID_TRACE, ("--> Our IP address on this interface: '%s'\n", A2S(Address)));
}
/* Create a net table entry for this interface */
if (!IPCreateNTE(IF, Address, 8)) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
TI_DbgPrint(MIN_TRACE, ("IPCreateNTE() failed.\n"));
FreeTDPackets(Adapter);
IPDestroyInterface(IF);
return;

View file

@ -24,11 +24,13 @@
#define DEBUG_DATALINK 0x00004000
#define DEBUG_ARP 0x00008000
#define DEBUG_IP 0x00010000
#define DEBUG_ICMP 0x00020000
#define DEBUG_ROUTER 0x00040000
#define DEBUG_RCACHE 0x00080000
#define DEBUG_NCACHE 0x00100000
#define DEBUG_CPOINT 0x00200000
#define DEBUG_UDP 0x00020000
#define DEBUG_TCP 0x00040000
#define DEBUG_ICMP 0x00080000
#define DEBUG_ROUTER 0x00100000
#define DEBUG_RCACHE 0x00200000
#define DEBUG_NCACHE 0x00400000
#define DEBUG_CPOINT 0x00800000
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG

View file

@ -69,8 +69,12 @@ UINT ResizePacket(
VOID DisplayIPPacket(
PIP_PACKET IPPacket);
#define DISPLAY_IP_PACKET(x) DisplayIPPacket(x)
VOID DisplayTCPPacket(
PIP_PACKET IPPacket);
#define DISPLAY_TCP_PACKET(x) DisplayTCPPacket(x)
#else
#define DISPLAY_IP_PACKET(x)
#define DISPLAY_TCP_PACKET(x)
#endif /* DBG */
#endif /* __ROUTINES_H */

View file

@ -95,6 +95,11 @@ NTSTATUS TCPConnect(
PTDI_CONNECTION_INFORMATION ConnInfo,
PTDI_CONNECTION_INFORMATION ReturnInfo);
NTSTATUS TCPListen(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PTDI_CONNECTION_INFORMATION ReturnInfo);
NTSTATUS TCPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,

View file

@ -176,7 +176,9 @@ 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 */
struct _CONNECTION_ENDPOINT *Connection;
/* Associated connection or NULL if no
associated connection exist */
PIP_ADDRESS AddrCache; /* One entry address cache (destination
address of last packet transmitted) */
@ -308,10 +310,10 @@ typedef struct _CONNECTION_ENDPOINT {
CONNECTION_STATE State; /* Connection state */
PIP_ADDRESS LocalAddress; /* Pointer to local IP address */
USHORT LocalPort; /* Local port number */
USHORT LocalPort; /* Local port number (network byte order) */
PIP_ADDRESS RemoteAddress; /* Pointer to remote IP address */
USHORT RemotePort; /* Remote port number */
USHORT RemotePort; /* Remote port number (network byte order) */
/* Send sequence variables */
ULONG SendUnacknowledged; /* Highest sequence number that is acknowledged */

View file

@ -515,10 +515,8 @@ PNET_TABLE_ENTRY IPLocateNTEOnInterface(
PLIST_ENTRY CurrentEntry;
PADDRESS_ENTRY Current;
// TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) AddressType (0x%X).\n",
// IF, Address, AddressType));
// TI_DbgPrint(DEBUG_IP, ("Address (%s) AddressType (0x%X).\n", A2S(Address)));
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (%s) AddressType (0x%X).\n",
IF, A2S(Address), AddressType));
KeAcquireSpinLock(&IF->Lock, &OldIrql);
@ -537,9 +535,6 @@ PNET_TABLE_ENTRY IPLocateNTEOnInterface(
KeReleaseSpinLock(&IF->Lock, OldIrql);
return Current->NTE;
}
else {
TI_DbgPrint(DEBUG_IP, ("CurrentEntry = 0x%X != &IF->ADEListHead = 0x%X.\n", CurrentEntry, &IF->ADEListHead));
}
CurrentEntry = CurrentEntry->Flink;
}

View file

@ -386,10 +386,10 @@ PADDRESS_FILE AddrSearchNext(
IPAddress = Current->ADE->Address;
TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, %s), (%d, %d, %s)).\n",
Current->Port,
WN2H(Current->Port),
Current->Protocol,
A2S(IPAddress),
SearchContext->Port,
WN2H(SearchContext->Port),
SearchContext->Protocol,
A2S(SearchContext->Address)));

View file

@ -326,11 +326,8 @@ NTSTATUS DispTdiAssociateAddress(
ReferenceObject(AddrFile);
Connection->AddressFile = AddrFile;
/* Add connection endpoint to connection list on the address file */
ExInterlockedInsertTailList(
&AddrFile->Connections,
&Connection->AddrFileEntry,
&AddrFile->Lock);
/* Add connection endpoint to the address file */
AddrFile->Connection = Connection;
/* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
ObDereferenceObject(FileObject);
@ -465,9 +462,44 @@ NTSTATUS DispTdiListen(
* Status of operation
*/
{
PCONNECTION_ENDPOINT Connection;
PTDI_REQUEST_KERNEL Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
TDI_REQUEST Request;
NTSTATUS Status;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_NOT_IMPLEMENTED;
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 = TCPListen(
&Request,
Parameters->RequestConnectionInformation,
Parameters->ReturnConnectionInformation);
return Status;
}

View file

@ -317,6 +317,9 @@ NTSTATUS FileOpenAddress(
TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n",
Protocol));
TI_DbgPrint(MID_TRACE, ("Port number for address file object is %d.\n",
WN2H(AddrFile->Port)));
/* Set protocol */
AddrFile->Protocol = Protocol;
@ -324,9 +327,6 @@ NTSTATUS FileOpenAddress(
InitializeListHead(&AddrFile->ReceiveQueue);
InitializeListHead(&AddrFile->TransmitQueue);
/* Initialize associated connection list */
InitializeListHead(&AddrFile->Connections);
/* Initialize work queue item. We use this for pending requests */
ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);

View file

@ -10,9 +10,10 @@
#include <tcpip.h>
#include <routines.h>
#include <pool.h>
#include <tcp.h>
UINT RandomNumber = 0x12345678;
static UINT RandomNumber = 0x12345678;
inline NTSTATUS BuildDatagramSendRequest(
@ -482,14 +483,13 @@ UINT ResizePacket(
VOID DisplayIPPacket(
PIP_PACKET IPPacket)
{
#if 0
UINT i;
PCHAR p;
UINT Length;
PNDIS_BUFFER Buffer;
PNDIS_BUFFER NextBuffer;
if ((DebugTraceLevel & DEBUG_BUFFER) == 0) {
if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_IP)) != (DEBUG_BUFFER | DEBUG_IP)) {
return;
}
@ -528,8 +528,79 @@ VOID DisplayIPPacket(
}
DbgPrint("\n");
}
#endif
}
#endif /* DBG */
/* EOF */
static VOID DisplayTCPHeader(
PUCHAR Header,
UINT Length)
{
/* FIXME: IPv4 only */
PIPv4_HEADER IPHeader = (PIPv4_HEADER)Header;
PTCP_HEADER TCPHeader;
if (IPHeader->Protocol != IPPROTO_TCP) {
DbgPrint("This is not a TCP datagram. Protocol is %d\n", IPHeader->Protocol);
return;
}
DbgPrint("VerIHL: 0x%x\n", IPHeader->VerIHL);
TCPHeader = (PTCP_HEADER)((PUCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4);
DbgPrint("TCP header:\n");
DbgPrint(" SourcePort: %d\n", WN2H(TCPHeader->SourcePort));
DbgPrint(" DestPort: %d\n", WN2H(TCPHeader->DestPort));
DbgPrint(" SeqNum: %d\n", WN2H(TCPHeader->SeqNum));
DbgPrint(" AckNum: %d\n", WN2H(TCPHeader->AckNum));
DbgPrint(" DataOfs: %d (%d)\n", TCPHeader->DataOfs, TCPHeader->DataOfs & 0x0F);
DbgPrint(" Flags: 0x%x (0x%x)\n", TCPHeader->Flags, TCPHeader->Flags & 0x3F);
if ((TCPHeader->Flags & TCP_URG) > 0) DbgPrint(" TCP_URG - Urgent Pointer field significant\n");
if ((TCPHeader->Flags & TCP_ACK) > 0) DbgPrint(" TCP_ACK - Acknowledgment field significant\n");
if ((TCPHeader->Flags & TCP_PSH) > 0) DbgPrint(" TCP_PSH - Push Function\n");
if ((TCPHeader->Flags & TCP_RST) > 0) DbgPrint(" TCP_RST - Reset the connection\n");
if ((TCPHeader->Flags & TCP_SYN) > 0) DbgPrint(" TCP_SYN - Synchronize sequence numbers\n");
if ((TCPHeader->Flags & TCP_FIN) > 0) DbgPrint(" TCP_FIN - No more data from sender\n");
DbgPrint(" Window: %d\n", WN2H(TCPHeader->Window));
DbgPrint(" Checksum: %d\n", WN2H(TCPHeader->Checksum));
DbgPrint(" Urgent: %d\n", WN2H(TCPHeader->Urgent));
}
VOID DisplayTCPPacket(
PIP_PACKET IPPacket)
{
UINT Length;
PUCHAR Buffer;
if ((DebugTraceLevel & (DEBUG_BUFFER | DEBUG_TCP)) != (DEBUG_BUFFER | DEBUG_TCP)) {
return;
}
if (!IPPacket) {
TI_DbgPrint(MIN_TRACE, ("Cannot display null packet.\n"));
return;
}
DisplayIPPacket(IPPacket);
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));
TI_DbgPrint(MIN_TRACE, ("ContigSize (%d).\n", IPPacket->ContigSize));
TI_DbgPrint(MIN_TRACE, ("NdisPacket (0x%X).\n", IPPacket->NdisPacket));
if (IPPacket->NdisPacket) {
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
Buffer = ExAllocatePool(NonPagedPool, Length);
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length);
DisplayTCPHeader(Buffer, Length);
ExFreePool(Buffer);
} else {
Buffer = IPPacket->Header;
Length = IPPacket->ContigSize;
DisplayTCPHeader(Buffer, Length);
}
}
#endif /* DBG */

View file

@ -12,9 +12,10 @@
#include <pool.h>
#include <address.h>
#include <datagram.h>
#include <routines.h>
BOOLEAN TCPInitialized = FALSE;
static BOOLEAN TCPInitialized = FALSE;
NTSTATUS TCPiAddHeaderIPv4(
@ -395,6 +396,60 @@ NTSTATUS TCPConnect(
}
NTSTATUS TCPListen(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PTDI_CONNECTION_INFORMATION ReturnInfo)
/*
* FUNCTION: Start listening for a connection from 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 listening for connections from 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 unsuccessful */
KeReleaseSpinLock(&Connection->Lock, OldIrql);
return STATUS_UNSUCCESSFUL;
}
Connection->LocalAddress = Connection->AddressFile->ADE->Address;
Connection->LocalPort = Connection->AddressFile->Port;
TI_DbgPrint(MIN_TRACE, ("Connection->LocalAddress (%s).\n", A2S(Connection->LocalAddress)));
TI_DbgPrint(MIN_TRACE, ("Connection->LocalPort (%d).\n", Connection->LocalPort));
/* Start listening for connection requests */
Connection->State = ctListen;
KeReleaseSpinLock(&Connection->Lock, OldIrql);
Status = STATUS_PENDING;
TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
return Status;
}
NTSTATUS TCPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
@ -415,6 +470,576 @@ NTSTATUS TCPSendDatagram(
}
static VOID TCPiReceive(
PADDRESS_FILE AddrFile,
PIP_PACKET IPPacket,
PTCP_HEADER TCPHeader)
{
register CONNECTION_STATE State;
if (AddrFile->Connection == NULL || AddrFile->Connection->State == ctClosed)
{
if ((TCPHeader->Flags & TCP_RST) == 0)
{
/* FIXME: Send RST
* If the ACK bit is off, sequence number zero is used,
*
* <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
*
* If the ACK bit is on,
*
* <SEQ=SEG.ACK><CTL=RST>
*/
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
}
return;
}
if (AddrFile->Connection->State == ctListen)
{
if ((TCPHeader->Flags & TCP_RST) > 0)
{
/* Discard */
return;
}
if ((TCPHeader->Flags & TCP_ACK) > 0)
{
/* FIXME: Send RST
<SEQ=SEG.ACK><CTL=RST> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
return;
}
if ((TCPHeader->Flags & TCP_SYN) > 0)
{
/* FIXME: If the SEG.PRC is greater than the TCB.PRC then if allowed by
the user and the system set TCB.PRC<-SEG.PRC, if not allowed
send a reset and return. */
if (FALSE)
{
/* FIXME: Send RST
* <SEQ=SEG.ACK><CTL=RST>
*/
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
return;
}
/* Set RCV.NXT to SEG.SEQ+1, IRS is set to SEG.SEQ and any other
control or text should be queued for processing later. ISS
should be selected and a SYN segment sent of the form:
<SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
SND.NXT is set to ISS+1 and SND.UNA to ISS. The connection
state should be changed to SYN-RECEIVED. Note that any other
incoming control or data (combined with SYN) will be processed
in the SYN-RECEIVED state, but processing of SYN and ACK should
not be repeated. If the listen was not fully specified (i.e.,
the foreign socket was not fully specified), then the
unspecified fields should be filled in now.
*/
TI_DbgPrint(MIN_TRACE, ("FIXME: Go to ctSynReceived connection state.\n"));
return;
}
/* Discard the segment as it is invalid */
return;
}
if (AddrFile->Connection->State == ctSynSent)
{
if ((TCPHeader->Flags & TCP_ACK) > 0)
{
/* FIXME: If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send a reset (unless
the RST bit is set, if so drop the segment and return)
<SEQ=SEG.ACK><CTL=RST> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
return;
}
/* FIXME: If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable. */
if ((TCPHeader->Flags & TCP_RST) > 0)
{
if (TRUE /* ACK is acceptable */)
{
AddrFile->Connection->State = ctClosed;
/* FIXME: Signal client */
TI_DbgPrint(MIN_TRACE, ("FIXME: Signal client.\n"));
}
else
{
/* Discard segment */
}
return;
}
/* FIXME: If the security/compartment in the segment does not exactly
match the security/compartment in the TCB */
if (FALSE)
{
if ((TCPHeader->Flags & TCP_ACK) > 0)
{
/* FIXME: Send RST
<SEQ=SEG.ACK><CTL=RST> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
}
else
{
/* FIXME: Send RST
<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
}
return;
}
if ((TCPHeader->Flags & TCP_ACK) > 0)
{
/* FIXME: If the precedence in the segment does not match the precedence in the TCB */
if (FALSE)
{
/* FIXME: Send RST
<SEQ=SEG.ACK><CTL=RST> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
return;
}
else
{
/* FIXME: If the precedence in the segment is higher than the precedence
in the TCB then if allowed by the user and the system raise
the precedence in the TCB to that in the segment, if not
allowed to raise the prec then send a reset. */
if (FALSE)
{
/* FIXME: Send RST
<SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
return;
}
else
{
/* Continue */
}
}
return;
}
/* The ACK is ok, or there is no ACK, and it the segment did not contain a RST */
if ((TCPHeader->Flags & TCP_SYN) > 0)
{
/* FIXME: The security/compartment and precedence are acceptable */
if (TRUE)
{
/* FIXME: RCV.NXT is set to SEG.SEQ+1, IRS is set to
SEG.SEQ. SND.UNA should be advanced to equal SEG.ACK (if there
is an ACK), and any segments on the retransmission queue which
are thereby acknowledged should be removed.
If SND.UNA > ISS (our SYN has been ACKed), change the connection
state to ESTABLISHED, form an ACK segment
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
Data or controls which were queued for
transmission may be included. If there are other controls or
text in the segment then continue processing at the sixth step
below where the URG bit is checked, otherwise return.
Otherwise enter SYN-RECEIVED, form a SYN,ACK segment
<SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
and send it. If there are other controls or text in the
segment, queue them for processing after the ESTABLISHED state
has been reached, return. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Maybe go to ctEstablished connection state.\n"));
}
else
{
/* FIXME: What happens here? */
}
}
/* FIXME: Send RST
<SEQ=SEG.ACK><CTL=RST> */
TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
return;
}
State = AddrFile->Connection->State;
if (State == ctSynReceived
|| State == ctEstablished
|| State == ctFinWait1
|| State == ctFinWait2
|| State == ctCloseWait
|| State == ctClosing
|| State == ctLastAck
|| State == ctTimeWait)
{
/* Segments are processed in sequence. Initial tests on arrival
are used to discard old duplicates, but further processing is
done in SEG.SEQ order. If a segment's contents straddle the
boundary between old and new, only the new parts should be
processed.
There are four cases for the acceptability test for an incoming
segment:
Segment Receive Test
Length Window
------- ------- -------------------------------------------
0 0 SEG.SEQ = RCV.NXT
0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>0 0 not acceptable
>0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
If the RCV.WND is zero, no segments will be acceptable, but
special allowance should be made to accept valid ACKs, URGs and
RSTs.
If an incoming segment is not acceptable, an acknowledgment
should be sent in reply (unless the RST bit is set, if so drop
the segment and return):
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
After sending the acknowledgment, drop the unacceptable segment
and return. */
if ((TCPHeader->Flags & TCP_RST) > 0)
{
if (AddrFile->Connection->State == ctSynReceived)
{
/* FIXME: If this connection was initiated with a passive OPEN (i.e.,
came from the LISTEN state), then return this connection to
LISTEN state and return. The user need not be informed. If
this connection was initiated with an active OPEN (i.e., came
from SYN-SENT state) then the connection was refused, signal
the user "connection refused". In either case, all segments
on the retransmission queue should be removed. And in the
active OPEN case, enter the CLOSED state and delete the TCB,
and return. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Maybe go to ctListen or ctClosed connection state.\n"));
return;
}
State = AddrFile->Connection->State;
if (State == ctEstablished
|| State == ctFinWait1
|| State == ctFinWait2
|| State == ctCloseWait)
{
/* FIXME: any outstanding RECEIVEs and SEND
should receive "reset" responses. All segment queues should be
flushed. Users should also receive an unsolicited general
"connection reset" signal. Enter the CLOSED state, delete the
TCB, and return. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Go to ctClosed connection state.\n"));
return;
}
State = AddrFile->Connection->State;
if (State == ctClosing
|| State == ctLastAck
|| State == ctTimeWait)
{
AddrFile->Connection->State = ctClosed;
return;
}
}
/* FIXME: check security and precedence */
if (AddrFile->Connection->State == ctSynReceived)
{
/* FIXME: If the security/compartment and precedence in the segment do not
exactly match the security/compartment and precedence in the TCB
then send a reset, and return. */
}
if (AddrFile->Connection->State == ctSynReceived)
{
/* FIXME: If the security/compartment and precedence in the segment do not
exactly match the security/compartment and precedence in the TCB
then send a reset, any outstanding RECEIVEs and SEND should
receive "reset" responses. All segment queues should be
flushed. Users should also receive an unsolicited general
"connection reset" signal. Enter the CLOSED state, delete the
TCB, and return. */
}
/* Note the previous check is placed following the sequence check to prevent
a segment from an old connection between these ports with a
different security or precedence from causing an abort of the
current connection. */
if ((TCPHeader->Flags & TCP_SYN) > 0)
{
State = AddrFile->Connection->State;
if (State == ctSynReceived
|| State == ctEstablished
|| State == ctFinWait1
|| State == ctFinWait2
|| State == ctCloseWait
|| State == ctClosing
|| State == ctLastAck
|| State == ctTimeWait)
{
/* FIXME: If the SYN is in the window it is an error, send a reset, any
outstanding RECEIVEs and SEND should receive "reset" responses,
all segment queues should be flushed, the user should also
receive an unsolicited general "connection reset" signal, enter
the CLOSED state, delete the TCB, and return.
If the SYN is not in the window this step would not be reached
and an ack would have been sent in the first step (sequence
number check). */
TI_DbgPrint(MIN_TRACE, ("FIXME: Maybe go to ctClosed connection state.\n"));
return;
}
}
if ((TCPHeader->Flags & TCP_ACK) == 0)
{
/* Discard the segment */
return;
}
if (AddrFile->Connection->State == ctSynReceived)
{
/* FIXME: If SND.UNA =< SEG.ACK =< SND.NXT then enter ESTABLISHED state
and continue processing.
If the segment acknowledgment is not acceptable, form a
reset segment,
<SEQ=SEG.ACK><CTL=RST>
and send it. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Maybe go to ctEstablished connection state.\n"));
return;
}
State = AddrFile->Connection->State;
if (State == ctEstablished
|| State == ctCloseWait)
{
/* FIXME: If SND.UNA < SEG.ACK =< SND.NXT then, set SND.UNA <- SEG.ACK.
Any segments on the retransmission queue which are thereby
entirely acknowledged are removed. Users should receive
positive acknowledgments for buffers which have been SENT and
fully acknowledged (i.e., SEND buffer should be returned with
"ok" response). If the ACK is a duplicate
(SEG.ACK < SND.UNA), it can be ignored. If the ACK acks
something not yet sent (SEG.ACK > SND.NXT) then send an ACK,
drop the segment, and return.
If SND.UNA < SEG.ACK =< SND.NXT, the send window should be
updated. If (SND.WL1 < SEG.SEQ or (SND.WL1 = SEG.SEQ and
SND.WL2 =< SEG.ACK)), set SND.WND <- SEG.WND, set
SND.WL1 <- SEG.SEQ, and set SND.WL2 <- SEG.ACK.
Note that SND.WND is an offset from SND.UNA, that SND.WL1
records the sequence number of the last segment used to update
SND.WND, and that SND.WL2 records the acknowledgment number of
the last segment used to update SND.WND. The check here
prevents using old segments to update the window. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Maybe send ACK.\n"));
return;
}
if (AddrFile->Connection->State == ctFinWait1)
{
/* FIXME: In addition to the processing for the ESTABLISHED state, if
our FIN is now acknowledged then enter FIN-WAIT-2 and continue
processing in that state. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle ctFinWait1 connection state.\n"));
return;
}
if (AddrFile->Connection->State == ctFinWait2)
{
/* FIXME: In addition to the processing for the ESTABLISHED state, if
the retransmission queue is empty, the user's CLOSE can be
acknowledged ("ok") but do not delete the TCB. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle ctFinWait2 connection state.\n"));
return;
}
if (AddrFile->Connection->State == ctClosing)
{
/* FIXME: In addition to the processing for the ESTABLISHED state, if
the ACK acknowledges our FIN then enter the TIME-WAIT state,
otherwise ignore the segment. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle ctClosing connection state.\n"));
return;
}
if (AddrFile->Connection->State == ctLastAck)
{
/* FIXME: The only thing that can arrive in this state is an
acknowledgment of our FIN. If our FIN is now acknowledged,
delete the TCB, enter the CLOSED state, and return. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle ctLastAck connection state.\n"));
return;
}
if (AddrFile->Connection->State == ctTimeWait)
{
/* FIXME: The only thing that can arrive in this state is a
retransmission of the remote FIN. Acknowledge it, and restart
the 2 MSL timeout. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle ctTimeWait connection state.\n"));
return;
}
if ((TCPHeader->Flags & TCP_URG) > 0)
{
State = AddrFile->Connection->State;
if (State == ctEstablished
|| State == ctFinWait1
|| State == ctFinWait2)
{
/* FIXME: If the URG bit is set, RCV.UP <- max(RCV.UP,SEG.UP), and signal
the user that the remote side has urgent data if the urgent
pointer (RCV.UP) is in advance of the data consumed. If the
user has already been signaled (or is still in the "urgent
mode") for this continuous sequence of urgent data, do not
signal the user again. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle URG flag.\n"));
return;
}
State = AddrFile->Connection->State;
if (State == ctCloseWait
|| State == ctClosing
|| State == ctLastAck
|| State == ctTimeWait)
{
/* This should not occur, since a FIN has been received from the
remote side. Ignore the URG. */
}
}
State = AddrFile->Connection->State;
if (State == ctEstablished
|| State == ctFinWait1
|| State == ctFinWait2)
{
/* FIXME: Once in the ESTABLISHED state, it is possible to deliver segment
text to user RECEIVE buffers. Text from segments can be moved
into buffers until either the buffer is full or the segment is
empty. If the segment empties and carries an PUSH flag, then
the user is informed, when the buffer is returned, that a PUSH
has been received.
When the TCP takes responsibility for delivering the data to the
user it must also acknowledge the receipt of the data.
Once the TCP takes responsibility for the data it advances
RCV.NXT over the data accepted, and adjusts RCV.WND as
apporopriate to the current buffer availability. The total of
RCV.NXT and RCV.WND should not be reduced.
Please note the window management suggestions in section 3.7.
Send an acknowledgment of the form:
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
This acknowledgment should be piggybacked on a segment being
transmitted if possible without incurring undue delay. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle data.\n"));
return;
}
State = AddrFile->Connection->State;
if (State == ctCloseWait
|| State == ctClosing
|| State == ctLastAck
|| State == ctTimeWait)
{
/* This should not occur, since a FIN has been received from the
remote side. Ignore the segment text. */
}
if ((TCPHeader->Flags & TCP_FIN) > 0)
{
/* Do not process the FIN if the state is CLOSED, LISTEN or SYN-SENT
since the SEG.SEQ cannot be validated; drop the segment and
return. */
State = AddrFile->Connection->State;
if (State == ctClosed
|| State == ctListen
|| State == ctSynSent)
{
/* Discard segment */
return;
}
/* FIXME: If the FIN bit is set, signal the user "connection closing" and
return any pending RECEIVEs with same message, advance RCV.NXT
over the FIN, and send an acknowledgment for the FIN. Note that
FIN implies PUSH for any segment text not yet delivered to the
user. */
TI_DbgPrint(MIN_TRACE, ("FIXME: Handle FIN flag.\n"));
State = AddrFile->Connection->State;
switch (State)
{
case ctSynReceived:
case ctEstablished:
{
/* FIXME: Enter ctClosed state */
break;
}
case ctFinWait1:
{
/* FIXME: If our FIN has been ACKed (perhaps in this segment), then
enter TIME-WAIT, start the time-wait timer, turn off the other
timers; otherwise enter the CLOSING state. */
break;
}
case ctFinWait2:
{
/* FIXME: Enter the TIME-WAIT state. Start the time-wait timer, turn
off the other timers. */
break;
}
case ctCloseWait:
case ctClosing:
case ctLastAck:
{
/* Remain in ctCloseWait, ctClosing or ctLastAck connection state */
break;
}
case ctTimeWait:
{
/* Remain in ctTimeWait connection state. Restart the 2 MSL time-wait
timeout */
return;
}
default:
ASSERT(FALSE);
return;
}
}
return;
}
}
VOID TCPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
@ -427,10 +1052,12 @@ VOID TCPReceive(
* This is the low level interface for receiving TCP data
*/
{
AF_SEARCH SearchContext;
PIPv4_HEADER IPv4Header;
PADDRESS_FILE AddrFile;
PTCP_HEADER TCPHeader;
PIP_ADDRESS DstAddress;
UINT DataSize, i;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
@ -453,8 +1080,36 @@ VOID TCPReceive(
return;
}
DISPLAY_TCP_PACKET(IPPacket);
TCPHeader = (PTCP_HEADER)IPPacket->Data;
/* FIXME: Calculate and validate TCP checksum */
/* FIXME: Sanity checks */
/* Locate the on destination address file object and deliver the
packet if one is found. If no matching address file object can be
found, drop the packet */
AddrFile = AddrSearchFirst(DstAddress,
TCPHeader->DestPort,
IPPROTO_TCP,
&SearchContext);
if (AddrFile) {
/* There can be only one client */
TI_DbgPrint(MID_TRACE, ("Found address file object for IPv4 TCP datagram to address (0x%X).\n",
DN2H(DstAddress->Address.IPv4Address)));
TCPiReceive(AddrFile, IPPacket, TCPHeader);
} else {
/* There are no open address files that will take this datagram */
/* FIXME: IPv4 only */
TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 TCP datagram to address (0x%X).\n",
DN2H(DstAddress->Address.IPv4Address)));
/* FIXME: Send ICMP reply */
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}

View file

@ -231,25 +231,33 @@ VOID CreateHelperDLLDatabase(VOID)
HelperDLL->Mapping = HeapAlloc(
GlobalHeap,
0,
3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
5 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
if (!HelperDLL->Mapping)
return;
HelperDLL->Mapping->Rows = 3;
HelperDLL->Mapping->Rows = 5;
HelperDLL->Mapping->Columns = 3;
HelperDLL->Mapping->Mapping[0].AddressFamily = AF_INET;
HelperDLL->Mapping->Mapping[0].SocketType = SOCK_STREAM;
HelperDLL->Mapping->Mapping[0].Protocol = IPPROTO_TCP;
HelperDLL->Mapping->Mapping[0].Protocol = 0;
HelperDLL->Mapping->Mapping[1].AddressFamily = AF_INET;
HelperDLL->Mapping->Mapping[1].SocketType = SOCK_DGRAM;
HelperDLL->Mapping->Mapping[1].Protocol = IPPROTO_UDP;
HelperDLL->Mapping->Mapping[1].SocketType = SOCK_STREAM;
HelperDLL->Mapping->Mapping[1].Protocol = IPPROTO_TCP;
HelperDLL->Mapping->Mapping[2].AddressFamily = AF_INET;
HelperDLL->Mapping->Mapping[2].SocketType = SOCK_RAW;
HelperDLL->Mapping->Mapping[2].SocketType = SOCK_DGRAM;
HelperDLL->Mapping->Mapping[2].Protocol = 0;
HelperDLL->Mapping->Mapping[3].AddressFamily = AF_INET;
HelperDLL->Mapping->Mapping[3].SocketType = SOCK_DGRAM;
HelperDLL->Mapping->Mapping[3].Protocol = IPPROTO_UDP;
HelperDLL->Mapping->Mapping[4].AddressFamily = AF_INET;
HelperDLL->Mapping->Mapping[4].SocketType = SOCK_RAW;
HelperDLL->Mapping->Mapping[4].Protocol = 0;
LoadHelperDLL(HelperDLL);
}

View file

@ -1,4 +1,4 @@
/* $Id: utils.c,v 1.75 2003/11/30 20:37:34 gdalsnes Exp $
/* $Id: utils.c,v 1.76 2003/12/25 14:06:15 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -542,14 +542,15 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
&SectionHandle);
}
RtlFreeUnicodeString(&AdjustedName);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create or open dll section (Status %lx)\n", Status);
DPRINT1("Failed to create or open dll section of '%wZ' (Status %lx)\n", &AdjustedName, Status);
RtlFreeUnicodeString(&AdjustedName);
return Status;
}
RtlFreeUnicodeString(&AdjustedName);
/*
* Map the dll into the process.
*/

View file

@ -20,21 +20,21 @@ unsigned long strtoul(const char *nptr, char **endptr, int base);
#define EXPORT STDCALL
extern HANDLE GlobalHeap;
extern BOOL Initialized; /* TRUE if WSAStartup() has been successfully called */
extern WSPUPCALLTABLE UpcallTable;
typedef struct _WINSOCK_THREAD_BLOCK {
INT LastErrorValue; /* Error value from last function that failed */
BOOL Initialized; /* TRUE if WSAStartup() has been successfully called */
CHAR Intoa[16]; /* Buffer for inet_ntoa() */
} WINSOCK_THREAD_BLOCK, *PWINSOCK_THREAD_BLOCK;
/* Macros */
#define WSAINITIALIZED (((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Initialized)
#define WSAINITIALIZED (Initialized)
#define WSASETINITIALIZED (((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Initialized = TRUE)
#define WSASETINITIALIZED (Initialized = TRUE)
#ifdef LE

View file

@ -280,24 +280,32 @@ VOID CreateCatalog(VOID)
Provider->Mapping = HeapAlloc(GlobalHeap,
0,
3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
5 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
if (!Provider->Mapping)
return;
Provider->Mapping->Rows = 3;
Provider->Mapping->Rows = 5;
Provider->Mapping->Columns = 3;
Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
Provider->Mapping->Mapping[0].SocketType = SOCK_STREAM;
Provider->Mapping->Mapping[0].Protocol = IPPROTO_TCP;
Provider->Mapping->Mapping[0].Protocol = 0;
Provider->Mapping->Mapping[1].AddressFamily = AF_INET;
Provider->Mapping->Mapping[1].SocketType = SOCK_DGRAM;
Provider->Mapping->Mapping[1].Protocol = IPPROTO_UDP;
Provider->Mapping->Mapping[1].SocketType = SOCK_STREAM;
Provider->Mapping->Mapping[1].Protocol = IPPROTO_TCP;
Provider->Mapping->Mapping[2].AddressFamily = AF_INET;
Provider->Mapping->Mapping[2].SocketType = SOCK_RAW;
Provider->Mapping->Mapping[2].SocketType = SOCK_DGRAM;
Provider->Mapping->Mapping[2].Protocol = 0;
Provider->Mapping->Mapping[3].AddressFamily = AF_INET;
Provider->Mapping->Mapping[3].SocketType = SOCK_DGRAM;
Provider->Mapping->Mapping[3].Protocol = IPPROTO_UDP;
Provider->Mapping->Mapping[4].AddressFamily = AF_INET;
Provider->Mapping->Mapping[4].SocketType = SOCK_RAW;
Provider->Mapping->Mapping[4].Protocol = 0;
#endif
}

View file

@ -25,6 +25,7 @@ VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
HANDLE GlobalHeap;
BOOL Initialized = FALSE; /* TRUE if WSAStartup() has been successfully called */
WSPUPCALLTABLE UpcallTable;
@ -198,6 +199,8 @@ WSASocketW(
af, type, protocol));
if (!WSAINITIALIZED) {
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d) = WSANOTINITIALISED.\n",
af, type, protocol));
WSASetLastError(WSANOTINITIALISED);
return INVALID_SOCKET;
}
@ -213,12 +216,16 @@ WSASocketW(
Provider = LocateProvider(lpProtocolInfo);
if (!Provider) {
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d) = WSAEAFNOSUPPORT.\n",
af, type, protocol));
WSASetLastError(WSAEAFNOSUPPORT);
return INVALID_SOCKET;
}
Status = LoadProvider(Provider, lpProtocolInfo);
if (Status != NO_ERROR) {
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d) = %d.\n",
af, type, protocol, Status));
WSASetLastError(Status);
return INVALID_SOCKET;
}
@ -590,7 +597,6 @@ DllMain(HANDLE hInstDll,
}
p->LastErrorValue = NO_ERROR;
p->Initialized = FALSE;
NtCurrentTeb()->WinSockData = p;
break;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: kdb.c,v 1.13 2003/12/23 05:04:58 arty Exp $
/* $Id: kdb.c,v 1.14 2003/12/25 14:06:15 chorns Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb.c
@ -28,6 +28,7 @@
/* INCLUDES ******************************************************************/
#include <ctype.h>
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ps.h>

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: message.c,v 1.40 2003/12/24 10:23:13 navaraf Exp $
/* $Id: message.c,v 1.41 2003/12/25 14:06:15 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -105,7 +105,7 @@ NtUserDispatchMessage(CONST MSG* UnsafeMsg)
if(WindowObject->OwnerThread != PsGetCurrentThread())
{
IntReleaseWindowObject(WindowObject);
DPRINT1("Window doesn't belong to the calling thread!\n");
DPRINT("Window doesn't belong to the calling thread!\n");
return 0;
}
/* FIXME: Call hook procedures. */