mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
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:
parent
9aa489b9bf
commit
08ba5babf3
29 changed files with 1191 additions and 96 deletions
|
@ -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.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* REVISIONS:
|
||||
* CSH 01/09/2000 Created
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <socket.h>
|
||||
#include <iterator.h>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
|
||||
void ReportErrorStr(LPTSTR lpsText)
|
||||
{
|
||||
wprintf((__wchar_t*)lpsText);
|
||||
wprintf((wchar_t*)lpsText);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in a new issue