More work on winsock stack (ping is now working)

svn path=/trunk/; revision=1971
This commit is contained in:
Casper Hornstrup 2001-06-15 17:48:43 +00:00
parent ae87e6af46
commit a3ba68ae58
16 changed files with 606 additions and 392 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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 */

View file

@ -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;

View file

@ -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));

View file

@ -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 */

View file

@ -217,6 +217,8 @@ typedef struct IPv4_HEADER {
extern NPAGED_LOOKASIDE_LIST BufferLookasideList;
extern NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
/* Prototypes from dispatch.c */

View file

@ -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)

View file

@ -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"));

View file

@ -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 */

View file

@ -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"));

View file

@ -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;
}

View file

@ -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)) {

View file

@ -396,6 +396,8 @@ DllMain(HANDLE hInstDll,
break;
}
WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll. Leaving.\n"));
return TRUE;
}

View file

@ -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;
}

View file

@ -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;
}