mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
More work on winsock stack (ping is now working)
svn path=/trunk/; revision=1971
This commit is contained in:
parent
ae87e6af46
commit
a3ba68ae58
16 changed files with 606 additions and 392 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: ping.c,v 1.4 2001/05/01 23:08:17 chorns Exp $
|
||||
/* $Id: ping.c,v 1.5 2001/06/15 17:48:43 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS ping utility
|
||||
|
@ -15,6 +15,8 @@
|
|||
#include <stdio.h>
|
||||
#ifndef _MSC_VER
|
||||
|
||||
//#define DBG
|
||||
|
||||
/* FIXME: Where should this be? */
|
||||
#define CopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length);
|
||||
|
||||
|
@ -99,6 +101,25 @@ LARGE_INTEGER TicksPerUs; /* Ticks per microsecond */
|
|||
BOOL UsePerformanceCounter;
|
||||
|
||||
|
||||
/* Display the contents of a buffer */
|
||||
VOID DisplayBuffer(
|
||||
PVOID Buffer,
|
||||
DWORD Size)
|
||||
{
|
||||
UINT i;
|
||||
PCHAR p;
|
||||
|
||||
printf("Buffer (0x%X) Size (0x%X).\n", Buffer, Size);
|
||||
|
||||
p = (PCHAR)Buffer;
|
||||
for (i = 0; i < Size; i++) {
|
||||
if (i % 16 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("%02X ", (p[i]) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display usage information on screen */
|
||||
VOID Usage(VOID)
|
||||
{
|
||||
|
@ -189,7 +210,7 @@ BOOL ParseCmdline(int argc, char* argv[])
|
|||
INT i;
|
||||
BOOL ShowUsage;
|
||||
BOOL FoundTarget;
|
||||
#if 0
|
||||
#if 1
|
||||
lstrcpy(TargetName, "127.0.0.1");
|
||||
PingCount = 1;
|
||||
return TRUE;
|
||||
|
@ -388,7 +409,7 @@ BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
|
|||
{
|
||||
PIPv4_HEADER IpHeader;
|
||||
PICMP_ECHO_PACKET Icmp;
|
||||
UINT IphLength;
|
||||
UINT IphLength;
|
||||
CHAR Time[100];
|
||||
LARGE_INTEGER RelativeTime;
|
||||
LARGE_INTEGER LargeTime;
|
||||
|
@ -397,16 +418,28 @@ BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
|
|||
|
||||
IphLength = IpHeader->IHL * 4;
|
||||
|
||||
if (size < IphLength + ICMP_MINSIZE)
|
||||
if (size < IphLength + ICMP_MINSIZE) {
|
||||
#ifdef DBG
|
||||
printf("Bad size (0x%X < 0x%X)\n", size, IphLength + ICMP_MINSIZE);
|
||||
#endif DBG
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Icmp = (PICMP_ECHO_PACKET)(buffer + IphLength);
|
||||
|
||||
if (Icmp->Icmp.Type != ICMPMSG_ECHOREPLY)
|
||||
if (Icmp->Icmp.Type != ICMPMSG_ECHOREPLY) {
|
||||
#ifdef DBG
|
||||
printf("Bad ICMP type (0x%X should be 0x%X)\n", Icmp->Icmp.Type, ICMPMSG_ECHOREPLY);
|
||||
#endif DBG
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Icmp->Icmp.Id != (USHORT)GetCurrentProcessId())
|
||||
if (Icmp->Icmp.Id != (USHORT)GetCurrentProcessId()) {
|
||||
#ifdef DBG
|
||||
printf("Bad ICMP id (0x%X should be 0x%X)\n", Icmp->Icmp.Id, (USHORT)GetCurrentProcessId());
|
||||
#endif DBG
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
QueryTime(&LargeTime);
|
||||
|
||||
|
@ -415,14 +448,14 @@ BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
|
|||
TimeToMsString(Time, RelativeTime);
|
||||
|
||||
printf("Reply from %s: bytes=%d time=%s TTL=%d\n", inet_ntoa(from->sin_addr),
|
||||
size - IphLength - sizeof(ICMP_ECHO_PACKET) , Time, IpHeader->TTL);
|
||||
size - IphLength - sizeof(ICMP_ECHO_PACKET), Time, IpHeader->TTL);
|
||||
if (RelativeTime.QuadPart < MinRTT.QuadPart) {
|
||||
MinRTT.QuadPart = RelativeTime.QuadPart;
|
||||
MinRTTSet = TRUE;
|
||||
MinRTT.QuadPart = RelativeTime.QuadPart;
|
||||
MinRTTSet = TRUE;
|
||||
}
|
||||
if (RelativeTime.QuadPart > MaxRTT.QuadPart)
|
||||
MaxRTT.QuadPart = RelativeTime.QuadPart;
|
||||
SumRTT.QuadPart += RelativeTime.QuadPart;
|
||||
if (RelativeTime.QuadPart > MaxRTT.QuadPart)
|
||||
MaxRTT.QuadPart = RelativeTime.QuadPart;
|
||||
SumRTT.QuadPart += RelativeTime.QuadPart;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -472,10 +505,17 @@ BOOL Ping(VOID)
|
|||
Timeval.tv_usec = Timeout % 1000;
|
||||
Status = select(0, NULL, &Fds, NULL, &Timeval);
|
||||
if ((Status != SOCKET_ERROR) && (Status != 0)) {
|
||||
|
||||
#ifdef DBG
|
||||
printf("Sending packet\n");
|
||||
DisplayBuffer(Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize);
|
||||
printf("\n");
|
||||
#endif DBG
|
||||
|
||||
Status = sendto(IcmpSock, Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize,
|
||||
0, (SOCKADDR*)&Target, sizeof(Target));
|
||||
SentCount++;
|
||||
}
|
||||
SentCount++;
|
||||
if (Status == SOCKET_ERROR) {
|
||||
if (WSAGetLastError() == WSAEHOSTUNREACH) {
|
||||
printf("Destination host unreachable.\n");
|
||||
|
@ -496,6 +536,12 @@ BOOL Ping(VOID)
|
|||
if ((Status != SOCKET_ERROR) && (Status != 0)) {
|
||||
Length = sizeof(From);
|
||||
Status = recvfrom(IcmpSock, Buffer, Size, 0, &From, &Length);
|
||||
|
||||
#ifdef DBG
|
||||
printf("Received packet\n");
|
||||
DisplayBuffer(Buffer, Status);
|
||||
printf("\n");
|
||||
#endif DBG
|
||||
}
|
||||
if (Status == SOCKET_ERROR) {
|
||||
if (WSAGetLastError() != WSAETIMEDOUT) {
|
||||
|
@ -515,7 +561,7 @@ BOOL Ping(VOID)
|
|||
|
||||
if (!DecodeResponse(Buffer, Status, (PSOCKADDR_IN)&From)) {
|
||||
/* FIXME: Wait again as it could be another ICMP message type */
|
||||
printf("Request timed out.\n");
|
||||
printf("Request timed out (incomplete datagram received).\n");
|
||||
LostCount++;
|
||||
}
|
||||
|
||||
|
@ -563,7 +609,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
if (!MinRTTSet)
|
||||
MinRTT.QuadPart = 0;
|
||||
MinRTT = MaxRTT;
|
||||
|
||||
TimeToMsString(MinTime, MinRTT);
|
||||
TimeToMsString(MaxTime, MaxRTT);
|
||||
|
|
|
@ -19,6 +19,7 @@ DWORD DebugTraceLevel = MIN_TRACE;
|
|||
|
||||
|
||||
NPAGED_LOOKASIDE_LIST BufferLookasideList;
|
||||
NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
|
||||
|
||||
|
||||
NTSTATUS
|
||||
|
@ -169,6 +170,16 @@ DriverEntry(
|
|||
TAG('A', 'F', 'D', 'B'),
|
||||
0);*/
|
||||
|
||||
/* ExInitializeNPagedLookasideList(
|
||||
&ReadRequestLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(AFD_READ_REQUEST),
|
||||
TAG('A', 'F', 'D', 'R'),
|
||||
0);*/
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,46 +21,46 @@ NTSTATUS AfdDispBind(
|
|||
* Status of operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_BIND Request;
|
||||
PFILE_REPLY_BIND Reply;
|
||||
PAFDFCB FCB;
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_BIND Request;
|
||||
PFILE_REPLY_BIND Reply;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_BIND)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_BIND))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_BIND)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_BIND))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
|
||||
Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
switch (Request->Name.sa_family) {
|
||||
case AF_INET:
|
||||
Status = TdiOpenAddressFileIPv4(&FCB->TdiDeviceName,
|
||||
&Request->Name,
|
||||
&FCB->TdiAddressObjectHandle,
|
||||
&FCB->TdiAddressObject);
|
||||
break;
|
||||
default:
|
||||
AFD_DbgPrint(MIN_TRACE, ("Bad address family (%d).\n", Request->Name.sa_family));
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
switch (Request->Name.sa_family) {
|
||||
case AF_INET:
|
||||
Status = TdiOpenAddressFileIPv4(&FCB->TdiDeviceName,
|
||||
&Request->Name,
|
||||
&FCB->TdiAddressObjectHandle,
|
||||
&FCB->TdiAddressObject);
|
||||
break;
|
||||
default:
|
||||
AFD_DbgPrint(MIN_TRACE, ("Bad address family (%d).\n", Request->Name.sa_family));
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status)) {
|
||||
AfdRegisterEventHandlers(FCB);
|
||||
FCB->State = SOCKET_STATE_BOUND;
|
||||
}
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
if (NT_SUCCESS(Status)) {
|
||||
AfdRegisterEventHandlers(FCB);
|
||||
FCB->State = SOCKET_STATE_BOUND;
|
||||
}
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,29 +76,29 @@ NTSTATUS AfdDispListen(
|
|||
* Status of operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_LISTEN Request;
|
||||
PFILE_REPLY_LISTEN Reply;
|
||||
PAFDFCB FCB;
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_LISTEN Request;
|
||||
PFILE_REPLY_LISTEN Reply;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,146 +114,146 @@ NTSTATUS AfdDispSendTo(
|
|||
* Status of operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_SENDTO Request;
|
||||
PFILE_REPLY_SENDTO Reply;
|
||||
PAFDFCB FCB;
|
||||
PVOID SystemVirtualAddress;
|
||||
PVOID DataBufferAddress;
|
||||
ULONG BufferSize;
|
||||
ULONG BytesCopied;
|
||||
PMDL Mdl;
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_SENDTO Request;
|
||||
PFILE_REPLY_SENDTO Reply;
|
||||
PAFDFCB FCB;
|
||||
PVOID SystemVirtualAddress;
|
||||
PVOID DataBufferAddress;
|
||||
ULONG BufferSize;
|
||||
ULONG BytesCopied;
|
||||
PMDL Mdl;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_SENDTO)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_SENDTO))) {
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_SENDTO)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_SENDTO))) {
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("FileObject at (0x%X).\n", IrpSp->FileObject));
|
||||
AFD_DbgPrint(MAX_TRACE, ("FCB at (0x%X).\n", IrpSp->FileObject->FsContext));
|
||||
AFD_DbgPrint(MAX_TRACE, ("CCB at (0x%X).\n", IrpSp->FileObject->FsContext2));
|
||||
AFD_DbgPrint(MAX_TRACE, ("FileObject at (0x%X).\n", IrpSp->FileObject));
|
||||
AFD_DbgPrint(MAX_TRACE, ("FCB at (0x%X).\n", IrpSp->FileObject->FsContext));
|
||||
AFD_DbgPrint(MAX_TRACE, ("CCB at (0x%X).\n", IrpSp->FileObject->FsContext2));
|
||||
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
|
||||
BufferSize = WSABufferSize(Request->Buffers, Request->BufferCount);
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
|
||||
BufferSize = WSABufferSize(Request->Buffers, Request->BufferCount);
|
||||
|
||||
|
||||
/* FIXME: Should we handle special cases here? */
|
||||
if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
|
||||
BufferSize += sizeof(IPv4_HEADER);
|
||||
}
|
||||
|
||||
|
||||
if (BufferSize != 0) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Allocating %d bytes for send buffer.\n", BufferSize));
|
||||
SystemVirtualAddress = ExAllocatePool(NonPagedPool, BufferSize);
|
||||
if (!SystemVirtualAddress) {
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* FIXME: Should we handle special cases here? */
|
||||
if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
|
||||
DataBufferAddress = SystemVirtualAddress + sizeof(IPv4_HEADER);
|
||||
|
||||
/* FIXME: Should TCP/IP driver assign source address for raw sockets? */
|
||||
((PSOCKADDR_IN)&FCB->SocketName)->sin_addr.S_un.S_addr = 0x0100007F;
|
||||
|
||||
BuildIPv4Header(
|
||||
(PIPv4_HEADER)SystemVirtualAddress,
|
||||
BufferSize,
|
||||
FCB->Protocol,
|
||||
&FCB->SocketName,
|
||||
&Request->To);
|
||||
} else {
|
||||
DataBufferAddress = SystemVirtualAddress;
|
||||
}
|
||||
|
||||
Status = MergeWSABuffers(
|
||||
Request->Buffers,
|
||||
Request->BufferCount,
|
||||
DataBufferAddress,
|
||||
BufferSize,
|
||||
&BytesCopied);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
SystemVirtualAddress = NULL;
|
||||
BytesCopied = 0;
|
||||
}
|
||||
|
||||
Mdl = IoAllocateMdl(
|
||||
SystemVirtualAddress, /* Virtual address of buffer */
|
||||
BufferSize, /* Length of buffer */
|
||||
FALSE, /* Not secondary */
|
||||
FALSE, /* Don't charge quota */
|
||||
NULL); /* Don't use IRP */
|
||||
if (!Mdl) {
|
||||
ExFreePool(SystemVirtualAddress);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
MmBuildMdlForNonPagedPool(Mdl);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("System virtual address is (0x%X).\n", SystemVirtualAddress));
|
||||
AFD_DbgPrint(MAX_TRACE, ("MDL for data buffer is at (0x%X).\n", Mdl));
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl->MdlFlags));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", Mdl->Next));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", Mdl->Size));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl->MappedSystemVa));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", Mdl->StartVa));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl->ByteCount));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl->ByteOffset));
|
||||
|
||||
#if 0
|
||||
#ifdef _MSC_VER
|
||||
try {
|
||||
#endif
|
||||
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
|
||||
#ifdef _MSC_VER
|
||||
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||
IoFreeMdl(Mdl);
|
||||
if (BufferSize != 0) {
|
||||
ExFreePool(SystemVirtualAddress);
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
/* FIXME: Should we handle special cases here? */
|
||||
if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
|
||||
BufferSize += sizeof(IPv4_HEADER);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Status = TdiSendDatagram(FCB->TdiAddressObject,
|
||||
&Request->To,
|
||||
Mdl,
|
||||
BufferSize);
|
||||
|
||||
/* FIXME: Assumes synchronous operation */
|
||||
if (BufferSize != 0) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Allocating %d bytes for send buffer.\n", BufferSize));
|
||||
SystemVirtualAddress = ExAllocatePool(NonPagedPool, BufferSize);
|
||||
if (!SystemVirtualAddress) {
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* FIXME: Should we handle special cases here? */
|
||||
if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
|
||||
DataBufferAddress = SystemVirtualAddress + sizeof(IPv4_HEADER);
|
||||
|
||||
/* FIXME: Should TCP/IP driver assign source address for raw sockets? */
|
||||
((PSOCKADDR_IN)&FCB->SocketName)->sin_addr.S_un.S_addr = 0x0100007F;
|
||||
|
||||
BuildIPv4Header(
|
||||
(PIPv4_HEADER)SystemVirtualAddress,
|
||||
BufferSize,
|
||||
FCB->Protocol,
|
||||
&FCB->SocketName,
|
||||
&Request->To);
|
||||
} else {
|
||||
DataBufferAddress = SystemVirtualAddress;
|
||||
}
|
||||
|
||||
Status = MergeWSABuffers(
|
||||
Request->Buffers,
|
||||
Request->BufferCount,
|
||||
DataBufferAddress,
|
||||
BufferSize,
|
||||
&BytesCopied);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
SystemVirtualAddress = NULL;
|
||||
BytesCopied = 0;
|
||||
}
|
||||
|
||||
Mdl = IoAllocateMdl(
|
||||
SystemVirtualAddress, /* Virtual address of buffer */
|
||||
BufferSize, /* Length of buffer */
|
||||
FALSE, /* Not secondary */
|
||||
FALSE, /* Don't charge quota */
|
||||
NULL); /* Don't use IRP */
|
||||
if (!Mdl) {
|
||||
ExFreePool(SystemVirtualAddress);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
MmBuildMdlForNonPagedPool(Mdl);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("System virtual address is (0x%X).\n", SystemVirtualAddress));
|
||||
AFD_DbgPrint(MAX_TRACE, ("MDL for data buffer is at (0x%X).\n", Mdl));
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl->MdlFlags));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", Mdl->Next));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", Mdl->Size));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl->MappedSystemVa));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", Mdl->StartVa));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl->ByteCount));
|
||||
AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl->ByteOffset));
|
||||
|
||||
#if 0
|
||||
MmUnlockPages(Mdl);
|
||||
#ifdef _MSC_VER
|
||||
try {
|
||||
#endif
|
||||
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
|
||||
#ifdef _MSC_VER
|
||||
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||
IoFreeMdl(Mdl);
|
||||
if (BufferSize != 0) {
|
||||
ExFreePool(SystemVirtualAddress);
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
IoFreeMdl(Mdl);
|
||||
Status = TdiSendDatagram(FCB->TdiAddressObject,
|
||||
&Request->To,
|
||||
Mdl,
|
||||
BufferSize);
|
||||
|
||||
if (BufferSize != 0) {
|
||||
ExFreePool(SystemVirtualAddress);
|
||||
}
|
||||
/* FIXME: Assumes synchronous operation */
|
||||
#if 0
|
||||
MmUnlockPages(Mdl);
|
||||
#endif
|
||||
|
||||
Reply->NumberOfBytesSent = BufferSize;
|
||||
Reply->Status = NO_ERROR;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
IoFreeMdl(Mdl);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
if (BufferSize != 0) {
|
||||
ExFreePool(SystemVirtualAddress);
|
||||
}
|
||||
|
||||
return Status;
|
||||
Reply->NumberOfBytesSent = BufferSize;
|
||||
Reply->Status = NO_ERROR;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -269,57 +269,139 @@ NTSTATUS AfdDispRecvFrom(
|
|||
* Status of operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_RECVFROM Request;
|
||||
PFILE_REPLY_RECVFROM Reply;
|
||||
PAFD_READ_REQUEST ReadRequest;
|
||||
KIRQL OldIrql;
|
||||
PAFDFCB FCB;
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_RECVFROM Request;
|
||||
PFILE_REPLY_RECVFROM Reply;
|
||||
PAFD_READ_REQUEST ReadRequest;
|
||||
DWORD NumberOfBytesRecvd;
|
||||
KIRQL OldIrql;
|
||||
PAFDFCB FCB;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_RECVFROM)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_RECVFROM))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_RECVFROM)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_RECVFROM))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
|
||||
Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
KeAcquireSpinLock(&FCB->ReadRequestQueueLock, &OldIrql);
|
||||
KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
|
||||
if (IsListEmpty(&FCB->ReceiveQueue)) {
|
||||
KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
|
||||
|
||||
if (IsListEmpty(&FCB->ReadRequestQueue)) {
|
||||
/* Queue request and return STATUS_PENDING */
|
||||
ReadRequest->Irp = Irp;
|
||||
ReadRequest->RecvFromRequest = Request;
|
||||
ReadRequest->RecvFromReply = Reply;
|
||||
InsertTailList(&FCB->ReadRequestQueue, &ReadRequest->ListEntry);
|
||||
KeReleaseSpinLock(&FCB->ReadRequestQueueLock, OldIrql);
|
||||
Status = STATUS_PENDING;
|
||||
} else {
|
||||
/* Satisfy the request at once */
|
||||
Status = FillWSABuffers(
|
||||
FCB,
|
||||
Request->Buffers,
|
||||
Request->BufferCount,
|
||||
&Reply->NumberOfBytesRecvd);
|
||||
KeReleaseSpinLock(&FCB->ReadRequestQueueLock, OldIrql);
|
||||
Reply->Status = NO_ERROR;
|
||||
}
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
/* Queue a read request and return STATUS_PENDING */
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Queueing read request.\n"));
|
||||
|
||||
return Status;
|
||||
/*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
|
||||
&ReadRequestLookasideList);*/
|
||||
ReadRequest = (PAFD_READ_REQUEST)ExAllocatePool(
|
||||
NonPagedPool,
|
||||
sizeof(AFD_READ_REQUEST));
|
||||
if (ReadRequest) {
|
||||
ReadRequest->Irp = Irp;
|
||||
ReadRequest->RecvFromRequest = Request;
|
||||
ReadRequest->RecvFromReply = Reply;
|
||||
|
||||
ExInterlockedInsertTailList(
|
||||
&FCB->ReadRequestQueue,
|
||||
&ReadRequest->ListEntry,
|
||||
&FCB->ReadRequestQueueLock);
|
||||
Status = STATUS_PENDING;
|
||||
} else {
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
} else {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
|
||||
|
||||
/* Satisfy the request at once */
|
||||
Status = FillWSABuffers(
|
||||
FCB,
|
||||
Request->Buffers,
|
||||
Request->BufferCount,
|
||||
&NumberOfBytesRecvd);
|
||||
KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
|
||||
Reply->Status = NO_ERROR;
|
||||
Reply->NumberOfBytesRecvd = NumberOfBytesRecvd;
|
||||
AFD_DbgPrint(MAX_TRACE, ("NumberOfBytesRecvd (0x%X).\n",
|
||||
NumberOfBytesRecvd));
|
||||
}
|
||||
} else {
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
typedef enum {
|
||||
soRead,
|
||||
soWrite,
|
||||
soExcept
|
||||
} SelectOperation;
|
||||
|
||||
|
||||
DWORD AfdDispSelectEx(
|
||||
LPFD_SET FDSet,
|
||||
SelectOperation Operation)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PAFDFCB Current;
|
||||
KIRQL OldIrql;
|
||||
DWORD Count;
|
||||
ULONG i;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("FDSet (0x%X) Operation (0x%X).\n",
|
||||
FDSet, Operation));
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("FDSet->fd_count (0x%X).\n", FDSet->fd_count));
|
||||
|
||||
Count = 0;
|
||||
for (i = 0; i < FDSet->fd_count; i++) {
|
||||
Status = ObReferenceObjectByHandle(
|
||||
(HANDLE)FDSet->fd_array[i],
|
||||
0,
|
||||
IoFileObjectType,
|
||||
KernelMode,
|
||||
(PVOID*)&Current,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
|
||||
switch (Operation) {
|
||||
case soRead:
|
||||
KeAcquireSpinLock(&Current->ReceiveQueueLock, &OldIrql);
|
||||
if (!IsListEmpty(&Current->ReceiveQueue)) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Socket is readable.\n"));
|
||||
Count++;
|
||||
}
|
||||
KeReleaseSpinLock(&Current->ReceiveQueueLock, OldIrql);
|
||||
break;
|
||||
case soWrite:
|
||||
/* FIXME: How can we check for writability? */
|
||||
Count++;
|
||||
break;
|
||||
case soExcept:
|
||||
/* FIXME: What is this? */
|
||||
Count++;
|
||||
break;
|
||||
}
|
||||
|
||||
ObDereferenceObject(Current);
|
||||
}
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
NTSTATUS AfdDispSelect(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
|
@ -332,29 +414,53 @@ NTSTATUS AfdDispSelect(
|
|||
* Status of operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_SELECT Request;
|
||||
PFILE_REPLY_SELECT Reply;
|
||||
PAFDFCB FCB;
|
||||
NTSTATUS Status;
|
||||
UINT InputBufferLength;
|
||||
UINT OutputBufferLength;
|
||||
PFILE_REQUEST_SELECT Request;
|
||||
PFILE_REPLY_SELECT Reply;
|
||||
DWORD SocketCount;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_SELECT)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_SELECT))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_SELECT)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_SELECT))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_SELECT)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_SELECT)Irp->AssociatedIrp.SystemBuffer;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
Request = (PFILE_REQUEST_SELECT)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_SELECT)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
AFD_DbgPrint(MAX_TRACE, ("R (0x%X) W (0x%X).\n",
|
||||
Request->ReadFDSet, Request->WriteFDSet));
|
||||
|
||||
return Status;
|
||||
SocketCount = 0;
|
||||
|
||||
if (Request->ReadFDSet) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Read.\n"));
|
||||
SocketCount += AfdDispSelectEx(Request->ReadFDSet, soRead);
|
||||
}
|
||||
if (Request->WriteFDSet) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Write.\n"));
|
||||
SocketCount += AfdDispSelectEx(Request->WriteFDSet, soWrite);
|
||||
}
|
||||
if (Request->ExceptFDSet) {
|
||||
SocketCount += AfdDispSelectEx(Request->ExceptFDSet, soExcept);
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Sockets selected (0x%X).\n", SocketCount));
|
||||
|
||||
Reply->Status = NO_ERROR;
|
||||
Reply->SocketCount = SocketCount;
|
||||
Status = STATUS_SUCCESS;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -120,6 +120,9 @@ NTSTATUS AfdEventReceiveDatagramHandler(
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Copy the data to a local buffer */
|
||||
RtlCopyMemory(ReceiveBuffer, Tsdu, BytesAvailable);
|
||||
|
||||
Buffer->Buffer.len = BytesAvailable;
|
||||
Buffer->Buffer.buf = ReceiveBuffer;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ PAFDFCB AfdInitializeFCB(
|
|||
KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock);
|
||||
|
||||
if (FileObject)
|
||||
FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB;
|
||||
FileObject->FsContext = (PVOID)NewFCB;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
|
||||
|
||||
|
|
|
@ -8,72 +8,76 @@
|
|||
* CSH 01/02-2001 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
ULONG WSABufferSize(
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount)
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount)
|
||||
{
|
||||
ULONG i;
|
||||
LPWSABUF p;
|
||||
ULONG Count = 0;
|
||||
ULONG i;
|
||||
LPWSABUF p;
|
||||
ULONG Count = 0;
|
||||
|
||||
p = Buffers;
|
||||
for (i = 0; i < BufferCount; i++) {
|
||||
Count += p->len;
|
||||
p++;
|
||||
}
|
||||
p = Buffers;
|
||||
for (i = 0; i < BufferCount; i++) {
|
||||
Count += p->len;
|
||||
p++;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
|
||||
|
||||
return Count;
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS MergeWSABuffers(
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount,
|
||||
PVOID Destination,
|
||||
ULONG MaxLength,
|
||||
PULONG BytesCopied)
|
||||
LPWSABUF Buffers,
|
||||
DWORD BufferCount,
|
||||
PVOID Destination,
|
||||
ULONG MaxLength,
|
||||
PULONG BytesCopied)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG Length;
|
||||
LPWSABUF p;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
ULONG Length;
|
||||
LPWSABUF p;
|
||||
ULONG i;
|
||||
|
||||
*BytesCopied = 0;
|
||||
if (BufferCount == 0)
|
||||
return STATUS_SUCCESS;
|
||||
*BytesCopied = 0;
|
||||
if (BufferCount == 0)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
p = Buffers;
|
||||
p = Buffers;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
|
||||
AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
|
||||
|
||||
for (i = 0; i < BufferCount; i++) {
|
||||
Length = p->len;
|
||||
if (Length > MaxLength)
|
||||
/* Don't copy out of bounds */
|
||||
Length = MaxLength;
|
||||
|
||||
RtlCopyMemory(Destination, p->buf, Length);
|
||||
Destination += Length;
|
||||
AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
|
||||
p++;
|
||||
AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
|
||||
|
||||
for (i = 0; i < BufferCount; i++) {
|
||||
Length = p->len;
|
||||
if (Length > MaxLength)
|
||||
/* Don't copy out of bounds */
|
||||
Length = MaxLength;
|
||||
*BytesCopied += Length;
|
||||
|
||||
RtlCopyMemory(Destination, p->buf, Length);
|
||||
Destination += Length;
|
||||
AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
|
||||
p++;
|
||||
AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
|
||||
MaxLength -= Length;
|
||||
if (MaxLength == 0)
|
||||
/* Destination buffer is full */
|
||||
break;
|
||||
}
|
||||
|
||||
*BytesCopied += Length;
|
||||
|
||||
MaxLength -= Length;
|
||||
if (MaxLength == 0)
|
||||
/* Destination buffer is full */
|
||||
break;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTES: ReceiveQueueLock must be acquired for the FCB when called
|
||||
*/
|
||||
NTSTATUS FillWSABuffers(
|
||||
PAFDFCB FCB,
|
||||
LPWSABUF Buffers,
|
||||
|
@ -83,7 +87,7 @@ NTSTATUS FillWSABuffers(
|
|||
NTSTATUS Status;
|
||||
PUCHAR DstData, SrcData;
|
||||
UINT DstSize, SrcSize;
|
||||
UINT Count, Total, Length;
|
||||
UINT Count, Total;
|
||||
PAFD_BUFFER SrcBuffer;
|
||||
PLIST_ENTRY Entry;
|
||||
ULONG Size;
|
||||
|
@ -92,6 +96,11 @@ NTSTATUS FillWSABuffers(
|
|||
if (BufferCount == 0)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
if (IsListEmpty(&FCB->ReceiveQueue))
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Entry = RemoveHeadList(&FCB->ReceiveQueue);
|
||||
SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
|
||||
SrcData = SrcBuffer->Buffer.buf;
|
||||
SrcSize = SrcBuffer->Buffer.len;
|
||||
|
||||
|
@ -101,25 +110,32 @@ NTSTATUS FillWSABuffers(
|
|||
/* Copy the data */
|
||||
for (Total = 0;;) {
|
||||
/* Find out how many bytes we can copy at one time */
|
||||
if (Length < SrcSize)
|
||||
Count = Length;
|
||||
if (DstSize < SrcSize)
|
||||
Count = DstSize;
|
||||
else
|
||||
Count = SrcSize;
|
||||
if (DstSize < Count)
|
||||
Count = DstSize;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcData (0x%X) Count (0x%X).\n",
|
||||
DstData, SrcData, Count));
|
||||
|
||||
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
|
||||
|
||||
Total += Count;
|
||||
Length -= Count;
|
||||
Total += Count;
|
||||
|
||||
SrcSize -= Count;
|
||||
if (SrcSize == 0) {
|
||||
ExFreePool(SrcBuffer->Buffer.buf);
|
||||
ExFreePool(SrcBuffer);
|
||||
|
||||
/* No more bytes in source buffer. Proceed to
|
||||
the next buffer in the source buffer chain */
|
||||
/* No more bytes in source buffer. Proceed to the next buffer
|
||||
in the source buffer chain if there is one */
|
||||
if (IsListEmpty(&FCB->ReceiveQueue)) {
|
||||
SrcBuffer = NULL;
|
||||
SrcData = 0;
|
||||
SrcSize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Entry = RemoveHeadList(&FCB->ReceiveQueue);
|
||||
SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
|
||||
SrcData = SrcBuffer->Buffer.buf;
|
||||
|
@ -137,13 +153,13 @@ NTSTATUS FillWSABuffers(
|
|||
DstData = Buffers->buf;
|
||||
DstSize = Buffers->len;
|
||||
}
|
||||
|
||||
if (Length == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (SrcSize > 0) {
|
||||
InsertHeadList(&FCB->ReceiveQueue, Entry);
|
||||
} else if (SrcBuffer != NULL) {
|
||||
ExFreePool(SrcBuffer->Buffer.buf);
|
||||
ExFreePool(SrcBuffer);
|
||||
}
|
||||
|
||||
*BytesCopied = Total;
|
||||
|
@ -165,61 +181,61 @@ ULONG ChecksumCompute(
|
|||
* Checksum of buffer
|
||||
*/
|
||||
{
|
||||
/* FIXME: This should be done in assembler */
|
||||
/* FIXME: This should be done in assembler */
|
||||
|
||||
register ULONG Sum = Seed;
|
||||
register ULONG Sum = Seed;
|
||||
|
||||
while (Count > 1) {
|
||||
Sum += *(PUSHORT)Data;
|
||||
Count -= 2;
|
||||
(ULONG_PTR)Data += 2;
|
||||
}
|
||||
while (Count > 1) {
|
||||
Sum += *(PUSHORT)Data;
|
||||
Count -= 2;
|
||||
(ULONG_PTR)Data += 2;
|
||||
}
|
||||
|
||||
/* Add left-over byte, if any */
|
||||
if (Count > 0)
|
||||
Sum += *(PUCHAR)Data;
|
||||
/* Add left-over byte, if any */
|
||||
if (Count > 0)
|
||||
Sum += *(PUCHAR)Data;
|
||||
|
||||
/* Fold 32-bit sum to 16 bits */
|
||||
while (Sum >> 16)
|
||||
Sum = (Sum & 0xFFFF) + (Sum >> 16);
|
||||
/* Fold 32-bit sum to 16 bits */
|
||||
while (Sum >> 16)
|
||||
Sum = (Sum & 0xFFFF) + (Sum >> 16);
|
||||
|
||||
return ~Sum;
|
||||
return ~Sum;
|
||||
}
|
||||
|
||||
VOID BuildIPv4Header(
|
||||
PIPv4_HEADER IPHeader,
|
||||
ULONG TotalSize,
|
||||
ULONG Protocol,
|
||||
PSOCKADDR SourceAddress,
|
||||
PSOCKADDR DestinationAddress)
|
||||
PIPv4_HEADER IPHeader,
|
||||
ULONG TotalSize,
|
||||
ULONG Protocol,
|
||||
PSOCKADDR SourceAddress,
|
||||
PSOCKADDR DestinationAddress)
|
||||
{
|
||||
PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
|
||||
PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
|
||||
PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
|
||||
PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
|
||||
|
||||
/* Version = 4, Length = 5 DWORDs */
|
||||
IPHeader->VerIHL = 0x45;
|
||||
/* Normal Type-of-Service */
|
||||
IPHeader->Tos = 0;
|
||||
/* Length of header and data */
|
||||
IPHeader->TotalLength = WH2N((USHORT)TotalSize);
|
||||
/* Identification */
|
||||
IPHeader->Id = 0;
|
||||
/* One fragment at offset 0 */
|
||||
IPHeader->FlagsFragOfs = 0;
|
||||
/* Time-to-Live is 128 */
|
||||
IPHeader->Ttl = 128;
|
||||
/* Protocol number */
|
||||
IPHeader->Protocol = Protocol;
|
||||
/* Checksum is 0 (calculated later) */
|
||||
IPHeader->Checksum = 0;
|
||||
/* Source address */
|
||||
IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
|
||||
/* Destination address */
|
||||
IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
|
||||
/* Version = 4, Length = 5 DWORDs */
|
||||
IPHeader->VerIHL = 0x45;
|
||||
/* Normal Type-of-Service */
|
||||
IPHeader->Tos = 0;
|
||||
/* Length of header and data */
|
||||
IPHeader->TotalLength = WH2N((USHORT)TotalSize);
|
||||
/* Identification */
|
||||
IPHeader->Id = 0;
|
||||
/* One fragment at offset 0 */
|
||||
IPHeader->FlagsFragOfs = 0;
|
||||
/* Time-to-Live is 128 */
|
||||
IPHeader->Ttl = 128;
|
||||
/* Protocol number */
|
||||
IPHeader->Protocol = Protocol;
|
||||
/* Checksum is 0 (calculated later) */
|
||||
IPHeader->Checksum = 0;
|
||||
/* Source address */
|
||||
IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
|
||||
/* Destination address */
|
||||
IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
|
||||
|
||||
/* Calculate checksum of IP header */
|
||||
IPHeader->Checksum = (USHORT)
|
||||
ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
|
||||
/* Calculate checksum of IP header */
|
||||
IPHeader->Checksum = (USHORT)
|
||||
ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -217,6 +217,8 @@ typedef struct IPv4_HEADER {
|
|||
|
||||
|
||||
extern NPAGED_LOOKASIDE_LIST BufferLookasideList;
|
||||
extern NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
|
||||
|
||||
|
||||
/* Prototypes from dispatch.c */
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ extern DWORD DebugTraceLevel;
|
|||
#define ASSERT(x) if (!(x)) { AFD_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
|
||||
#endif /* NASSERT */
|
||||
|
||||
#define ASSERT_KM(x) ASSERT((x) >= 0xC0000000)
|
||||
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
|
||||
|
||||
#else /* DBG */
|
||||
|
@ -60,12 +61,14 @@ extern DWORD DebugTraceLevel;
|
|||
#define AFD_DbgPrint(_t_, _x_)
|
||||
|
||||
#define ASSERT_IRQL(x)
|
||||
#define ASSERTKM(x)
|
||||
#define ASSERT(x)
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
#define assert(x) ASSERT(x)
|
||||
#define assert_km(x) ASSERT_KM(x)
|
||||
#define assert_irql(x) ASSERT_IRQL(x)
|
||||
|
||||
|
||||
|
|
|
@ -197,11 +197,15 @@ VOID ICMPReceive(
|
|||
return;
|
||||
|
||||
/* Copy ICMP header and data into new packet */
|
||||
RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize + sizeof(ICMP_HEADER));
|
||||
RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize + sizeof(ICMP_HEADER));
|
||||
((PICMP_HEADER)NewPacket->Data)->Type = ICMP_TYPE_ECHO_REPLY;
|
||||
((PICMP_HEADER)NewPacket->Data)->Code = 0;
|
||||
((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
|
||||
|
||||
DisplayIPPacket(IPPacket);
|
||||
|
||||
DisplayIPPacket(NewPacket);
|
||||
|
||||
ICMPTransmit(NTE, NewPacket);
|
||||
|
||||
TI_DbgPrint(DEBUG_ICMP, ("Echo reply sent.\n"));
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = MIN_TRACE;
|
||||
//DWORD DebugTraceLevel = MAX_TRACE;
|
||||
//DWORD DebugTraceLevel = MAX_TRACE | DEBUG_ICMP | DEBUG_BUFFER;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
|
|
@ -239,6 +239,7 @@ VOID DGDeliverData(
|
|||
* Address = Remote address the packet came from
|
||||
* IPPacket = Pointer to IP packet to deliver
|
||||
* DataSize = Number of bytes in data area
|
||||
* (incl. IP header for raw IP file objects)
|
||||
* NOTES:
|
||||
* If there is a receive request, then we copy the data to the
|
||||
* buffer supplied by the user and complete the receive request.
|
||||
|
@ -253,11 +254,19 @@ VOID DGDeliverData(
|
|||
PVOID SourceAddress;
|
||||
ULONG BytesTaken;
|
||||
NTSTATUS Status;
|
||||
PVOID DataBuffer;
|
||||
|
||||
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
|
||||
|
||||
if (AddrFile->Protocol == IPPROTO_UDP) {
|
||||
DataBuffer = IPPacket->Data;
|
||||
} else {
|
||||
/* Give client the IP header too if it is a raw IP file object */
|
||||
DataBuffer = IPPacket->Header;
|
||||
}
|
||||
|
||||
if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PDATAGRAM_RECEIVE_REQUEST Current;
|
||||
|
@ -296,7 +305,7 @@ VOID DGDeliverData(
|
|||
/* Copy the data into buffer provided by the user */
|
||||
CopyBufferToBufferChain(Current->Buffer,
|
||||
0,
|
||||
IPPacket->Data,
|
||||
DataBuffer,
|
||||
DataSize);
|
||||
|
||||
/* Complete the receive request */
|
||||
|
@ -332,7 +341,7 @@ VOID DGDeliverData(
|
|||
DataSize,
|
||||
DataSize,
|
||||
&BytesTaken,
|
||||
IPPacket->Data,
|
||||
DataBuffer,
|
||||
NULL);
|
||||
} else {
|
||||
TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
|
||||
|
|
|
@ -364,7 +364,7 @@ WSPSelect(
|
|||
|
||||
AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n",
|
||||
readfds, writefds, exceptfds));
|
||||
|
||||
#if 0
|
||||
/* FIXME: For now, all reads are timed out immediately */
|
||||
if (readfds != NULL) {
|
||||
AFD_DbgPrint(MID_TRACE, ("Timing out read query.\n"));
|
||||
|
@ -378,8 +378,7 @@ WSPSelect(
|
|||
*lpErrno = NO_ERROR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
ReadSize = 0;
|
||||
if ((readfds != NULL) && (readfds->fd_count > 0)) {
|
||||
|
@ -406,26 +405,35 @@ WSPSelect(
|
|||
}
|
||||
|
||||
/* Put FD SETs after request structure */
|
||||
Current = (Request + sizeof(FILE_REQUEST_SELECT));
|
||||
Request->ReadFDSet = (LPFD_SET)Current;
|
||||
Current = (Request + 1);
|
||||
|
||||
if (ReadSize > 0) {
|
||||
Request->ReadFDSet = (LPFD_SET)Current;
|
||||
Current += ReadSize;
|
||||
RtlCopyMemory(Request->ReadFDSet, readfds, ReadSize);
|
||||
} else {
|
||||
Request->ReadFDSet = NULL;
|
||||
}
|
||||
|
||||
Current += ReadSize;
|
||||
|
||||
if (WriteSize > 0) {
|
||||
Request->WriteFDSet = (LPFD_SET)Current;
|
||||
Current += WriteSize;
|
||||
RtlCopyMemory(Request->WriteFDSet, writefds, WriteSize);
|
||||
} else {
|
||||
Request->WriteFDSet = NULL;
|
||||
}
|
||||
|
||||
Current += WriteSize;
|
||||
|
||||
if (ExceptSize > 0) {
|
||||
Request->ExceptFDSet = (LPFD_SET)Current;
|
||||
RtlCopyMemory(Request->ExceptFDSet, exceptfds, ExceptSize);
|
||||
} else {
|
||||
Request->ExceptFDSet = NULL;
|
||||
}
|
||||
|
||||
Status = NtDeviceIoControlFile(CommandChannel,
|
||||
AFD_DbgPrint(MAX_TRACE, ("R1 (0x%X) W1 (0x%X).\n", Request->ReadFDSet, Request->WriteFDSet));
|
||||
|
||||
Status = NtDeviceIoControlFile(
|
||||
CommandChannel,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -441,12 +449,7 @@ WSPSelect(
|
|||
if (Status == STATUS_PENDING) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
|
||||
/* FIXME: Wait only for blocking sockets */
|
||||
if (!NT_SUCCESS(NtWaitForSingleObject(CommandChannel, FALSE, NULL))) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Wait failed.\n"));
|
||||
/* FIXME: What error code should be returned? */
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
Status = NtWaitForSingleObject(CommandChannel, FALSE, NULL);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
@ -455,11 +458,12 @@ WSPSelect(
|
|||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Select successful.\n"));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Select successful. Status (0x%X) Count (0x%X).\n",
|
||||
Reply.Status, Reply.SocketCount));
|
||||
|
||||
*lpErrno = NO_ERROR;
|
||||
*lpErrno = Reply.Status;
|
||||
|
||||
return 0;
|
||||
return Reply.SocketCount;
|
||||
}
|
||||
|
||||
|
||||
|
@ -722,6 +726,8 @@ DllMain(HANDLE hInstDll,
|
|||
break;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("DllMain of msafd.dll (leaving)\n"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,12 +113,7 @@ WSPRecvFrom(
|
|||
if (Status == STATUS_PENDING) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
|
||||
/* FIXME: Wait only for blocking sockets */
|
||||
if (!NT_SUCCESS(NtWaitForSingleObject((HANDLE)s, FALSE, NULL))) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Wait failed.\n"));
|
||||
/* FIXME: What error code should be returned? */
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
@ -127,7 +122,18 @@ WSPRecvFrom(
|
|||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Receive successful.\n"));
|
||||
AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
|
||||
Reply.NumberOfBytesRecvd));
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("lpNumberOfBytesRecvd (0x%X).\n",
|
||||
lpNumberOfBytesRecvd));
|
||||
|
||||
*lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
|
||||
//*lpFlags = 0;
|
||||
((PSOCKADDR_IN)lpFrom)->sin_family = AF_INET;
|
||||
((PSOCKADDR_IN)lpFrom)->sin_port = 0;
|
||||
((PSOCKADDR_IN)lpFrom)->sin_addr.S_un.S_addr = 0x0100007F;
|
||||
*lpFromLen = sizeof(SOCKADDR_IN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -223,12 +229,7 @@ WSPSendTo(
|
|||
if (Status == STATUS_PENDING) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
|
||||
/* FIXME: Wait only for blocking sockets */
|
||||
if (!NT_SUCCESS(NtWaitForSingleObject((HANDLE)s, FALSE, NULL))) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Wait failed.\n"));
|
||||
/* FIXME: What error code should be returned? */
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
|
|
@ -396,6 +396,8 @@ DllMain(HANDLE hInstDll,
|
|||
break;
|
||||
}
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll. Leaving.\n"));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -404,13 +404,16 @@ inet_ntoa(
|
|||
PCHAR p;
|
||||
|
||||
p = ((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Intoa;
|
||||
_itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
|
||||
strcpy(p, b);
|
||||
_itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
|
||||
strcat(p, b);
|
||||
_itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10);
|
||||
strcat(p, b);
|
||||
_itoa(in.S_un.S_addr & 0xFF, b, 10);
|
||||
strcpy(p, b);
|
||||
_itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10);
|
||||
strcat(p, ".");
|
||||
strcat(p, b);
|
||||
_itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
|
||||
strcat(p, ".");
|
||||
strcat(p, b);
|
||||
_itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
|
||||
strcat(p, ".");
|
||||
strcat(p, b);
|
||||
return (CHAR FAR*)p;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,9 @@ recvfrom(
|
|||
WSABuf.len = len;
|
||||
WSABuf.buf = (CHAR FAR*)buf;
|
||||
|
||||
return WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL);
|
||||
WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL);
|
||||
|
||||
return BytesReceived;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue