diff --git a/reactos/apps/utils/net/ping/makefile b/reactos/apps/utils/net/ping/makefile index 26a11a9421d..7b21cc92b9b 100644 --- a/reactos/apps/utils/net/ping/makefile +++ b/reactos/apps/utils/net/ping/makefile @@ -34,5 +34,6 @@ $(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: % $(TARGETNAME).exe: $(OBJECTS) $(LIBS) $(CC) $(OBJECTS) $(LIBS) -o $(TARGETNAME).exe + $(NM) --numeric-sort $(TARGETNAME).exe > $(TARGETNAME).sym include ../../../rules.mak diff --git a/reactos/drivers/net/afd/afd/afd.c b/reactos/drivers/net/afd/afd/afd.c index 464bbf3513b..02c6bb897f7 100644 --- a/reactos/drivers/net/afd/afd/afd.c +++ b/reactos/drivers/net/afd/afd/afd.c @@ -13,10 +13,14 @@ /* See debug.h for debug/trace constants */ DWORD DebugTraceLevel = MIN_TRACE; +//DWORD DebugTraceLevel = DEBUG_ULTRA; #endif /* DBG */ +NPAGED_LOOKASIDE_LIST BufferLookasideList; + + NTSTATUS STDCALL AfdFileSystemControl( @@ -72,6 +76,10 @@ AfdDispatch( Status = AfdDispRecvFrom(Irp, IrpSp); break; + case IOCTL_AFD_SELECT: + Status = AfdDispSelect(Irp, IrpSp); + break; + default: AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%X).\n", IrpSp->Parameters.DeviceIoControl.IoControlCode)); @@ -152,6 +160,15 @@ DriverEntry( DriverObject->DriverUnload = (PDRIVER_UNLOAD)AfdUnload; +/* ExInitializeNPagedLookasideList( + &BufferLookasideList, + NULL, + NULL, + 0, + sizeof(AFD_BUFFER), + TAG('A', 'F', 'D', 'B'), + 0);*/ + return STATUS_SUCCESS; } diff --git a/reactos/drivers/net/afd/afd/dispatch.c b/reactos/drivers/net/afd/afd/dispatch.c index 4d9f90cacee..88d545f3c4c 100644 --- a/reactos/drivers/net/afd/afd/dispatch.c +++ b/reactos/drivers/net/afd/afd/dispatch.c @@ -102,7 +102,6 @@ NTSTATUS AfdDispListen( } - NTSTATUS AfdDispSendTo( PIRP Irp, PIO_STACK_LOCATION IrpSp) @@ -122,6 +121,7 @@ NTSTATUS AfdDispSendTo( PFILE_REPLY_SENDTO Reply; PAFDFCB FCB; PVOID SystemVirtualAddress; + PVOID DataBufferAddress; ULONG BufferSize; ULONG BytesCopied; PMDL Mdl; @@ -142,18 +142,41 @@ NTSTATUS AfdDispSendTo( 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) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); 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, - SystemVirtualAddress, + DataBufferAddress, BufferSize, &BytesCopied); if (!NT_SUCCESS(Status)) { @@ -165,8 +188,6 @@ NTSTATUS AfdDispSendTo( BytesCopied = 0; } - AFD_DbgPrint(MAX_TRACE, ("KeGetCurrentIrql() 1 (%d).\n", KeGetCurrentIrql())); - Mdl = IoAllocateMdl( SystemVirtualAddress, /* Virtual address of buffer */ BufferSize, /* Length of buffer */ @@ -174,19 +195,12 @@ NTSTATUS AfdDispSendTo( FALSE, /* Don't charge quota */ NULL); /* Don't use IRP */ if (!Mdl) { - AFD_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n")); ExFreePool(SystemVirtualAddress); return STATUS_INSUFFICIENT_RESOURCES; } - AFD_DbgPrint(MAX_TRACE, ("KeGetCurrentIrql() 2 (%d).\n", KeGetCurrentIrql())); - - AFD_DbgPrint(MIN_TRACE, ("NDIS data buffer MdlFlags 1 is (0x%X).\n", Mdl->MdlFlags)); - MmBuildMdlForNonPagedPool(Mdl); - AFD_DbgPrint(MAX_TRACE, ("KeGetCurrentIrql() 3 (%d).\n", KeGetCurrentIrql())); - 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)); @@ -216,13 +230,10 @@ NTSTATUS AfdDispSendTo( #endif #endif - DisplayBuffer(SystemVirtualAddress, BufferSize); - - Status = STATUS_SUCCESS; -/* Status = TdiSendDatagram(FCB->TdiAddressObject, + Status = TdiSendDatagram(FCB->TdiAddressObject, &Request->To, Mdl, - BufferSize);*/ + BufferSize); /* FIXME: Assumes synchronous operation */ #if 0 @@ -231,16 +242,12 @@ NTSTATUS AfdDispSendTo( IoFreeMdl(Mdl); - AFD_DbgPrint(MAX_TRACE, ("KeGetCurrentIrql() 4 (%d).\n", KeGetCurrentIrql())); - if (BufferSize != 0) { ExFreePool(SystemVirtualAddress); } - AFD_DbgPrint(MAX_TRACE, ("KeGetCurrentIrql() 5 (%d).\n", KeGetCurrentIrql())); - Reply->NumberOfBytesSent = BufferSize; - Reply->Status = Status; + Reply->Status = NO_ERROR; } else Status = STATUS_INVALID_PARAMETER; @@ -267,8 +274,12 @@ NTSTATUS AfdDispRecvFrom( UINT OutputBufferLength; PFILE_REQUEST_RECVFROM Request; PFILE_REPLY_RECVFROM Reply; + PAFD_READ_REQUEST ReadRequest; + KIRQL OldIrql; PAFDFCB FCB; + AFD_DbgPrint(MAX_TRACE, ("Called.\n")); + InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; @@ -279,6 +290,65 @@ NTSTATUS AfdDispRecvFrom( Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer; Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer; + + KeAcquireSpinLock(&FCB->ReadRequestQueueLock, &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; + + AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status)); + + return Status; +} + + +NTSTATUS AfdDispSelect( + PIRP Irp, + PIO_STACK_LOCATION IrpSp) +/* + * FUNCTION: Checks if sockets have data in the receive buffers + * ARGUMENTS: + * Irp = Pointer to I/O request packet + * IrpSp = Pointer to current stack location of Irp + * RETURNS: + * Status of operation + */ +{ + NTSTATUS Status; + UINT InputBufferLength; + UINT OutputBufferLength; + PFILE_REQUEST_SELECT Request; + PFILE_REPLY_SELECT Reply; + PAFDFCB FCB; + + 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; + + Request = (PFILE_REQUEST_SELECT)Irp->AssociatedIrp.SystemBuffer; + Reply = (PFILE_REPLY_SELECT)Irp->AssociatedIrp.SystemBuffer; } else Status = STATUS_INVALID_PARAMETER; diff --git a/reactos/drivers/net/afd/afd/event.c b/reactos/drivers/net/afd/afd/event.c index fe0ee8c5e2f..f1743bc3cc6 100644 --- a/reactos/drivers/net/afd/afd/event.c +++ b/reactos/drivers/net/afd/afd/event.c @@ -82,24 +82,77 @@ NTSTATUS ClientEventChainedReceive( NTSTATUS AfdEventReceiveDatagramHandler( - IN PVOID TdiEventContext, - IN LONG SourceAddressLength, - IN PVOID SourceAddress, - IN LONG OptionsLength, - IN PVOID Options, - IN ULONG ReceiveDatagramFlags, - IN ULONG BytesIndicated, - IN ULONG BytesAvailable, - OUT ULONG *BytesTaken, - IN PVOID Tsdu, - OUT PIRP *IoRequestPacket) + IN PVOID TdiEventContext, + IN LONG SourceAddressLength, + IN PVOID SourceAddress, + IN LONG OptionsLength, + IN PVOID Options, + IN ULONG ReceiveDatagramFlags, + IN ULONG BytesIndicated, + IN ULONG BytesAvailable, + OUT ULONG *BytesTaken, + IN PVOID Tsdu, + OUT PIRP *IoRequestPacket) { - AFD_DbgPrint(MAX_TRACE, ("Called.\n")); + PAFDFCB FCB = (PAFDFCB)TdiEventContext; + PAFD_READ_REQUEST ReadRequest; + PVOID ReceiveBuffer; + PAFD_BUFFER Buffer; + PLIST_ENTRY Entry; + NTSTATUS Status; + KIRQL OldIrql; - AFD_DbgPrint(MID_TRACE, ("Receiving (%d) bytes from (0x%X).\n", - BytesAvailable, *(PULONG)SourceAddress)); + AFD_DbgPrint(MAX_TRACE, ("Called.\n")); - return STATUS_SUCCESS; + AFD_DbgPrint(MID_TRACE, ("Receiving (%d) bytes from (0x%X).\n", + BytesAvailable, *(PULONG)SourceAddress)); + + ReceiveBuffer = ExAllocatePool(NonPagedPool, BytesAvailable); + if (!ReceiveBuffer) { + return STATUS_INSUFFICIENT_RESOURCES; + } + + /*Buffer = (PAFD_BUFFER)ExAllocateFromNPagedLookasideList( + &BufferLookasideList);*/ + Buffer = (PAFD_BUFFER)ExAllocatePool(NonPagedPool, sizeof(AFD_BUFFER)); + if (!Buffer) { + ExFreePool(ReceiveBuffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Buffer->Buffer.len = BytesAvailable; + Buffer->Buffer.buf = ReceiveBuffer; + + ExInterlockedInsertTailList( + &FCB->ReceiveQueue, + &Buffer->ListEntry, + &FCB->ReceiveQueueLock); + + KeAcquireSpinLock(&FCB->ReadRequestQueueLock, &OldIrql); + + if (!IsListEmpty(&FCB->ReadRequestQueue)) { + Entry = RemoveHeadList(&FCB->ReceiveQueue); + ReadRequest = CONTAINING_RECORD(Entry, AFD_READ_REQUEST, ListEntry); + + Status = FillWSABuffers( + FCB, + ReadRequest->RecvFromRequest->Buffers, + ReadRequest->RecvFromRequest->BufferCount, + &ReadRequest->RecvFromReply->NumberOfBytesRecvd); + ReadRequest->RecvFromReply->Status = NO_ERROR; + + ReadRequest->Irp->IoStatus.Information = 0; + ReadRequest->Irp->IoStatus.Status = Status; + IoCompleteRequest(ReadRequest->Irp, IO_NETWORK_INCREMENT); + } + + KeReleaseSpinLock(&FCB->ReadRequestQueueLock, OldIrql); + + *BytesTaken = BytesAvailable; + + AFD_DbgPrint(MAX_TRACE, ("Leaving.\n")); + + return STATUS_SUCCESS; } @@ -108,6 +161,9 @@ NTSTATUS AfdRegisterEventHandlers( { NTSTATUS Status; + assert(FCB->TdiAddressObject); + + /* Report errors for all types of sockets */ Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_ERROR, (PVOID)AfdEventError, @@ -140,7 +196,9 @@ NTSTATUS AfdRegisterEventHandlers( (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } break; + case SOCK_DGRAM: + case SOCK_RAW: Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE_DATAGRAM, (PVOID)AfdEventReceiveDatagramHandler, @@ -190,6 +248,7 @@ NTSTATUS AfdDeregisterEventHandlers( break; case SOCK_DGRAM: + case SOCK_RAW: Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE_DATAGRAM, NULL, diff --git a/reactos/drivers/net/afd/afd/opnclose.c b/reactos/drivers/net/afd/afd/opnclose.c index 26d5880153c..2622483bf67 100644 --- a/reactos/drivers/net/afd/afd/opnclose.c +++ b/reactos/drivers/net/afd/afd/opnclose.c @@ -16,13 +16,13 @@ PAFDFCB AfdInitializeFCB( * FUNCTION: Allocates and initializes a File Control Block structure */ { - PAFDFCB NewFCB; + PAFDFCB NewFCB; - NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB)); - if (!NewFCB) - return NULL; + NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB)); + if (!NewFCB) + return NULL; - RtlZeroMemory(NewFCB, sizeof(AFDFCB)); + RtlZeroMemory(NewFCB, sizeof(AFDFCB)); ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource); ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource); @@ -31,19 +31,25 @@ PAFDFCB AfdInitializeFCB( NewFCB->ReferenceCount = 1; NewFCB->OpenHandleCount = 1; - NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE; - NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE; + NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE; + NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE; - InitializeListHead(&NewFCB->CCBListHead); + InitializeListHead(&NewFCB->CCBListHead); - InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry); + InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry); + + InitializeListHead(&NewFCB->ReceiveQueue); + KeInitializeSpinLock(&NewFCB->ReceiveQueueLock); + + InitializeListHead(&NewFCB->ReadRequestQueue); + KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock); if (FileObject) FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB; - AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB)); + AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB)); - return NewFCB; + return NewFCB; } @@ -91,7 +97,7 @@ AfdCreate( PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT FileObject = IrpSp->FileObject; - AFD_DbgPrint(MIN_TRACE, ("Called.\n")); + AFD_DbgPrint(MAX_TRACE, ("Called.\n")); assert(DeviceObject); @@ -126,39 +132,47 @@ AfdCreate( CCB = AfdInitializeCCB(FCB, FileObject); if (CCB && FCB) { - FCB->AddressFamily = SocketInfo->AddressFamily; - FCB->SocketType = SocketInfo->SocketType; - FCB->Protocol = SocketInfo->Protocol; - FCB->HelperContext = SocketInfo->HelperContext; - FCB->NotificationEvents = SocketInfo->NotificationEvents; + FCB->CommandChannel = SocketInfo->CommandChannel; - if (RtlCreateUnicodeString(&FCB->TdiDeviceName, SocketInfo->TdiDeviceName.Buffer)) { -/* RtlInitUnicodeString(&FCB->TdiDeviceName, NULL); - FCB->TdiDeviceName.MaximumLength = SocketInfo->TdiDeviceName.Length + sizeof(WCHAR); - FCB->TdiDeviceName.Buffer = ExAllocatePool(NonPagedPool, FCB->TdiDeviceName.MaximumLength);*/ + if (!FCB->CommandChannel) { + FCB->AddressFamily = SocketInfo->AddressFamily; + FCB->SocketType = SocketInfo->SocketType; + FCB->Protocol = SocketInfo->Protocol; + FCB->SocketName = SocketInfo->Name; + FCB->HelperContext = SocketInfo->HelperContext; + FCB->NotificationEvents = SocketInfo->NotificationEvents; - RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName); + if (RtlCreateUnicodeString(&FCB->TdiDeviceName, SocketInfo->TdiDeviceName.Buffer)) { - AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName)); + RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName); - /* Open address file now for raw sockets */ - if (FCB->SocketType == SOCK_RAW) { - AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n")); + AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName)); - Status = TdiOpenAddressFile( - &FCB->TdiDeviceName, - &SocketInfo->Name, - &FCB->TdiAddressObjectHandle, - &FCB->TdiAddressObject); + /* Open address file now for raw sockets */ + if (FCB->SocketType == SOCK_RAW) { + AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n")); - AFD_DbgPrint(MAX_TRACE, ("Status of open operation (0x%X).\n", Status)); - - if (NT_SUCCESS(Status)) - FCB->State = SOCKET_STATE_BOUND; + Status = TdiOpenAddressFile( + &FCB->TdiDeviceName, + &SocketInfo->Name, + &FCB->TdiAddressObjectHandle, + &FCB->TdiAddressObject); + if (NT_SUCCESS(Status)) { + Status = AfdRegisterEventHandlers(FCB); + if (NT_SUCCESS(Status)) { + FCB->State = SOCKET_STATE_BOUND; + } else { + AFD_DbgPrint(MAX_TRACE, ("AfdRegisterEventHandlers() failed (0x%X).\n", Status)); + } + } else { + AFD_DbgPrint(MAX_TRACE, ("TdiOpenAddressFile() failed (0x%X).\n", Status)); + } + } else + Status = STATUS_SUCCESS; } else - Status = STATUS_SUCCESS; + Status = STATUS_INSUFFICIENT_RESOURCES; } else - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_SUCCESS; } else Status = STATUS_INSUFFICIENT_RESOURCES; @@ -171,7 +185,7 @@ AfdCreate( IoCompleteRequest(Irp, IO_NO_INCREMENT); - AFD_DbgPrint(MIN_TRACE, ("Leaving. Status (0x%X).\n", Status)); + AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status)); return Status; } @@ -189,7 +203,7 @@ AfdClose( PAFDFCB FCB; PAFDCCB CCB; - AFD_DbgPrint(MIN_TRACE, ("Called.\n")); + AFD_DbgPrint(MAX_TRACE, ("Called.\n")); assert(DeviceObject); assert(FileObject); @@ -202,17 +216,19 @@ AfdClose( case IRP_MJ_CLOSE: FCB->ReferenceCount--; if (FCB->ReferenceCount < 1) { - /* Close TDI connection file object */ - if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) { - TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject); - FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE; - } + if (!FCB->CommandChannel) { + /* Close TDI connection file object */ + if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) { + TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject); + FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE; + } - /* Close TDI address file object */ - if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) { - AfdDeregisterEventHandlers(FCB); - TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject); - FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE; + /* Close TDI address file object */ + if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) { + AfdDeregisterEventHandlers(FCB); + TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject); + FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE; + } } ExFreePool(FCB); diff --git a/reactos/drivers/net/afd/afd/rdwr.c b/reactos/drivers/net/afd/afd/rdwr.c index 76ff7161807..ce2818078a1 100644 --- a/reactos/drivers/net/afd/afd/rdwr.c +++ b/reactos/drivers/net/afd/afd/rdwr.c @@ -12,7 +12,7 @@ NTSTATUS AfdReadFile( PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, - PVOID Buffer, + PVOID Buffer, ULONG Length, ULONG Offset) /* @@ -79,23 +79,39 @@ AfdWrite( FCB = FileObject->FsContext; CCB = FileObject->FsContext2; + assert(FCB); + assert(CCB); + Length = IoSp->Parameters.Write.Length; Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress); Offset = IoSp->Parameters.Write.ByteOffset.u.LowPart; - AFD_DbgPrint(MIN_TRACE, ("Called. Length (%d) Buffer (0x%X) Offset (0x%X)\n", + AFD_DbgPrint(MAX_TRACE, ("Called. Length (%d) Buffer (0x%X) Offset (0x%X)\n", Length, Buffer, Offset)); - /* FIXME: Connectionless communication only */ - //Status = TdiSendDatagram(FCB->TdiAddressObject, WH2N(2000), 0x7F000001, Buffer, Length); - //if (!NT_SUCCESS(Status)) - Length = 0; + assert((FCB->SocketType == SOCK_STREAM) || (FCB->SocketType == SOCK_DGRAM)); + + switch (FCB->SocketType) { + case SOCK_STREAM: + /* FIXME: Support connectionful communication */ + break; + case SOCK_DGRAM: + /* Connectionless communication */ + //Status = TdiSendDatagram(FCB->TdiAddressObject, WH2N(2000), 0x7F000001, Buffer, Length); + //if (!NT_SUCCESS(Status)) { + Length = 0; + //} + break; + case SOCK_RAW: + /* FIXME: Support raw communication */ + break; + } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Length; IoCompleteRequest(Irp, IO_NO_INCREMENT); - AFD_DbgPrint(MIN_TRACE, ("Leaving.\n")); + AFD_DbgPrint(MAX_TRACE, ("Leaving.\n")); return Status; } diff --git a/reactos/drivers/net/afd/afd/routines.c b/reactos/drivers/net/afd/afd/routines.c index 258695263c2..987bef8325e 100644 --- a/reactos/drivers/net/afd/afd/routines.c +++ b/reactos/drivers/net/afd/afd/routines.c @@ -74,5 +74,152 @@ NTSTATUS MergeWSABuffers( return STATUS_SUCCESS; } +NTSTATUS FillWSABuffers( + PAFDFCB FCB, + LPWSABUF Buffers, + DWORD BufferCount, + PULONG BytesCopied) +{ + NTSTATUS Status; + PUCHAR DstData, SrcData; + UINT DstSize, SrcSize; + UINT Count, Total, Length; + PAFD_BUFFER SrcBuffer; + PLIST_ENTRY Entry; + ULONG Size; + + *BytesCopied = 0; + if (BufferCount == 0) + return STATUS_SUCCESS; + + SrcData = SrcBuffer->Buffer.buf; + SrcSize = SrcBuffer->Buffer.len; + + DstData = Buffers->buf; + DstSize = Buffers->len; + + /* Copy the data */ + for (Total = 0;;) { + /* Find out how many bytes we can copy at one time */ + if (Length < SrcSize) + Count = Length; + else + Count = SrcSize; + if (DstSize < Count) + Count = DstSize; + + RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count); + + Total += Count; + Length -= 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 */ + Entry = RemoveHeadList(&FCB->ReceiveQueue); + SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry); + SrcData = SrcBuffer->Buffer.buf; + SrcSize = SrcBuffer->Buffer.len; + } + + DstSize -= Count; + if (DstSize == 0) { + /* No more bytes in destination buffer. Proceed to + the next buffer in the destination buffer chain */ + BufferCount--; + if (BufferCount < 1) + break; + Buffers++; + DstData = Buffers->buf; + DstSize = Buffers->len; + } + + if (Length == 0) + break; + } + + if (SrcSize > 0) { + InsertHeadList(&FCB->ReceiveQueue, Entry); + } + + *BytesCopied = Total; + + return STATUS_SUCCESS; +} + +ULONG ChecksumCompute( + PVOID Data, + UINT Count, + ULONG Seed) +/* + * FUNCTION: Calculate checksum of a buffer + * ARGUMENTS: + * Data = Pointer to buffer with data + * Count = Number of bytes in buffer + * Seed = Previously calculated checksum (if any) + * RETURNS: + * Checksum of buffer + */ +{ + /* FIXME: This should be done in assembler */ + + register ULONG Sum = Seed; + + while (Count > 1) { + Sum += *(PUSHORT)Data; + Count -= 2; + (ULONG_PTR)Data += 2; + } + + /* 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); + + return ~Sum; +} + +VOID BuildIPv4Header( + PIPv4_HEADER IPHeader, + ULONG TotalSize, + ULONG Protocol, + PSOCKADDR SourceAddress, + PSOCKADDR 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; + + /* Calculate checksum of IP header */ + IPHeader->Checksum = (USHORT) + ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0); +} /* EOF */ diff --git a/reactos/drivers/net/afd/afd/tdi.c b/reactos/drivers/net/afd/afd/tdi.c index d22d5946972..32a94801708 100644 --- a/reactos/drivers/net/afd/afd/tdi.c +++ b/reactos/drivers/net/afd/afd/tdi.c @@ -182,7 +182,7 @@ NTSTATUS TdiCall( NULL); } - AFD_DbgPrint(MIN_TRACE, ("Status (0x%X) Iosb.Status (0x%X).\n", Status, IoStatusBlock->Status)); + AFD_DbgPrint(MAX_TRACE, ("Status (0x%X) Iosb.Status (0x%X).\n", Status, IoStatusBlock->Status)); return IoStatusBlock->Status; } @@ -230,15 +230,18 @@ NTSTATUS TdiOpenDevice( EaInfo, /* EA buffer */ EaLength); /* EA length */ if (NT_SUCCESS(Status)) { - Status = ObReferenceObjectByHandle(*Handle, /* Handle to open file */ - GENERIC_READ | GENERIC_WRITE, /* Access mode */ - NULL, /* Object type */ - KernelMode, /* Access mode */ - (PVOID*)Object, /* Pointer to object */ - NULL); /* Handle information */ + Status = ObReferenceObjectByHandle(*Handle, /* Handle to open file */ + GENERIC_READ | GENERIC_WRITE, /* Access mode */ + NULL, /* Object type */ + KernelMode, /* Access mode */ + (PVOID*)Object, /* Pointer to object */ + NULL); /* Handle information */ if (!NT_SUCCESS(Status)) { - AFD_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status)); + AFD_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status)); ZwClose(*Handle); + } else { + AFD_DbgPrint(MAX_TRACE, ("Got handle (0x%X) Object (0x%X)\n", + *Handle, *Object)); } } else { AFD_DbgPrint(MIN_TRACE, ("ZwCreateFile() failed with status (0x%X)\n", Status)); @@ -254,12 +257,12 @@ NTSTATUS TdiCloseDevice( AFD_DbgPrint(MAX_TRACE, ("Called. Handle (0x%X) FileObject (0x%X)\n", Handle, FileObject)); - if (FileObject) - ObDereferenceObject(FileObject); - if (Handle) ZwClose(Handle); + if (FileObject) + ObDereferenceObject(FileObject); + return STATUS_SUCCESS; } @@ -292,10 +295,8 @@ NTSTATUS TdiOpenAddressFileIPv4( TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_ADDRESS_IP); EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength); - if (!EaInfo) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + if (!EaInfo) return STATUS_INSUFFICIENT_RESOURCES; - } RtlZeroMemory(EaInfo, EaLength); EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; @@ -335,7 +336,11 @@ NTSTATUS TdiOpenAddressFile( switch (Name->sa_family) { case AF_INET: - Status = TdiOpenAddressFileIPv4(DeviceName, Name, AddressHandle, AddressObject); + Status = TdiOpenAddressFileIPv4( + DeviceName, + Name, + AddressHandle, + AddressObject); break; default: Status = STATUS_INVALID_PARAMETER; @@ -370,6 +375,8 @@ NTSTATUS TdiSetEventHandler( AFD_DbgPrint(MAX_TRACE, ("Called\n")); + assert(FileObject); + DeviceObject = IoGetRelatedDeviceObject(FileObject); Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */ @@ -717,12 +724,10 @@ DisplayBuffer(Request->Buffers->buf, Request->Buffers->len); } #endif -CP BaseAddress = MmMapLockedPages(Mdl, KernelMode); AFD_DbgPrint(MAX_TRACE, ("Mapped user mode buffer at 0x%X.\n", BaseAddress)); -CP TdiBuildSendDatagram(Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ @@ -733,13 +738,13 @@ CP ConnectInfo); /* Connection information */ Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL); -CP + MmUnmapLockedPages(BaseAddress, Mdl); -CP + MmUnlockPages(Mdl); -CP + IoFreeMdl(Mdl); -CP + ExFreePool(ConnectInfo); return Status; @@ -771,32 +776,21 @@ NTSTATUS TdiSendDatagram( NTSTATUS Status; PIRP Irp; -CP - DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } -CP + TdiAddressSize = TdiAddressSizeFromName(Address); - AFD_DbgPrint(MIN_TRACE, ("TdiAddressSize %d.\n", TdiAddressSize)); - -CP ConnectInfo = (PTDI_CONNECTION_INFORMATION) ExAllocatePool(NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize); - - AFD_DbgPrint(MIN_TRACE, ("ConnectInfo 0x%X.\n", ConnectInfo)); - -CP - if (!ConnectInfo) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + if (!ConnectInfo) return STATUS_INSUFFICIENT_RESOURCES; - } -CP + RtlZeroMemory(ConnectInfo, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize); @@ -804,15 +798,14 @@ CP ConnectInfo->RemoteAddressLength = TdiAddressSize; ConnectInfo->RemoteAddress = (PVOID) (ConnectInfo + sizeof(TDI_CONNECTION_INFORMATION)); -CP + TdiBuildAddress(ConnectInfo->RemoteAddress, Address); -CP + Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */ DeviceObject, /* Device object */ TransportObject, /* File object */ NULL, /* Event */ NULL); /* Return buffer */ -CP if (!Irp) { AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n")); ExFreePool(ConnectInfo); @@ -844,7 +837,6 @@ CP } #endif #endif -CP TdiBuildSendDatagram(Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ @@ -854,17 +846,17 @@ CP Mdl, /* Descriptor for data buffer */ BufferSize, /* Size of data to send */ ConnectInfo); /* Connection information */ -CP + Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL); -CP + #if 0 MmUnlockPages(Mdl); -CP + IoFreeMdl(Mdl); #endif -CP + ExFreePool(ConnectInfo); -CP + return Status; } @@ -995,11 +987,11 @@ NTSTATUS TdiReceiveDatagram( *BufferSize = Iosb.Information; TdiBuildName(Address, ReturnInfo->RemoteAddress); } -CP + MmUnlockPages(Mdl); -CP + IoFreeMdl(Mdl); -CP + ExFreePool(ReceiveInfo); return Status; diff --git a/reactos/drivers/net/afd/include/afd.h b/reactos/drivers/net/afd/include/afd.h index 8aa1f20ed4a..7f01dde87a1 100644 --- a/reactos/drivers/net/afd/include/afd.h +++ b/reactos/drivers/net/afd/include/afd.h @@ -60,6 +60,7 @@ typedef struct _FsdNTRequiredFCB { typedef struct _AFDFCB { FsdNTRequiredFCB NTRequiredFCB; LIST_ENTRY ListEntry; + BOOL CommandChannel; PDEVICE_EXTENSION DeviceExt; SHARE_ACCESS ShareAccess; ULONG ReferenceCount; @@ -72,11 +73,16 @@ typedef struct _AFDFCB { INT AddressFamily; INT SocketType; INT Protocol; + SOCKADDR SocketName; PVOID HelperContext; DWORD NotificationEvents; UNICODE_STRING TdiDeviceName; DWORD State; PVOID SendBuffer; + LIST_ENTRY ReceiveQueue; + KSPIN_LOCK ReceiveQueueLock; + LIST_ENTRY ReadRequestQueue; + KSPIN_LOCK ReadRequestQueueLock; } AFDFCB, *PAFDFCB; /* Socket states */ @@ -84,6 +90,18 @@ typedef struct _AFDFCB { #define SOCKET_STATE_BOUND 1 #define SOCKET_STATE_LISTENING 2 +typedef struct _AFD_BUFFER { + LIST_ENTRY ListEntry; + WSABUF Buffer; +} AFD_BUFFER, *PAFD_BUFFER; + +typedef struct _AFD_READ_REQUEST { + LIST_ENTRY ListEntry; + PIRP Irp; + PFILE_REQUEST_RECVFROM RecvFromRequest; + PFILE_REPLY_RECVFROM RecvFromReply; +} AFD_READ_REQUEST, *PAFD_READ_REQUEST; + typedef struct IPSNMP_INFO { ULONG Forwarding; ULONG DefaultTTL; @@ -127,6 +145,21 @@ typedef struct IPADDR_ENTRY { #define IP_MIB_ADDRTABLE_ENTRY_ID 0x102 +/* IPv4 header format */ +typedef struct IPv4_HEADER { + UCHAR VerIHL; /* 4-bit version, 4-bit Internet Header Length */ + UCHAR Tos; /* Type of Service */ + USHORT TotalLength; /* Total Length */ + USHORT Id; /* Identification */ + USHORT FlagsFragOfs; /* 3-bit Flags, 13-bit Fragment Offset */ + UCHAR Ttl; /* Time to Live */ + UCHAR Protocol; /* Protocol */ + USHORT Checksum; /* Header Checksum */ + ULONG SrcAddr; /* Source Address */ + ULONG DstAddr; /* Destination Address */ +} IPv4_HEADER, *PIPv4_HEADER; + + /* IOCTL codes */ #define IOCTL_TCP_QUERY_INFORMATION_EX \ @@ -183,6 +216,8 @@ typedef struct IPADDR_ENTRY { #endif /* i386 */ +extern NPAGED_LOOKASIDE_LIST BufferLookasideList; + /* Prototypes from dispatch.c */ NTSTATUS AfdDispBind( @@ -201,6 +236,10 @@ NTSTATUS AfdDispRecvFrom( PIRP Irp, PIO_STACK_LOCATION IrpSp); +NTSTATUS AfdDispSelect( + PIRP Irp, + PIO_STACK_LOCATION IrpSp); + /* Prototypes from event.c */ NTSTATUS AfdRegisterEventHandlers( @@ -255,6 +294,19 @@ NTSTATUS MergeWSABuffers( ULONG MaxLength, PULONG BytesCopied); +NTSTATUS FillWSABuffers( + PAFDFCB FCB, + LPWSABUF Buffers, + DWORD BufferCount, + PULONG BytesCopied); + +VOID BuildIPv4Header( + PIPv4_HEADER IPHeader, + ULONG TotalSize, + ULONG Protocol, + PSOCKADDR SourceAddress, + PSOCKADDR DestinationAddress); + /* Prototypes from tdi.c */ NTSTATUS TdiCloseDevice( diff --git a/reactos/drivers/net/tcpip/include/datagram.h b/reactos/drivers/net/tcpip/include/datagram.h index 9dc7e656d54..2f79486718f 100644 --- a/reactos/drivers/net/tcpip/include/datagram.h +++ b/reactos/drivers/net/tcpip/include/datagram.h @@ -14,6 +14,12 @@ VOID DGSend( PVOID Context, PDATAGRAM_SEND_REQUEST SendRequest); +VOID DGDeliverData( + PADDRESS_FILE AddrFile, + PIP_ADDRESS Address, + PIP_PACKET IPPacket, + UINT DataSize); + VOID DGCancelSendRequest( PADDRESS_FILE AddrFile, PVOID Context); diff --git a/reactos/drivers/net/tcpip/include/rawip.h b/reactos/drivers/net/tcpip/include/rawip.h index 0029ef1d5ba..fbd0961d9fa 100644 --- a/reactos/drivers/net/tcpip/include/rawip.h +++ b/reactos/drivers/net/tcpip/include/rawip.h @@ -13,6 +13,10 @@ NTSTATUS RawIPSendDatagram( PNDIS_BUFFER Buffer, ULONG DataSize); +VOID RawIPReceive( + PNET_TABLE_ENTRY NTE, + PIP_PACKET IPPacket); + NTSTATUS RawIPStartup( VOID); diff --git a/reactos/drivers/net/tcpip/network/icmp.c b/reactos/drivers/net/tcpip/network/icmp.c index 462292220e0..ac957f2ef1d 100644 --- a/reactos/drivers/net/tcpip/network/icmp.c +++ b/reactos/drivers/net/tcpip/network/icmp.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include @@ -73,6 +74,9 @@ PIP_PACKET PrepareICMPPacket( TI_DbgPrint(DEBUG_ICMP, ("IPPacket at (0x%X).\n", IPPacket)); + /* No special flags */ + IPPacket->Flags = 0; + Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) + sizeof(ICMP_HEADER) + DataSize; DataBuffer = ExAllocatePool(NonPagedPool, Size); @@ -189,10 +193,8 @@ VOID ICMPReceive( /* Reply with an ICMP echo reply message */ DataSize = IPPacket->TotalSize - IPPacket->HeaderSize - sizeof(ICMP_HEADER); NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize); - if (!NewPacket) { - TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + if (!NewPacket) return; - } /* Copy ICMP header and data into new packet */ RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize + sizeof(ICMP_HEADER)); @@ -203,13 +205,20 @@ VOID ICMPReceive( ICMPTransmit(NTE, NewPacket); TI_DbgPrint(DEBUG_ICMP, ("Echo reply sent.\n")); - return; + + case ICMP_TYPE_ECHO_REPLY: + break; + default: - TI_DbgPrint(DEBUG_ICMP, ("Discarded ICMP datagram of unknown type.\n")); + TI_DbgPrint(DEBUG_ICMP, ("Discarded ICMP datagram of unknown type %d.\n", + ICMPHeader->Type)); /* Discard packet */ break; } + + /* Send datagram up the protocol stack */ + RawIPReceive(NTE, IPPacket); } @@ -256,8 +265,8 @@ VOID ICMPTransmit( VOID ICMPReply( PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket, - UCHAR Type, - UCHAR Code) + UCHAR Type, + UCHAR Code) /* * FUNCTION: Transmits an ICMP packet in response to an incoming packet * ARGUMENTS: diff --git a/reactos/drivers/net/tcpip/network/receive.c b/reactos/drivers/net/tcpip/network/receive.c index 4d56d6bbc23..0b6c1e1c7da 100644 --- a/reactos/drivers/net/tcpip/network/receive.c +++ b/reactos/drivers/net/tcpip/network/receive.c @@ -543,7 +543,7 @@ VOID IPv4Receive( PNET_TABLE_ENTRY NTE; UINT AddressType; - //TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n")); + TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n")); IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2; diff --git a/reactos/drivers/net/tcpip/network/transmit.c b/reactos/drivers/net/tcpip/network/transmit.c index bf192eec3ec..45739bb6381 100644 --- a/reactos/drivers/net/tcpip/network/transmit.c +++ b/reactos/drivers/net/tcpip/network/transmit.c @@ -321,7 +321,7 @@ NTSTATUS IPSendDatagram( if (IPPacket->TotalSize > PathMTU) { return SendFragments(IPPacket, NCE, PathMTU); } else { - if (IPPacket->Flags & IP_PACKET_FLAG_RAW == 0) { + if ((IPPacket->Flags & IP_PACKET_FLAG_RAW) == 0) { /* Calculate checksum of IP header */ ((PIPv4_HEADER)IPPacket->Header)->Checksum = 0; @@ -330,6 +330,9 @@ NTSTATUS IPSendDatagram( TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n", WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength))); + } else { + TI_DbgPrint(MAX_TRACE, ("Sending raw packet (flags are 0x%X).\n", + IPPacket->Flags)); } return IPSendFragment(IPPacket->NdisPacket, NCE); diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index d5702b9551c..5b6024730f2 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -244,6 +244,7 @@ NTSTATUS FileOpenAddress( break; default: /* Use raw IP for all other protocols */ + AddrFile->Port = 0; AddrFile->Send = RawIPSendDatagram; break; } diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index 7c405ac1a7a..e4a3f734202 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -19,8 +19,8 @@ #ifdef DBG /* See debug.h for debug/trace constants */ -//DWORD DebugTraceLevel = MAX_TRACE | DEBUG_CHECK | DEBUG_IRP | DEBUG_RCACHE | DEBUG_ROUTER | DEBUG_REFCOUNT; DWORD DebugTraceLevel = MIN_TRACE; +//DWORD DebugTraceLevel = MAX_TRACE; #endif /* DBG */ diff --git a/reactos/drivers/net/tcpip/tcpip/routines.c b/reactos/drivers/net/tcpip/tcpip/routines.c index 48fca6705eb..7120e0eb150 100644 --- a/reactos/drivers/net/tcpip/tcpip/routines.c +++ b/reactos/drivers/net/tcpip/tcpip/routines.c @@ -405,6 +405,10 @@ VOID DisplayIPPacket( PNDIS_BUFFER Buffer; PNDIS_BUFFER NextBuffer; + if ((DebugTraceLevel & DEBUG_BUFFER) == 0) { + return; + } + if (!IPPacket) { TI_DbgPrint(MIN_TRACE, ("Cannot display null packet.\n")); return; diff --git a/reactos/drivers/net/tcpip/transport/datagram/datagram.c b/reactos/drivers/net/tcpip/transport/datagram/datagram.c index ac9d48e908d..3323cb87178 100644 --- a/reactos/drivers/net/tcpip/transport/datagram/datagram.c +++ b/reactos/drivers/net/tcpip/transport/datagram/datagram.c @@ -227,6 +227,121 @@ VOID DGSend( } +VOID DGDeliverData( + PADDRESS_FILE AddrFile, + PIP_ADDRESS Address, + PIP_PACKET IPPacket, + UINT DataSize) +/* + * FUNCTION: Delivers datagram data to a user + * ARGUMENTS: + * AddrFile = Address file to deliver data to + * Address = Remote address the packet came from + * IPPacket = Pointer to IP packet to deliver + * DataSize = Number of bytes in data area + * NOTES: + * If there is a receive request, then we copy the data to the + * buffer supplied by the user and complete the receive request. + * If no suitable receive request exists, then we call the event + * handler if it exists, otherwise we drop the packet. + */ +{ + KIRQL OldIrql; + PTDI_IND_RECEIVE_DATAGRAM ReceiveHandler; + PVOID HandlerContext; + LONG AddressLength; + PVOID SourceAddress; + ULONG BytesTaken; + NTSTATUS Status; + + TI_DbgPrint(MAX_TRACE, ("Called.\n")); + + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + + if (!IsListEmpty(&AddrFile->ReceiveQueue)) { + PLIST_ENTRY CurrentEntry; + PDATAGRAM_RECEIVE_REQUEST Current; + BOOLEAN Found; + + TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n")); + + /* Search receive request list to find a match */ + Found = FALSE; + CurrentEntry = AddrFile->ReceiveQueue.Flink; + while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) { + Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); + if (!Current->RemoteAddress) + Found = TRUE; + else if (AddrIsEqual(Address, Current->RemoteAddress)) + Found = TRUE; + + if (Found) { + /* FIXME: Maybe we should check if the buffer of this + receive request is large enough and if not, search + for another */ + + /* Remove the request from the queue */ + RemoveEntryList(&Current->ListEntry); + AddrFile->RefCount--; + break; + } + CurrentEntry = CurrentEntry->Flink; + } + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + + if (Found) { + TI_DbgPrint(MAX_TRACE, ("Suitable receive request found.\n")); + + /* Copy the data into buffer provided by the user */ + CopyBufferToBufferChain(Current->Buffer, + 0, + IPPacket->Data, + DataSize); + + /* Complete the receive request */ + (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize); + + /* Finally free the receive request */ + if (Current->RemoteAddress) + PoolFreeBuffer(Current->RemoteAddress); + PoolFreeBuffer(Current); + } + } else if (AddrFile->RegisteredReceiveDatagramHandler) { + TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n")); + + ReceiveHandler = AddrFile->ReceiveDatagramHandler; + HandlerContext = AddrFile->ReceiveDatagramHandlerContext; + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + + if (Address->Type == IP_ADDRESS_V4) { + AddressLength = sizeof(IPv4_RAW_ADDRESS); + SourceAddress = &Address->Address.IPv4Address; + } else /* (Address->Type == IP_ADDRESS_V6) */ { + AddressLength = sizeof(IPv6_RAW_ADDRESS); + SourceAddress = Address->Address.IPv6Address; + } + + Status = (*ReceiveHandler)(HandlerContext, + AddressLength, + SourceAddress, + 0, + NULL, + TDI_RECEIVE_ENTIRE_MESSAGE, + DataSize, + DataSize, + &BytesTaken, + IPPacket->Data, + NULL); + } else { + TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); + } + + TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); +} + + VOID DGCancelSendRequest( PADDRESS_FILE AddrFile, PVOID Context) diff --git a/reactos/drivers/net/tcpip/transport/rawip/rawip.c b/reactos/drivers/net/tcpip/transport/rawip/rawip.c index a3f635dbe41..0401d7e539c 100644 --- a/reactos/drivers/net/tcpip/transport/rawip/rawip.c +++ b/reactos/drivers/net/tcpip/transport/rawip/rawip.c @@ -8,9 +8,10 @@ * CSH 01/08-2000 Created */ #include +#include #include #include -#include +#include #include @@ -96,8 +97,6 @@ NTSTATUS BuildRawIPPacket( NdisChainBufferAtFront(Packet->NdisPacket, HeaderBuffer); } - TI_DbgPrint(MIN_TRACE, ("Chaining data NDIS buffer at back (0x%X)\n", SendRequest->Buffer)); - /* Chain data after link level header if it exists */ NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer); @@ -130,6 +129,70 @@ NTSTATUS RawIPSendDatagram( } +VOID RawIPReceive( + PNET_TABLE_ENTRY NTE, + PIP_PACKET IPPacket) +/* + * FUNCTION: Receives and queues a raw IP datagram + * ARGUMENTS: + * NTE = Pointer to net table entry which the packet was received on + * IPPacket = Pointer to an IP packet that was received + * NOTES: + * This is the low level interface for receiving ICMP datagrams. + * It delivers the packet header and data to anyone that wants it + * When we get here the datagram has already passed sanity checks + */ +{ + AF_SEARCH SearchContext; + PADDRESS_FILE AddrFile; + PIP_ADDRESS DstAddress; + + TI_DbgPrint(MAX_TRACE, ("Called.\n")); + + switch (IPPacket->Type) { + /* IPv4 packet */ + case IP_ADDRESS_V4: + DstAddress = &IPPacket->DstAddr; + break; + + /* IPv6 packet */ + case IP_ADDRESS_V6: + TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 raw IP datagram (%i bytes).\n", + IPPacket->TotalSize)); + + /* FIXME: IPv6 is not supported */ + return; + + default: + return; + } + + /* Locate a receive request on destination address file object + and deliver the packet if one is found. If there is no receive + request on the address file object, call the associated receive + handler. If no receive handler is registered, drop the packet */ + + AddrFile = AddrSearchFirst(DstAddress, + 0, + IPPROTO_ICMP, + &SearchContext); + if (AddrFile) { + do { + DGDeliverData(AddrFile, + DstAddress, + IPPacket, + IPPacket->TotalSize); + } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL); + } else { + /* There are no open address files that will take this datagram */ + /* FIXME: IPv4 only */ + TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 ICMP datagram to address (0x%X).\n", + DN2H(DstAddress->Address.IPv4Address))); + } + TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); +} + + NTSTATUS RawIPStartup( VOID) /* diff --git a/reactos/drivers/net/tcpip/transport/udp/udp.c b/reactos/drivers/net/tcpip/transport/udp/udp.c index bb4661548ba..82b535fa940 100644 --- a/reactos/drivers/net/tcpip/transport/udp/udp.c +++ b/reactos/drivers/net/tcpip/transport/udp/udp.c @@ -181,115 +181,6 @@ NTSTATUS BuildUDPPacket( } -VOID DeliverUDPData( - PADDRESS_FILE AddrFile, - PIP_ADDRESS Address, - PIP_PACKET IPPacket, - UINT DataSize) -/* - * FUNCTION: Delivers UDP data to a user - * ARGUMENTS: - * AddrFile = Address file to deliver data to - * Address = Remote address the packet came from - * IPPacket = Pointer to IP packet to deliver - * DataSize = Number of bytes in data area - * NOTES: - * If there is a receive request, then we copy the data to the - * buffer supplied by the user and complete the receive request. - * If no suitable receive request exists, then we call the event - * handler if it exists, otherwise we drop the packet. - */ -{ - KIRQL OldIrql; - PTDI_IND_RECEIVE_DATAGRAM ReceiveHandler; - PVOID HandlerContext; - LONG AddressLength; - PVOID SourceAddress; - ULONG BytesTaken; - NTSTATUS Status; - - TI_DbgPrint(MAX_TRACE, ("Called.\n")); - - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); - - if (!IsListEmpty(&AddrFile->ReceiveQueue)) { - PLIST_ENTRY CurrentEntry; - PDATAGRAM_RECEIVE_REQUEST Current; - BOOLEAN Found; - - /* Search receive request list to find a match */ - Found = FALSE; - CurrentEntry = AddrFile->ReceiveQueue.Flink; - while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) { - Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); - if (!Current->RemoteAddress) - Found = TRUE; - else if (AddrIsEqual(Address, Current->RemoteAddress)) - Found = TRUE; - - if (Found) { - /* FIXME: Maybe we should check if the buffer of this - receive request is large enough and if not, search - for another. Also a 'best fit' strategy could be used. */ - - /* Remove the request from the queue */ - RemoveEntryList(&Current->ListEntry); - AddrFile->RefCount--; - break; - } - CurrentEntry = CurrentEntry->Flink; - } - - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - - if (Found) { - /* Copy the data into buffer provided by the user */ - CopyBufferToBufferChain(Current->Buffer, - 0, - IPPacket->Data, - DataSize); - - /* Complete the receive request */ - (*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize); - - /* Finally free the receive request */ - if (Current->RemoteAddress) - PoolFreeBuffer(Current->RemoteAddress); - PoolFreeBuffer(Current); - } - } else if (AddrFile->RegisteredReceiveDatagramHandler) { - TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n")); - - ReceiveHandler = AddrFile->ReceiveDatagramHandler; - HandlerContext = AddrFile->ReceiveDatagramHandlerContext; - - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - - if (Address->Type == IP_ADDRESS_V4) { - AddressLength = sizeof(IPv4_RAW_ADDRESS); - SourceAddress = &Address->Address.IPv4Address; - } else /* (Address->Type == IP_ADDRESS_V6) */ { - AddressLength = sizeof(IPv6_RAW_ADDRESS); - SourceAddress = Address->Address.IPv6Address; - } - - Status = (*ReceiveHandler)(HandlerContext, - AddressLength, - SourceAddress, - 0, - NULL, - TDI_RECEIVE_ENTIRE_MESSAGE, - DataSize, - DataSize, - &BytesTaken, - IPPacket->Data, - NULL); - } - - TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); -} - - NTSTATUS UDPSendDatagram( PTDI_REQUEST Request, PTDI_CONNECTION_INFORMATION ConnInfo, @@ -416,10 +307,10 @@ VOID UDPReceive( &SearchContext); if (AddrFile) { do { - DeliverUDPData(AddrFile, - DstAddress, - IPPacket, - DataSize); + DGDeliverData(AddrFile, + DstAddress, + IPPacket, + DataSize); } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL); } else { /* There are no open address files that will take this datagram */ diff --git a/reactos/include/afd/shared.h b/reactos/include/afd/shared.h index b386872efe0..caccb4f7e58 100644 --- a/reactos/include/afd/shared.h +++ b/reactos/include/afd/shared.h @@ -11,6 +11,7 @@ #define AFD_SOCKET_LENGTH (sizeof(AfdSocket) - 1) typedef struct _AFD_SOCKET_INFORMATION { + BOOL CommandChannel; INT AddressFamily; INT SocketType; INT Protocol; @@ -40,6 +41,9 @@ typedef struct _AFD_SOCKET_INFORMATION { #define IOCTL_AFD_RECVFROM \ AFD_CTL_CODE(3, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_AFD_SELECT \ + AFD_CTL_CODE(4, METHOD_BUFFERED, FILE_ANY_ACCESS) + typedef struct _FILE_REQUEST_BIND { SOCKADDR Name; } FILE_REQUEST_BIND, *PFILE_REQUEST_BIND; @@ -86,6 +90,19 @@ typedef struct _FILE_REPLY_RECVFROM { DWORD NumberOfBytesRecvd; } FILE_REPLY_RECVFROM, *PFILE_REPLY_RECVFROM; + +typedef struct _FILE_REQUEST_SELECT { + LPFD_SET ReadFDSet; + LPFD_SET WriteFDSet; + LPFD_SET ExceptFDSet; + TIMEVAL Timeout; +} FILE_REQUEST_SELECT, *PFILE_REQUEST_SELECT; + +typedef struct _FILE_REPLY_SELECT { + INT Status; + DWORD SocketCount; +} FILE_REPLY_SELECT, *PFILE_REPLY_SELECT; + #endif /*__AFD_SHARED_H */ /* EOF */ diff --git a/reactos/include/ddk/exfuncs.h b/reactos/include/ddk/exfuncs.h index 49d6cd75eeb..e55bdbd708c 100644 --- a/reactos/include/ddk/exfuncs.h +++ b/reactos/include/ddk/exfuncs.h @@ -3,6 +3,8 @@ /* EXECUTIVE ROUTINES ******************************************************/ +#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) + VOID FASTCALL ExAcquireFastMutex ( diff --git a/reactos/include/ntdll/ldr.h b/reactos/include/ntdll/ldr.h index 7886313351e..d2ad9d81819 100644 --- a/reactos/include/ntdll/ldr.h +++ b/reactos/include/ntdll/ldr.h @@ -1,3 +1,6 @@ +#include +#include "../ntoskrnl/include/internal/config.h" + typedef NTSTATUS (*PEPFUNC)(PPEB); typedef struct _LDR_MODULE @@ -16,6 +19,9 @@ typedef struct _LDR_MODULE HANDLE SectionHandle; ULONG CheckSum; ULONG TimeDateStamp; +#ifdef KDBG + SYMBOL_TABLE Symbols; +#endif /* KDBG */ } LDR_MODULE, *PLDR_MODULE; @@ -68,4 +74,6 @@ LdrShutdownThread (VOID); NTSTATUS STDCALL LdrUnloadDll (IN PVOID BaseAddress); +VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject); + /* EOF */ diff --git a/reactos/include/ntos/kdbgsyms.h b/reactos/include/ntos/kdbgsyms.h new file mode 100644 index 00000000000..f5f6847d6c4 --- /dev/null +++ b/reactos/include/ntos/kdbgsyms.h @@ -0,0 +1,22 @@ + +#ifndef __KDBGSYMS_H +#define __KDBGSYMS_H + +#include + +typedef struct _SYMBOL +{ + struct _SYMBOL *Next; + /* Address relative to module base address */ + ULONG RelativeAddress; + UNICODE_STRING Name; +} SYMBOL, *PSYMBOL; + +typedef struct _SYMBOL_TABLE +{ + ULONG SymbolCount; + PSYMBOL Symbols; +} SYMBOL_TABLE, *PSYMBOL_TABLE; + +#endif + diff --git a/reactos/include/ntos/types.h b/reactos/include/ntos/types.h index e24ce5e7c54..63c38e55edb 100644 --- a/reactos/include/ntos/types.h +++ b/reactos/include/ntos/types.h @@ -376,9 +376,9 @@ typedef struct _EXCEPTION_RECORD { } EXCEPTION_RECORD, *PEXCEPTION_RECORD, *LPEXCEPTION_RECORD; typedef const void *LPCVOID; -typedef BYTE *LPBYTE; +typedef BYTE *LPBYTE, *PBYTE; -typedef BYTE *PBYTE; +typedef BOOL *PBOOL; typedef DWORD LCID; typedef DWORD *PLCID; diff --git a/reactos/lib/msafd/misc/dllmain.c b/reactos/lib/msafd/misc/dllmain.c index c037a9fa28d..2a0a0f3f43b 100644 --- a/reactos/lib/msafd/misc/dllmain.c +++ b/reactos/lib/msafd/misc/dllmain.c @@ -14,6 +14,7 @@ /* See debug.h for debug/trace constants */ DWORD DebugTraceLevel = MIN_TRACE; +//DWORD DebugTraceLevel = DEBUG_ULTRA; #endif /* DBG */ @@ -26,15 +27,17 @@ WSPUPCALLTABLE Upcalls; LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest; CRITICAL_SECTION InitCriticalSection; DWORD StartupCount = 0; +HANDLE CommandChannel; + NTSTATUS OpenSocket( - SOCKET *Socket, - INT AddressFamily, - INT SocketType, - INT Protocol, - PVOID HelperContext, - DWORD NotificationEvents, - PUNICODE_STRING TdiDeviceName) + SOCKET *Socket, + INT AddressFamily, + INT SocketType, + INT Protocol, + PVOID HelperContext, + DWORD NotificationEvents, + PUNICODE_STRING TdiDeviceName) /* * FUNCTION: Opens a socket * ARGUMENTS: @@ -49,97 +52,102 @@ NTSTATUS OpenSocket( * Status of operation */ { - OBJECT_ATTRIBUTES ObjectAttributes; - PAFD_SOCKET_INFORMATION SocketInfo; - PFILE_FULL_EA_INFORMATION EaInfo; - UNICODE_STRING DeviceName; - IO_STATUS_BLOCK Iosb; - HANDLE FileHandle; - NTSTATUS Status; - ULONG EaLength; - ULONG EaShort; + OBJECT_ATTRIBUTES ObjectAttributes; + PAFD_SOCKET_INFORMATION SocketInfo; + PFILE_FULL_EA_INFORMATION EaInfo; + UNICODE_STRING DeviceName; + IO_STATUS_BLOCK Iosb; + HANDLE FileHandle; + NTSTATUS Status; + ULONG EaLength; + ULONG EaShort; - AFD_DbgPrint(MAX_TRACE, ("Called.\n")); + AFD_DbgPrint(MAX_TRACE, ("Socket (0x%X) TdiDeviceName (%wZ)\n", + Socket, TdiDeviceName)); - EaShort = sizeof(FILE_FULL_EA_INFORMATION) + - AFD_SOCKET_LENGTH + - sizeof(AFD_SOCKET_INFORMATION); + AFD_DbgPrint(MAX_TRACE, ("Socket2 (0x%X) TdiDeviceName (%S)\n", + Socket, TdiDeviceName->Buffer)); - EaLength = EaShort + TdiDeviceName->Length + sizeof(WCHAR); + EaShort = sizeof(FILE_FULL_EA_INFORMATION) + + AFD_SOCKET_LENGTH + + sizeof(AFD_SOCKET_INFORMATION); - EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength); - if (!EaInfo) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - return STATUS_INSUFFICIENT_RESOURCES; - } + EaLength = EaShort + TdiDeviceName->Length + sizeof(WCHAR); - RtlZeroMemory(EaInfo, EaLength); - EaInfo->EaNameLength = AFD_SOCKET_LENGTH; - RtlCopyMemory(EaInfo->EaName, - AfdSocket, - AFD_SOCKET_LENGTH); - EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION); + EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength); + if (!EaInfo) { + return STATUS_INSUFFICIENT_RESOURCES; + } - SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + AFD_SOCKET_LENGTH); + RtlZeroMemory(EaInfo, EaLength); + EaInfo->EaNameLength = AFD_SOCKET_LENGTH; + RtlCopyMemory(EaInfo->EaName, + AfdSocket, + AFD_SOCKET_LENGTH); + EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION); - SocketInfo->AddressFamily = AddressFamily; - SocketInfo->SocketType = SocketType; - SocketInfo->Protocol = Protocol; - SocketInfo->HelperContext = HelperContext; - SocketInfo->NotificationEvents = NotificationEvents; - /* Zeroed above so initialized to a wildcard address if a raw socket */ - SocketInfo->Name.sa_family = AddressFamily; + SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + AFD_SOCKET_LENGTH); + SocketInfo->CommandChannel = FALSE; + SocketInfo->AddressFamily = AddressFamily; + SocketInfo->SocketType = SocketType; + SocketInfo->Protocol = Protocol; + SocketInfo->HelperContext = HelperContext; + SocketInfo->NotificationEvents = NotificationEvents; + /* Zeroed above so initialized to a wildcard address if a raw socket */ + SocketInfo->Name.sa_family = AddressFamily; - /* Store TDI device name last in buffer */ - SocketInfo->TdiDeviceName.Buffer = (PWCHAR)(EaInfo + EaShort); - SocketInfo->TdiDeviceName.MaximumLength = TdiDeviceName->Length + sizeof(WCHAR); - RtlCopyUnicodeString(&SocketInfo->TdiDeviceName, TdiDeviceName); + /* Store TDI device name last in buffer */ + SocketInfo->TdiDeviceName.Buffer = (PWCHAR)(EaInfo + EaShort); + SocketInfo->TdiDeviceName.MaximumLength = TdiDeviceName->Length + sizeof(WCHAR); + RtlCopyUnicodeString(&SocketInfo->TdiDeviceName, TdiDeviceName); - AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) EaLength is (%d).\n", (UINT)EaInfo, (INT)EaLength)); + AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) EaLength is (%d).\n", (UINT)EaInfo, (INT)EaLength)); + RtlInitUnicodeString(&DeviceName, L"\\Device\\Afd"); + InitializeObjectAttributes( + &ObjectAttributes, + &DeviceName, + 0, + NULL, + NULL); - RtlInitUnicodeString(&DeviceName, L"\\Device\\Afd"); - InitializeObjectAttributes(&ObjectAttributes, - &DeviceName, - 0, - NULL, - NULL); + Status = NtCreateFile( + &FileHandle, + FILE_GENERIC_READ | FILE_GENERIC_WRITE, + &ObjectAttributes, + &Iosb, + NULL, + 0, + 0, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_ALERT, + EaInfo, + EaLength); - Status = NtCreateFile(&FileHandle, - FILE_GENERIC_READ | FILE_GENERIC_WRITE, - &ObjectAttributes, - &Iosb, - NULL, - 0, - 0, - FILE_OPEN, - FILE_SYNCHRONOUS_IO_ALERT, - EaInfo, - EaLength); + HeapFree(GlobalHeap, 0, EaInfo); - HeapFree(GlobalHeap, 0, EaInfo); + if (!NT_SUCCESS(Status)) { + AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n", + (UINT)Status)); + return STATUS_INSUFFICIENT_RESOURCES; + } - if (!NT_SUCCESS(Status)) { - AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n", (UINT)Status)); - return STATUS_INSUFFICIENT_RESOURCES; - } + *Socket = (SOCKET)FileHandle; - *Socket = (SOCKET)FileHandle; - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } SOCKET WSPAPI WSPSocket( - IN INT af, - IN INT type, - IN INT protocol, - IN LPWSAPROTOCOL_INFOW lpProtocolInfo, - IN GROUP g, - IN DWORD dwFlags, - OUT LPINT lpErrno) + IN INT af, + IN INT type, + IN INT protocol, + IN LPWSAPROTOCOL_INFOW lpProtocolInfo, + IN GROUP g, + IN DWORD dwFlags, + OUT LPINT lpErrno) /* * FUNCTION: Creates a new socket * ARGUMENTS: @@ -154,92 +162,91 @@ WSPSocket( * Created socket, or INVALID_SOCKET if it could not be created */ { - WSAPROTOCOL_INFOW ProtocolInfo; - UNICODE_STRING TdiDeviceName; - DWORD NotificationEvents; - PWSHELPER_DLL HelperDLL; - PVOID HelperContext; - INT AddressFamily; - NTSTATUS NtStatus; - INT SocketType; - SOCKET Socket2; - SOCKET Socket; - INT Protocol; - INT Status; + WSAPROTOCOL_INFOW ProtocolInfo; + UNICODE_STRING TdiDeviceName; + DWORD NotificationEvents; + PWSHELPER_DLL HelperDLL; + PVOID HelperContext; + INT AddressFamily; + NTSTATUS NtStatus; + INT SocketType; + SOCKET Socket2; + SOCKET Socket; + INT Protocol; + INT Status; - AFD_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n", - af, type, protocol)); + AFD_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n", + af, type, protocol)); - if (!lpProtocolInfo) { - CP - lpProtocolInfo = &ProtocolInfo; - ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW)); + if (!lpProtocolInfo) { + lpProtocolInfo = &ProtocolInfo; + ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW)); - ProtocolInfo.iAddressFamily = af; - ProtocolInfo.iSocketType = type; - ProtocolInfo.iProtocol = protocol; - } + ProtocolInfo.iAddressFamily = af; + ProtocolInfo.iSocketType = type; + ProtocolInfo.iProtocol = protocol; + } - HelperDLL = LocateHelperDLL(lpProtocolInfo); - if (!HelperDLL) { - *lpErrno = WSAEAFNOSUPPORT; - return INVALID_SOCKET; - } + HelperDLL = LocateHelperDLL(lpProtocolInfo); + if (!HelperDLL) { + *lpErrno = WSAEAFNOSUPPORT; + return INVALID_SOCKET; + } - AddressFamily = lpProtocolInfo->iAddressFamily; - SocketType = lpProtocolInfo->iSocketType; - Protocol = lpProtocolInfo->iProtocol; + AddressFamily = lpProtocolInfo->iAddressFamily; + SocketType = lpProtocolInfo->iSocketType; + Protocol = lpProtocolInfo->iProtocol; - Status = HelperDLL->EntryTable.lpWSHOpenSocket2(&AddressFamily, - &SocketType, - &Protocol, - 0, - 0, - &TdiDeviceName, - &HelperContext, - &NotificationEvents); - if (Status != NO_ERROR) { - *lpErrno = Status; - return INVALID_SOCKET; - } + Status = HelperDLL->EntryTable.lpWSHOpenSocket2( + &AddressFamily, + &SocketType, + &Protocol, + 0, + 0, + &TdiDeviceName, + &HelperContext, + &NotificationEvents); + if (Status != NO_ERROR) { + *lpErrno = Status; + return INVALID_SOCKET; + } - NtStatus = OpenSocket(&Socket, - AddressFamily, - SocketType, - Protocol, - HelperContext, - NotificationEvents, - &TdiDeviceName); + NtStatus = OpenSocket(&Socket, + AddressFamily, + SocketType, + Protocol, + HelperContext, + NotificationEvents, + &TdiDeviceName); - RtlFreeUnicodeString(&TdiDeviceName); - if (!NT_SUCCESS(NtStatus)) { - CP - *lpErrno = RtlNtStatusToDosError(Status); - return INVALID_SOCKET; - } + RtlFreeUnicodeString(&TdiDeviceName); + if (!NT_SUCCESS(NtStatus)) { + *lpErrno = RtlNtStatusToDosError(Status); + return INVALID_SOCKET; + } - /* FIXME: Assumes catalog entry id to be 1 */ - Socket2 = Upcalls.lpWPUModifyIFSHandle(1, Socket, lpErrno); + /* FIXME: Assumes catalog entry id to be 1 */ + Socket2 = Upcalls.lpWPUModifyIFSHandle(1, Socket, lpErrno); - if (Socket2 == INVALID_SOCKET) { - /* FIXME: Cleanup */ - AFD_DbgPrint(MIN_TRACE, ("FIXME: Cleanup.\n")); - return INVALID_SOCKET; - } + if (Socket2 == INVALID_SOCKET) { + /* FIXME: Cleanup */ + AFD_DbgPrint(MIN_TRACE, ("FIXME: Cleanup.\n")); + return INVALID_SOCKET; + } - *lpErrno = NO_ERROR; + *lpErrno = NO_ERROR; - AFD_DbgPrint(MID_TRACE, ("Returning socket descriptor (0x%X).\n", Socket2)); + AFD_DbgPrint(MID_TRACE, ("Returning socket descriptor (0x%X).\n", Socket2)); - return Socket2; + return Socket2; } INT WSPAPI WSPCloseSocket( - IN SOCKET s, - OUT LPINT lpErrno) + IN SOCKET s, + OUT LPINT lpErrno) /* * FUNCTION: Closes an open socket * ARGUMENTS: @@ -249,29 +256,29 @@ WSPCloseSocket( * NO_ERROR, or SOCKET_ERROR if the socket could not be closed */ { - NTSTATUS Status; + NTSTATUS Status; - AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s)); + AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s)); - Status = NtClose((HANDLE)s); + Status = NtClose((HANDLE)s); - if (NT_SUCCESS(Status)) { - *lpErrno = NO_ERROR; - return NO_ERROR; - } + if (NT_SUCCESS(Status)) { + *lpErrno = NO_ERROR; + return NO_ERROR; + } - *lpErrno = WSAENOTSOCK; - return SOCKET_ERROR; + *lpErrno = WSAENOTSOCK; + return SOCKET_ERROR; } INT WSPAPI WSPBind( - IN SOCKET s, - IN CONST LPSOCKADDR name, - IN INT namelen, - OUT LPINT lpErrno) + IN SOCKET s, + IN CONST LPSOCKADDR name, + IN INT namelen, + OUT LPINT lpErrno) /* * FUNCTION: Associates a local address with a socket * ARGUMENTS: @@ -293,7 +300,8 @@ WSPBind( RtlCopyMemory(&Request.Name, name, sizeof(SOCKADDR)); - Status = NtDeviceIoControlFile((HANDLE)s, + Status = NtDeviceIoControlFile( + (HANDLE)s, NULL, NULL, NULL, @@ -324,12 +332,12 @@ WSPBind( INT WSPAPI WSPSelect( - IN INT nfds, - IN OUT LPFD_SET readfds, - IN OUT LPFD_SET writefds, - IN OUT LPFD_SET exceptfds, - IN CONST LPTIMEVAL timeout, - OUT LPINT lpErrno) + IN INT nfds, + IN OUT LPFD_SET readfds, + IN OUT LPFD_SET writefds, + IN OUT LPFD_SET exceptfds, + IN CONST LPTIMEVAL timeout, + OUT LPINT lpErrno) /* * FUNCTION: Returns status of one or more sockets * ARGUMENTS: @@ -344,37 +352,217 @@ WSPSelect( * Number of ready socket descriptors, or SOCKET_ERROR if an error ocurred */ { - AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n", + PFILE_REQUEST_SELECT Request; + FILE_REPLY_SELECT Reply; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + DWORD Size; + DWORD ReadSize; + DWORD WriteSize; + DWORD ExceptSize; + PVOID Current; + + AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n", readfds, writefds, exceptfds)); - /* FIXME: For now, all reads are timed out immediately */ - if (readfds != NULL) { - AFD_DbgPrint(MIN_TRACE, ("Timing out read query.\n")); - *lpErrno = WSAETIMEDOUT; - return SOCKET_ERROR; - } - - /* FIXME: For now, always allow write */ - if (writefds != NULL) { - AFD_DbgPrint(MIN_TRACE, ("Setting one socket writeable.\n")); - *lpErrno = NO_ERROR; - return 1; - } + /* FIXME: For now, all reads are timed out immediately */ + if (readfds != NULL) { + AFD_DbgPrint(MID_TRACE, ("Timing out read query.\n")); + *lpErrno = WSAETIMEDOUT; + return SOCKET_ERROR; + } + /* FIXME: For now, always allow write */ + if (writefds != NULL) { + AFD_DbgPrint(MID_TRACE, ("Setting one socket writeable.\n")); *lpErrno = NO_ERROR; + return 1; + } - return 0; + return 0; + + ReadSize = 0; + if ((readfds != NULL) && (readfds->fd_count > 0)) { + ReadSize = (readfds->fd_count * sizeof(SOCKET)) + sizeof(UINT); + } + + WriteSize = 0; + if ((writefds != NULL) && (writefds->fd_count > 0)) { + WriteSize = (writefds->fd_count * sizeof(SOCKET)) + sizeof(UINT); + } + + ExceptSize = 0; + if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) { + ExceptSize = (exceptfds->fd_count * sizeof(SOCKET)) + sizeof(UINT); + } + + Size = ReadSize + WriteSize + ExceptSize; + + Request = (PFILE_REQUEST_SELECT)HeapAlloc( + GlobalHeap, 0, sizeof(FILE_REQUEST_SELECT) + Size); + if (!Request) { + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + + /* Put FD SETs after request structure */ + Current = (Request + sizeof(FILE_REQUEST_SELECT)); + Request->ReadFDSet = (LPFD_SET)Current; + + if (ReadSize > 0) { + RtlCopyMemory(Request->ReadFDSet, readfds, ReadSize); + } + + Current += ReadSize; + + if (WriteSize > 0) { + RtlCopyMemory(Request->WriteFDSet, writefds, WriteSize); + } + + Current += WriteSize; + + if (ExceptSize > 0) { + RtlCopyMemory(Request->ExceptFDSet, exceptfds, ExceptSize); + } + + Status = NtDeviceIoControlFile(CommandChannel, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_AFD_SELECT, + Request, + sizeof(FILE_REQUEST_SELECT) + Size, + &Reply, + sizeof(FILE_REPLY_SELECT)); + + HeapFree(GlobalHeap, 0, Request); + + 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; + } + } + + if (!NT_SUCCESS(Status)) { + AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status)); + *lpErrno = WSAENOBUFS; + return SOCKET_ERROR; + } + + AFD_DbgPrint(MAX_TRACE, ("Select successful.\n")); + + *lpErrno = NO_ERROR; + + return 0; +} + + +NTSTATUS OpenCommandChannel( + VOID) +/* + * FUNCTION: Opens a command channel to afd.sys + * ARGUMENTS: + * None + * RETURNS: + * Status of operation + */ +{ + OBJECT_ATTRIBUTES ObjectAttributes; + PAFD_SOCKET_INFORMATION SocketInfo; + PFILE_FULL_EA_INFORMATION EaInfo; + UNICODE_STRING DeviceName; + IO_STATUS_BLOCK Iosb; + HANDLE FileHandle; + NTSTATUS Status; + ULONG EaLength; + ULONG EaShort; + + AFD_DbgPrint(MAX_TRACE, ("Called\n")); + + EaShort = sizeof(FILE_FULL_EA_INFORMATION) + + AFD_SOCKET_LENGTH + + sizeof(AFD_SOCKET_INFORMATION); + + EaLength = EaShort; + + EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength); + if (!EaInfo) { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlZeroMemory(EaInfo, EaLength); + EaInfo->EaNameLength = AFD_SOCKET_LENGTH; + RtlCopyMemory(EaInfo->EaName, + AfdSocket, + AFD_SOCKET_LENGTH); + EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION); + + SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + AFD_SOCKET_LENGTH); + SocketInfo->CommandChannel = TRUE; + + RtlInitUnicodeString(&DeviceName, L"\\Device\\Afd"); + InitializeObjectAttributes( + &ObjectAttributes, + &DeviceName, + 0, + NULL, + NULL); + + Status = NtCreateFile( + &FileHandle, + FILE_GENERIC_READ | FILE_GENERIC_WRITE, + &ObjectAttributes, + &Iosb, + NULL, + 0, + 0, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_ALERT, + EaInfo, + EaLength); + + if (!NT_SUCCESS(Status)) { + AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n", + (UINT)Status)); + return Status; + } + + CommandChannel = FileHandle; + + return STATUS_SUCCESS; +} + + +NTSTATUS CloseCommandChannel( + VOID) +/* + * FUNCTION: Closes command channel to afd.sys + * ARGUMENTS: + * None + * RETURNS: + * Status of operation + */ +{ + AFD_DbgPrint(MAX_TRACE, ("Called.\n")); + + return NtClose(CommandChannel); } INT WSPAPI WSPStartup( - IN WORD wVersionRequested, - OUT LPWSPDATA lpWSPData, - IN LPWSAPROTOCOL_INFOW lpProtocolInfo, - IN WSPUPCALLTABLE UpcallTable, - OUT LPWSPPROC_TABLE lpProcTable) + IN WORD wVersionRequested, + OUT LPWSPDATA lpWSPData, + IN LPWSAPROTOCOL_INFOW lpProtocolInfo, + IN WSPUPCALLTABLE UpcallTable, + OUT LPWSPPROC_TABLE lpProcTable) /* * FUNCTION: Initialize service provider for a client * ARGUMENTS: @@ -387,89 +575,89 @@ WSPStartup( * Status of operation */ { - HMODULE hWS2_32; - INT Status; + HMODULE hWS2_32; + INT Status; - AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested)); + AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested)); - //EnterCriticalSection(&InitCriticalSection); + EnterCriticalSection(&InitCriticalSection); - Upcalls = UpcallTable; + Upcalls = UpcallTable; - if (StartupCount == 0) { - /* First time called */ + if (StartupCount == 0) { + /* First time called */ - Status = WSAVERNOTSUPPORTED; + Status = WSAVERNOTSUPPORTED; - hWS2_32 = GetModuleHandle(L"ws2_32.dll"); - - if (hWS2_32 != NULL) { - lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST) - GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest"); - - if (lpWPUCompleteOverlappedRequest != NULL) { - Status = NO_ERROR; - StartupCount++; - CP - } - } else { - AFD_DbgPrint(MIN_TRACE, ("GetModuleHandle() failed for ws2_32.dll\n")); + Status = OpenCommandChannel(); + if (NT_SUCCESS(Status)) { + hWS2_32 = GetModuleHandle(L"ws2_32.dll"); + if (hWS2_32 != NULL) { + lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST) + GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest"); + if (lpWPUCompleteOverlappedRequest != NULL) { + Status = NO_ERROR; + StartupCount++; } + } else { + AFD_DbgPrint(MIN_TRACE, ("GetModuleHandle() failed for ws2_32.dll\n")); + } } else { - Status = NO_ERROR; - StartupCount++; + AFD_DbgPrint(MIN_TRACE, ("Cannot open afd.sys\n")); } + } else { + Status = NO_ERROR; + StartupCount++; + } - //LeaveCriticalSection(&InitCriticalSection); + LeaveCriticalSection(&InitCriticalSection); - AFD_DbgPrint(MIN_TRACE, ("WSPSocket() is at 0x%X\n", WSPSocket)); + if (Status == NO_ERROR) { + lpProcTable->lpWSPAccept = WSPAccept; + lpProcTable->lpWSPAddressToString = WSPAddressToString; + lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect; + lpProcTable->lpWSPBind = WSPBind; + lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall; + lpProcTable->lpWSPCleanup = WSPCleanup; + lpProcTable->lpWSPCloseSocket = WSPCloseSocket; + lpProcTable->lpWSPConnect = WSPConnect; + lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket; + lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents; + lpProcTable->lpWSPEventSelect = WSPEventSelect; + lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult; + lpProcTable->lpWSPGetPeerName = WSPGetPeerName; + lpProcTable->lpWSPGetSockName = WSPGetSockName; + lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt; + lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName; + lpProcTable->lpWSPIoctl = WSPIoctl; + lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf; + lpProcTable->lpWSPListen = WSPListen; + lpProcTable->lpWSPRecv = WSPRecv; + lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect; + lpProcTable->lpWSPRecvFrom = WSPRecvFrom; + lpProcTable->lpWSPSelect = WSPSelect; + lpProcTable->lpWSPSend = WSPSend; + lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect; + lpProcTable->lpWSPSendTo = WSPSendTo; + lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt; + lpProcTable->lpWSPShutdown = WSPShutdown; + lpProcTable->lpWSPSocket = WSPSocket; + lpProcTable->lpWSPStringToAddress = WSPStringToAddress; - if (Status == NO_ERROR) { - lpProcTable->lpWSPAccept = WSPAccept; - lpProcTable->lpWSPAddressToString = WSPAddressToString; - lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect; - lpProcTable->lpWSPBind = WSPBind; - lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall; - lpProcTable->lpWSPCleanup = WSPCleanup; - lpProcTable->lpWSPCloseSocket = WSPCloseSocket; - lpProcTable->lpWSPConnect = WSPConnect; - lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket; - lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents; - lpProcTable->lpWSPEventSelect = WSPEventSelect; - lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult; - lpProcTable->lpWSPGetPeerName = WSPGetPeerName; - lpProcTable->lpWSPGetSockName = WSPGetSockName; - lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt; - lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName; - lpProcTable->lpWSPIoctl = WSPIoctl; - lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf; - lpProcTable->lpWSPListen = WSPListen; - lpProcTable->lpWSPRecv = WSPRecv; - lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect; - lpProcTable->lpWSPRecvFrom = WSPRecvFrom; - lpProcTable->lpWSPSelect = WSPSelect; - lpProcTable->lpWSPSend = WSPSend; - lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect; - lpProcTable->lpWSPSendTo = WSPSendTo; - lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt; - lpProcTable->lpWSPShutdown = WSPShutdown; - lpProcTable->lpWSPSocket = WSPSocket; - lpProcTable->lpWSPStringToAddress = WSPStringToAddress; + lpWSPData->wVersion = MAKEWORD(2, 2); + lpWSPData->wHighVersion = MAKEWORD(2, 2); + } - lpWSPData->wVersion = MAKEWORD(2, 2); - lpWSPData->wHighVersion = MAKEWORD(2, 2); - } + AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status)); - AFD_DbgPrint(MIN_TRACE, ("Status (%d).\n", Status)); - - return Status; + return Status; } INT WSPAPI WSPCleanup( - OUT LPINT lpErrno) + OUT LPINT lpErrno) /* * FUNCTION: Cleans up service provider for a client * ARGUMENTS: @@ -478,23 +666,25 @@ WSPCleanup( * 0 if successful, or SOCKET_ERROR if not */ { - AFD_DbgPrint(MAX_TRACE, ("\n")); + AFD_DbgPrint(MAX_TRACE, ("\n")); - //EnterCriticalSection(&InitCriticalSection); + EnterCriticalSection(&InitCriticalSection); - if (StartupCount > 0) { - StartupCount--; + if (StartupCount > 0) { + StartupCount--; - if (StartupCount == 0) { - AFD_DbgPrint(MAX_TRACE, ("Cleaning up msafd.dll.\n")); - } + if (StartupCount == 0) { + AFD_DbgPrint(MAX_TRACE, ("Cleaning up msafd.dll.\n")); + + CloseCommandChannel(); } + } - //LeaveCriticalSection(&InitCriticalSection); + LeaveCriticalSection(&InitCriticalSection); - *lpErrno = NO_ERROR; + *lpErrno = NO_ERROR; - return 0; + return 0; } @@ -504,7 +694,7 @@ DllMain(HANDLE hInstDll, ULONG dwReason, PVOID Reserved) { - AFD_DbgPrint(MIN_TRACE, ("DllMain of msafd.dll\n")); + AFD_DbgPrint(MAX_TRACE, ("DllMain of msafd.dll\n")); switch (dwReason) { case DLL_PROCESS_ATTACH: @@ -512,14 +702,9 @@ DllMain(HANDLE hInstDll, so disable them to improve performance */ DisableThreadLibraryCalls(hInstDll); - //InitializeCriticalSection(&InitCriticalSection); + InitializeCriticalSection(&InitCriticalSection); GlobalHeap = GetProcessHeap(); - //GlobalHeap = HeapCreate(0, 0, 0); - if (!GlobalHeap) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); - return FALSE; - } CreateHelperDLLDatabase(); break; @@ -532,9 +717,8 @@ DllMain(HANDLE hInstDll, case DLL_PROCESS_DETACH: DestroyHelperDLLDatabase(); - //HeapDestroy(GlobalHeap); - //DeleteCriticalSection(&InitCriticalSection); + DeleteCriticalSection(&InitCriticalSection); break; } diff --git a/reactos/lib/msafd/misc/helpers.c b/reactos/lib/msafd/misc/helpers.c index 523743271ad..2263724a6b0 100644 --- a/reactos/lib/msafd/misc/helpers.c +++ b/reactos/lib/msafd/misc/helpers.c @@ -10,7 +10,7 @@ #include #include -//CRITICAL_SECTION HelperDLLDatabaseLock; +CRITICAL_SECTION HelperDLLDatabaseLock; LIST_ENTRY HelperDLLDatabaseListHead; PWSHELPER_DLL CreateHelperDLL( @@ -19,19 +19,17 @@ PWSHELPER_DLL CreateHelperDLL( PWSHELPER_DLL HelperDLL; HelperDLL = HeapAlloc(GlobalHeap, 0, sizeof(WSHELPER_DLL)); - if (!HelperDLL) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); + if (!HelperDLL) return NULL; - } - //InitializeCriticalSection(&HelperDLL->Lock); + InitializeCriticalSection(&HelperDLL->Lock); HelperDLL->hModule = NULL; lstrcpyW(HelperDLL->LibraryName, LibraryName); HelperDLL->Mapping = NULL; - //EnterCriticalSection(&HelperDLLDatabaseLock); + EnterCriticalSection(&HelperDLLDatabaseLock); InsertTailList(&HelperDLLDatabaseListHead, &HelperDLL->ListEntry); - //LeaveCriticalSection(&HelperDLLDatabaseLock); + LeaveCriticalSection(&HelperDLLDatabaseLock); AFD_DbgPrint(MAX_TRACE, ("Returning helper at (0x%X).\n", HelperDLL)); @@ -46,9 +44,9 @@ INT DestroyHelperDLL( AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X).\n", HelperDLL)); - //EnterCriticalSection(&HelperDLLDatabaseLock); + EnterCriticalSection(&HelperDLLDatabaseLock); RemoveEntryList(&HelperDLL->ListEntry); - //LeaveCriticalSection(&HelperDLLDatabaseLock); + LeaveCriticalSection(&HelperDLLDatabaseLock); if (HelperDLL->hModule) { Status = UnloadHelperDLL(HelperDLL); @@ -59,7 +57,7 @@ INT DestroyHelperDLL( if (HelperDLL->Mapping) HeapFree(GlobalHeap, 0, HelperDLL->Mapping); - //DeleteCriticalSection(&HelperDLL->Lock); + DeleteCriticalSection(&HelperDLL->Lock); HeapFree(GlobalHeap, 0, HelperDLL); @@ -74,7 +72,7 @@ PWSHELPER_DLL LocateHelperDLL( PWSHELPER_DLL HelperDLL; UINT i; - //EnterCriticalSection(&HelperDLLDatabaseLock); + EnterCriticalSection(&HelperDLLDatabaseLock); CurrentEntry = HelperDLLDatabaseListHead.Flink; while (CurrentEntry != &HelperDLLDatabaseListHead) { HelperDLL = CONTAINING_RECORD(CurrentEntry, @@ -86,7 +84,7 @@ PWSHELPER_DLL LocateHelperDLL( (lpProtocolInfo->iSocketType == HelperDLL->Mapping->Mapping[i].SocketType) && ((lpProtocolInfo->iProtocol == HelperDLL->Mapping->Mapping[i].Protocol) || (lpProtocolInfo->iSocketType == SOCK_RAW))) { - //LeaveCriticalSection(&HelperDLLDatabaseLock); + LeaveCriticalSection(&HelperDLLDatabaseLock); AFD_DbgPrint(MAX_TRACE, ("Returning helper DLL at (0x%X).\n", HelperDLL)); return HelperDLL; } @@ -94,7 +92,7 @@ PWSHELPER_DLL LocateHelperDLL( CurrentEntry = CurrentEntry->Flink; } - //LeaveCriticalSection(&HelperDLLDatabaseLock); + LeaveCriticalSection(&HelperDLLDatabaseLock); AFD_DbgPrint(MAX_TRACE, ("Could not locate helper DLL.\n")); @@ -156,7 +154,7 @@ INT LoadHelperDLL( } else Status = NO_ERROR; - AFD_DbgPrint(MIN_TRACE, ("Status (%d).\n", Status)); + AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status)); return Status; } @@ -186,22 +184,18 @@ VOID CreateHelperDLLDatabase(VOID) { PWSHELPER_DLL HelperDLL; - //InitializeCriticalSection(&HelperDLLDatabaseLock); + InitializeCriticalSection(&HelperDLLDatabaseLock); InitializeListHead(&HelperDLLDatabaseListHead); /* FIXME: Read helper DLL configuration from registry */ HelperDLL = CreateHelperDLL(L"wshtcpip.dll"); - if (!HelperDLL) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); + if (!HelperDLL) return; - } HelperDLL->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD)); - if (!HelperDLL->Mapping) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); + if (!HelperDLL->Mapping) return; - } HelperDLL->Mapping->Rows = 1; HelperDLL->Mapping->Columns = 3; @@ -231,7 +225,7 @@ VOID DestroyHelperDLLDatabase(VOID) CurrentEntry = NextEntry; } - //DeleteCriticalSection(&HelperDLLDatabaseLock); + DeleteCriticalSection(&HelperDLLDatabaseLock); } /* EOF */ diff --git a/reactos/lib/msafd/misc/sndrcv.c b/reactos/lib/msafd/misc/sndrcv.c index c614809db4f..c7ef48d3b88 100644 --- a/reactos/lib/msafd/misc/sndrcv.c +++ b/reactos/lib/msafd/misc/sndrcv.c @@ -193,7 +193,6 @@ WSPSendTo( Request = (PFILE_REQUEST_SENDTO)HeapAlloc( GlobalHeap, 0, sizeof(FILE_REQUEST_SENDTO) + Size); if (!Request) { - AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); *lpErrno = WSAENOBUFS; return SOCKET_ERROR; } diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index 6306ba92910..51381d48e70 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -1,4 +1,4 @@ -/* $Id: startup.c,v 1.33 2000/11/19 15:59:46 ekohl Exp $ +/* $Id: startup.c,v 1.34 2001/06/04 11:26:10 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -179,6 +179,10 @@ LdrInitializeThunk (ULONG Unknown1, InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, &NtModule->InInitializationOrderModuleList); +#ifdef KDBG + LdrLoadModuleSymbols(NtModule); +#endif /* KDBG */ + /* add entry for executable (becomes first list entry) */ ExeModule = (PLDR_MODULE)RtlAllocateHeap (Peb->ProcessHeap, @@ -221,6 +225,10 @@ LdrInitializeThunk (ULONG Unknown1, InsertHeadList(&Peb->Ldr->InLoadOrderModuleList, &ExeModule->InLoadOrderModuleList); +#ifdef KDBG + LdrLoadModuleSymbols(ExeModule); +#endif /* KDBG */ + EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL); ExeModule->EntryPoint = (ULONG)EntryPoint; diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index 4aebfe86f9e..8e256b15c75 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.43 2001/04/10 19:14:27 ekohl Exp $ +/* $Id: utils.c,v 1.44 2001/06/04 11:26:10 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -52,6 +52,23 @@ static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hin /* FUNCTIONS *****************************************************************/ + +#ifdef KDBG + +VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject) +{ + NtSystemDebugControl( + 0xffffffff, + (PVOID)ModuleObject, + 0, + NULL, + 0, + NULL); +} + +#endif /* KDBG */ + + /*************************************************************************** * NAME LOCAL * LdrAdjustDllName @@ -385,7 +402,11 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, InsertTailList(&NtCurrentPeb()->Ldr->InInitializationOrderModuleList, &Module->InInitializationOrderModuleList); /* FIXME: release loader lock */ - + +#ifdef KDBG + LdrLoadModuleSymbols(Module); +#endif /* KDBG */ + /* initialize dll */ if ((NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) == IMAGE_FILE_DLL) @@ -415,7 +436,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL, &Module->BaseDllName); } } - + *BaseAddress = Module->BaseAddress; return STATUS_SUCCESS; } diff --git a/reactos/lib/ws2_32/include/catalog.h b/reactos/lib/ws2_32/include/catalog.h index 6969c168dd0..885c0406d99 100644 --- a/reactos/lib/ws2_32/include/catalog.h +++ b/reactos/lib/ws2_32/include/catalog.h @@ -14,7 +14,7 @@ typedef struct _CATALOG_ENTRY { LIST_ENTRY ListEntry; ULONG ReferenceCount; CRITICAL_SECTION Lock; - WCHAR LibraryName[MAX_PATH]; + UNICODE_STRING LibraryName; HMODULE hModule; WSAPROTOCOL_INFOW ProtocolInfo; PWINSOCK_MAPPING Mapping; diff --git a/reactos/lib/ws2_32/misc/catalog.c b/reactos/lib/ws2_32/misc/catalog.c index 56357a4f8bd..5eae1fdf571 100644 --- a/reactos/lib/ws2_32/misc/catalog.c +++ b/reactos/lib/ws2_32/misc/catalog.c @@ -59,12 +59,16 @@ PCATALOG_ENTRY CreateCatalogEntry( Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY)); if (!Provider) { - WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); return NULL; } ZeroMemory(Provider, sizeof(CATALOG_ENTRY)); + if (!RtlCreateUnicodeString(&Provider->LibraryName, LibraryName)) { + RtlFreeHeap(GlobalHeap, 0, Provider); + return NULL; + } + Provider->ReferenceCount = 1; InitializeCriticalSection(&Provider->Lock); @@ -164,8 +168,8 @@ PCATALOG_ENTRY LocateProviderById( if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) { //LeaveCriticalSection(&CatalogLock); - WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%s).\n", - Provider, Provider->LibraryName)); + WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%wZ).\n", + Provider, &Provider->LibraryName)); return Provider; } @@ -185,23 +189,33 @@ INT LoadProvider( { INT Status; - WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X) Name (%S).\n", - Provider, Provider->LibraryName)); + WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X) Name (%wZ).\n", + Provider, &Provider->LibraryName)); - if (!Provider->hModule) { + if (Provider->hModule == INVALID_HANDLE_VALUE) { /* DLL is not loaded so load it now */ - Provider->hModule = LoadLibrary(Provider->LibraryName); - - if (Provider->hModule) { - Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule, - "WSPStartup"); + Provider->hModule = LoadLibrary(Provider->LibraryName.Buffer); + if (Provider->hModule != INVALID_HANDLE_VALUE) { + Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress( + Provider->hModule, + "WSPStartup"); if (Provider->WSPStartup) { - WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n", Provider->WSPStartup)); - Status = Provider->WSPStartup(MAKEWORD(2, 2), + WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n", + Provider->WSPStartup)); + Status = Provider->WSPStartup( + MAKEWORD(2, 2), &Provider->WSPData, lpProtocolInfo, UpcallTable, &Provider->ProcTable); + + /* FIXME: Validate the procedure table */ + + WS_DbgPrint(MAX_TRACE, ("OFFSET2 (0x%X)\n", + FIELD_OFFSET(WSPPROC_TABLE, lpWSPSocket))); + + assert(Provider->ProcTable.lpWSPSocket); + } else Status = ERROR_BAD_PROVIDER; } else @@ -253,9 +267,9 @@ VOID CreateCatalog(VOID) #if 1 Provider = CreateCatalogEntry(L"msafd.dll"); if (!Provider) { - WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n")); - return; - } + WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n")); + return; + } /* Assume one Service Provider with id 1 */ Provider->ProtocolInfo.dwCatalogEntryId = 1; diff --git a/reactos/lib/ws2_32/misc/dllmain.c b/reactos/lib/ws2_32/misc/dllmain.c index c2ca003c4a2..d7b10771f7d 100644 --- a/reactos/lib/ws2_32/misc/dllmain.c +++ b/reactos/lib/ws2_32/misc/dllmain.c @@ -16,6 +16,7 @@ /* See debug.h for debug/trace constants */ DWORD DebugTraceLevel = MIN_TRACE; +//DWORD DebugTraceLevel = MAX_TRACE; #endif /* DBG */ @@ -185,22 +186,24 @@ WSASocketW( } Status = LoadProvider(Provider, lpProtocolInfo); - if (Status != NO_ERROR) { WSASetLastError(Status); - return INVALID_SOCKET; + return INVALID_SOCKET; } - WS_DbgPrint(MAX_TRACE, ("Calling WSPSocket at (0x%X).\n", Provider->ProcTable.lpWSPSocket)); + WS_DbgPrint(MAX_TRACE, ("Calling WSPSocket at (0x%X).\n", + Provider->ProcTable.lpWSPSocket)); - Socket = Provider->ProcTable.lpWSPSocket(af, + assert(Provider->ProcTable.lpWSPSocket); + + Socket = Provider->ProcTable.lpWSPSocket( + af, type, protocol, lpProtocolInfo, g, dwFlags, &Status); - if (Status != NO_ERROR) { WSASetLastError(Status); return INVALID_SOCKET; @@ -336,33 +339,28 @@ DllMain(HANDLE hInstDll, switch (dwReason) { case DLL_PROCESS_ATTACH: GlobalHeap = GetProcessHeap(); - //GlobalHeap = HeapCreate(0, 0, 0); - if (!GlobalHeap) { - WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); - return FALSE; - } CreateCatalog(); InitProviderHandleTable(); -/* FIXME: Causes trap - UpcallTable.lpWPUCloseEvent = WPUCloseEvent; - UpcallTable.lpWPUCloseSocketHandle = WPUCloseSocketHandle; - UpcallTable.lpWPUCreateEvent = WPUCreateEvent; - UpcallTable.lpWPUCreateSocketHandle = WPUCreateSocketHandle; - UpcallTable.lpWPUFDIsSet = WPUFDIsSet; - UpcallTable.lpWPUGetProviderPath = WPUGetProviderPath; - UpcallTable.lpWPUModifyIFSHandle = WPUModifyIFSHandle; - UpcallTable.lpWPUPostMessage = WPUPostMessage; - UpcallTable.lpWPUQueryBlockingCallback = WPUQueryBlockingCallback; - UpcallTable.lpWPUQuerySocketHandleContext = WPUQuerySocketHandleContext; - UpcallTable.lpWPUQueueApc = WPUQueueApc; - UpcallTable.lpWPUResetEvent = WPUResetEvent; - UpcallTable.lpWPUSetEvent = WPUSetEvent; - UpcallTable.lpWPUOpenCurrentThread = WPUOpenCurrentThread; - UpcallTable.lpWPUCloseThread = WPUCloseThread;*/ - /* Fall through to thread attachment handler */ + UpcallTable.lpWPUCloseEvent = WPUCloseEvent; + UpcallTable.lpWPUCloseSocketHandle = WPUCloseSocketHandle; + UpcallTable.lpWPUCreateEvent = WPUCreateEvent; + UpcallTable.lpWPUCreateSocketHandle = WPUCreateSocketHandle; + UpcallTable.lpWPUFDIsSet = WPUFDIsSet; + UpcallTable.lpWPUGetProviderPath = WPUGetProviderPath; + UpcallTable.lpWPUModifyIFSHandle = WPUModifyIFSHandle; + UpcallTable.lpWPUPostMessage = WPUPostMessage; + UpcallTable.lpWPUQueryBlockingCallback = WPUQueryBlockingCallback; + UpcallTable.lpWPUQuerySocketHandleContext = WPUQuerySocketHandleContext; + UpcallTable.lpWPUQueueApc = WPUQueueApc; + UpcallTable.lpWPUResetEvent = WPUResetEvent; + UpcallTable.lpWPUSetEvent = WPUSetEvent; + UpcallTable.lpWPUOpenCurrentThread = WPUOpenCurrentThread; + UpcallTable.lpWPUCloseThread = WPUCloseThread; + + /* Fall through to thread attachment handler */ case DLL_THREAD_ATTACH: p = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_THREAD_BLOCK)); @@ -370,7 +368,6 @@ DllMain(HANDLE hInstDll, WS_DbgPrint(MAX_TRACE, ("Thread block at 0x%X.\n", p)); if (!p) { - WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); return FALSE; } @@ -389,8 +386,6 @@ DllMain(HANDLE hInstDll, DestroyCatalog(); FreeProviderHandleTable(); - - //HeapDestroy(GlobalHeap); break; case DLL_THREAD_DETACH: diff --git a/reactos/lib/ws2_32/misc/handle.c b/reactos/lib/ws2_32/misc/handle.c index 3c75769cbe6..49c75d62e44 100644 --- a/reactos/lib/ws2_32/misc/handle.c +++ b/reactos/lib/ws2_32/misc/handle.c @@ -163,9 +163,8 @@ CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable, GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK)); if (!NewBlock) { - WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); return NULL; - } + } ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK)); InsertTailList(&HandleTable->Entry, &NewBlock->Entry); @@ -239,9 +238,8 @@ CloseProviderHandle(HANDLE Handle) Provider = DeleteProviderHandle(ProviderHandleTable, Handle); if (!Provider) { - WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); return FALSE; - } + } //LeaveCriticalSection(&ProviderHandleTableLock); @@ -257,11 +255,8 @@ InitProviderHandleTable(VOID) ProviderHandleTable = (PPROVIDER_HANDLE_BLOCK) HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK)); if (!ProviderHandleTable) { - WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n")); return FALSE; - } - - WS_DbgPrint(MIN_TRACE, ("ProviderHandleTable at 0x%X.\n", ProviderHandleTable)); + } ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK)); diff --git a/reactos/lib/ws2_32/misc/sndrcv.c b/reactos/lib/ws2_32/misc/sndrcv.c index d7fc982d08a..8b4a30db176 100644 --- a/reactos/lib/ws2_32/misc/sndrcv.c +++ b/reactos/lib/ws2_32/misc/sndrcv.c @@ -34,9 +34,16 @@ recvfrom( OUT LPSOCKADDR from, IN OUT INT FAR* fromlen) { - UNIMPLEMENTED + DWORD BytesReceived; + WSABUF WSABuf; - return 0; + WS_DbgPrint(MAX_TRACE, ("s (0x%X) buf (0x%X) len (0x%X) flags (0x%X).\n", + s, buf, len, flags)); + + WSABuf.len = len; + WSABuf.buf = (CHAR FAR*)buf; + + return WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL); } @@ -119,9 +126,29 @@ WSARecvFrom( IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { - UNIMPLEMENTED + PCATALOG_ENTRY Provider; + INT Errno; + INT Code; - return 0; + WS_DbgPrint(MAX_TRACE, ("Called.\n")); + + if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) { + WSASetLastError(WSAENOTSOCK); + return SOCKET_ERROR; + } + + assert(Provider->ProcTable.lpWSPRecvFrom); + + Code = Provider->ProcTable.lpWSPRecvFrom(s, lpBuffers, dwBufferCount, + lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, lpOverlapped, + lpCompletionRoutine, NULL /* lpThreadId */, &Errno); + + DereferenceProviderByPointer(Provider); + + if (Code == SOCKET_ERROR) + WSASetLastError(Errno); + + return Code; } @@ -178,6 +205,8 @@ WSASendTo( return SOCKET_ERROR; } + assert(Provider->ProcTable.lpWSPSendTo); + Code = Provider->ProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo, iToLen, lpOverlapped, lpCompletionRoutine, NULL /* lpThreadId */, &Errno); diff --git a/reactos/ntoskrnl/dbg/dbgctrl.c b/reactos/ntoskrnl/dbg/dbgctrl.c index 94e1abbc686..4d310ef6021 100644 --- a/reactos/ntoskrnl/dbg/dbgctrl.c +++ b/reactos/ntoskrnl/dbg/dbgctrl.c @@ -26,7 +26,10 @@ /* INCLUDES *****************************************************************/ #include +#include +#include +#define NDEBUG #include /* FUNCTIONS *****************************************************************/ @@ -39,5 +42,18 @@ NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode, ULONG OutputBufferLength, PULONG ReturnLength) { - UNIMPLEMENTED; + switch (ControlCode) { + case DebugGetTraceInformation: + case DebugSetInternalBreakpoint: + case DebugSetSpecialCalls: + case DebugClearSpecialCalls: + case DebugQuerySpecialCalls: + case DebugDbgBreakPoint: + break; + default: +#ifdef KDBG + LdrLoadUserModuleSymbols((PLDR_MODULE)InputBuffer); +#endif /* KDBG */ + } + return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/ex/work.c b/reactos/ntoskrnl/ex/work.c index 3c07d0de9b5..f13b8dee0a5 100644 --- a/reactos/ntoskrnl/ex/work.c +++ b/reactos/ntoskrnl/ex/work.c @@ -1,4 +1,4 @@ -/* $Id: work.c,v 1.9 2000/10/07 13:41:50 dwelch Exp $ +/* $Id: work.c,v 1.10 2001/06/04 11:26:11 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -15,6 +15,7 @@ #include +#define NDEBUG #include /* DEFINES *******************************************************************/ @@ -89,7 +90,7 @@ static NTSTATUS ExWorkerThreadEntryPoint(PVOID context) KernelMode, FALSE, NULL); - DPRINT1("Woke from wait\n"); + DPRINT("Woke from wait\n"); } } } diff --git a/reactos/ntoskrnl/include/internal/ldr.h b/reactos/ntoskrnl/include/internal/ldr.h index bba0fcec2af..07970eb2358 100644 --- a/reactos/ntoskrnl/include/internal/ldr.h +++ b/reactos/ntoskrnl/include/internal/ldr.h @@ -10,6 +10,7 @@ #include #include +#include NTSTATUS LdrLoadDriver ( @@ -81,5 +82,6 @@ VOID LdrInit1(VOID); VOID LdrInitDebug(PLOADER_MODULE Module, PWCH Name); +VOID LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject); #endif /* __INCLUDE_INTERNAL_LDR_H */ diff --git a/reactos/ntoskrnl/include/internal/module.h b/reactos/ntoskrnl/include/internal/module.h index 6f1a5e46dd8..388dcf21e79 100644 --- a/reactos/ntoskrnl/include/internal/module.h +++ b/reactos/ntoskrnl/include/internal/module.h @@ -5,24 +5,7 @@ #include #include #include - -#ifdef KDBG - -typedef struct _SYMBOL -{ - struct _SYMBOL *Next; - /* Address relative to module base address */ - ULONG RelativeAddress; - UNICODE_STRING Name; -} SYMBOL, *PSYMBOL; - -typedef struct _SYMBOL_TABLE -{ - ULONG SymbolCount; - PSYMBOL Symbols; -} SYMBOL_TABLE, *PSYMBOL_TABLE; - -#endif /* KDBG */ +#include typedef struct _MODULE_TEXT_SECTION { diff --git a/reactos/ntoskrnl/include/internal/pool.h b/reactos/ntoskrnl/include/internal/pool.h index 8fa6ff06bb3..000d93ea8ee 100644 --- a/reactos/ntoskrnl/include/internal/pool.h +++ b/reactos/ntoskrnl/include/internal/pool.h @@ -10,6 +10,4 @@ PVOID STDCALL ExAllocatePagedPoolWithTag (POOL_TYPE Type, ULONG size, ULONG Tag); -#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) - #endif /* __INTERNAL_POOL_H */ diff --git a/reactos/ntoskrnl/io/cleanup.c b/reactos/ntoskrnl/io/cleanup.c index 7691f405eb6..dd28ea328fb 100644 --- a/reactos/ntoskrnl/io/cleanup.c +++ b/reactos/ntoskrnl/io/cleanup.c @@ -252,7 +252,7 @@ VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost) if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE) { - ObDereferenceObject(FileObject); + //ObDereferenceObject(FileObject); } IoFreeIrp(Irp); diff --git a/reactos/ntoskrnl/io/create.c b/reactos/ntoskrnl/io/create.c index a7341e056ed..ddd2a1f2d22 100644 --- a/reactos/ntoskrnl/io/create.c +++ b/reactos/ntoskrnl/io/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.42 2001/05/13 13:35:37 chorns Exp $ +/* $Id: create.c,v 1.43 2001/06/04 11:26:11 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -406,7 +406,7 @@ IoCreateFile( } if (!NT_SUCCESS(Status)) { - DPRINT1("Failing create request with status %x\n", Status); + DPRINT("Failing create request with status %x\n", Status); ZwClose(*FileHandle); (*FileHandle) = 0; } diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 32ca3ac6956..8ee7c3c0a64 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -37,6 +37,7 @@ #include #include #include +#include #define NDEBUG #include @@ -98,7 +99,7 @@ static char *ExceptionTypeStrings[] = extern unsigned int _text_start__, _text_end__; STATIC BOOLEAN -print_address(PVOID address) +print_kernel_address(PVOID address) { #ifdef KDBG ULONG Offset; @@ -161,6 +162,97 @@ print_address(PVOID address) return(FALSE); } +STATIC BOOLEAN +print_user_address(PVOID address) +{ +#ifdef KDBG + ULONG Offset; + PSYMBOL Symbol, NextSymbol; + BOOLEAN Printed = FALSE; + ULONG NextAddress; +#endif /* KDBG */ + PLIST_ENTRY current_entry; + PLDR_MODULE current; + PEPROCESS CurrentProcess; + PPEB Peb = NULL; + + CurrentProcess = PsGetCurrentProcess(); + if (NULL != CurrentProcess) + { + Peb = CurrentProcess->Peb; + } + + if (NULL == Peb) + { + DbgPrint("<%x>", address); + return(TRUE); + } + + current_entry = Peb->Ldr->InLoadOrderModuleList.Flink; + + while (current_entry != &Peb->Ldr->InLoadOrderModuleList && + current_entry != NULL) + { + current = + CONTAINING_RECORD(current_entry, LDR_MODULE, InLoadOrderModuleList); + + if (address >= (PVOID)current->BaseAddress && + address < (PVOID)(current->BaseAddress + current->SizeOfImage)) + { +#ifdef KDBG + + Offset = (ULONG)(address - current->BaseAddress); + Symbol = current->Symbols.Symbols; + while (Symbol != NULL) + { + NextSymbol = Symbol->Next; + if (NextSymbol != NULL) + NextAddress = NextSymbol->RelativeAddress; + else + NextAddress = current->SizeOfImage; + + if ((Offset >= Symbol->RelativeAddress) && + (Offset < NextAddress)) + { + DbgPrint("<%wZ: %x (%wZ)>", + ¤t->BaseDllName, Offset, &Symbol->Name); + Printed = TRUE; + break; + } + Symbol = NextSymbol; + } + if (!Printed) + DbgPrint("<%wZ: %x>", ¤t->BaseDllName, Offset); + +#else /* KDBG */ + + DbgPrint("<%wZ: %x>", ¤t->BaseDllName, + address - current->BaseAddress); + +#endif /* KDBG */ + + return(TRUE); + } + + current_entry = current_entry->Flink; + } + return(FALSE); +} + +STATIC BOOLEAN +print_address(PVOID address) +{ + /* FIXME: There is a variable with this value somewhere...use it */ + if ((ULONG)address >= 0xc0000000) + { + return print_kernel_address(address); + } + else + { + return print_user_address(address); + } +} + #if 0 ULONG KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) @@ -244,7 +336,7 @@ KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) DbgPrint("\n"); __asm__("movl %%cr3,%0\n\t" : "=d" (cr3)); DbgPrint("CR2 %x CR3 %x ", Cr2, cr3); - DbgPrint("Proc: %x ",PsGetCurrentProcess()); + DbgPrint("Process: %x ",PsGetCurrentProcess()); if (PsGetCurrentProcess() != NULL) { DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId); @@ -305,14 +397,10 @@ KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2) Frame = (PULONG)Tf->Ebp; while (Frame != NULL) { - DbgPrint("%.8x ", Frame[1]); + print_address((PVOID)Frame[1]); Frame = (PULONG)Frame[0]; i++; } - if ((i % 8) != 0) - { - DbgPrint("\n"); - } /* * Kill the faulting task @@ -466,7 +554,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr) /* Use the address of the trap frame as approximation to the ring0 esp */ Esp0 = (ULONG)&Tf->Eip; - + /* Get CR2 */ __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 4d250516e74..ccfaead247a 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -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: main.c,v 1.95 2001/05/01 23:08:19 chorns Exp $ +/* $Id: main.c,v 1.96 2001/06/04 11:26:12 chorns Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c @@ -660,7 +660,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) * This should be done by the boot loader. */ strcpy (KeLoaderCommandLine, - "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN"); + "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=COM1"); strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine); KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine; diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 88d6dcd9af8..fbd033bb7ef 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.80 2001/05/26 10:05:40 jfilby Exp $ +/* $Id: loader.c,v 1.81 2001/06/04 11:26:12 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -341,7 +341,7 @@ ULONG HexL(PCHAR Buffer) PSYMBOL LdrpParseLine(PCHAR Line, PULONG TextBase, PBOOLEAN TextBaseValid, - PULONG FileAlignment) + PULONG Alignment) /* Line format: [ADDRESS] TYPE: @@ -386,19 +386,12 @@ PSYMBOL LdrpParseLine(PCHAR Line, else strncpy((char*)&Buffer, Line, Str - Line); - if ((Type == 'A') && (strcmp((char*)&Buffer, "__file_alignment__")) == 0) + if ((Type == 'A') && (strcmp((char*)&Buffer, "__section_alignment__")) == 0) { - *FileAlignment = Address; + *Alignment = Address; return NULL; } -/* if ((Type == 'A') && (strcmp((char*)&Buffer, "__image_base__")) == 0) - { - *TextBase = Address; - *TextBaseValid = TRUE; - return NULL; - }*/ - /* We only want symbols in the .text segment */ if ((Type != 't') && (Type != 'T')) return NULL; @@ -420,7 +413,7 @@ PSYMBOL LdrpParseLine(PCHAR Line, if (!(*TextBaseValid)) { - *TextBase = Address - *FileAlignment; + *TextBase = Address - *Alignment; *TextBaseValid = TRUE; } @@ -440,7 +433,7 @@ VOID LdrpLoadModuleSymbolsFromBuffer( BOOLEAN TextBaseValid; BOOLEAN Valid; ULONG TextBase = 0; - ULONG FileAlignment = 0; + ULONG Alignment = 0; CHAR Line[256]; ULONG Tmp; @@ -463,7 +456,7 @@ VOID LdrpLoadModuleSymbolsFromBuffer( Valid = FALSE; while (LdrpReadLine((PCHAR)&Line, 256, &Buffer, &Length)) { - Symbol = LdrpParseLine((PCHAR)&Line, &Tmp, &Valid, &FileAlignment); + Symbol = LdrpParseLine((PCHAR)&Line, &Tmp, &Valid, &Alignment); if ((Valid) && (!TextBaseValid)) { @@ -487,7 +480,61 @@ VOID LdrpLoadModuleSymbolsFromBuffer( } } -VOID LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) +VOID LdrpLoadUserModuleSymbolsFromBuffer( + PLDR_MODULE ModuleObject, + PVOID Buffer, + ULONG Length) +/* + Symbols must be sorted by address, e.g. + "nm --numeric-sort module.dll > module.sym" + */ +{ + PSYMBOL Symbol, CurrentSymbol = NULL; + BOOLEAN TextBaseValid; + BOOLEAN Valid; + ULONG TextBase = 0; + ULONG Alignment = 0; + CHAR Line[256]; + ULONG Tmp; + + if (ModuleObject->Symbols.SymbolCount > 0) + { + DPRINT("Symbols are already loaded for %wZ\n", &ModuleObject->BaseDllName); + return; + } + + ModuleObject->Symbols.SymbolCount = 0; + ModuleObject->Symbols.Symbols = NULL; + TextBaseValid = FALSE; + Valid = FALSE; + while (LdrpReadLine((PCHAR)&Line, 256, &Buffer, &Length)) + { + Symbol = LdrpParseLine((PCHAR)&Line, &Tmp, &Valid, &Alignment); + + if ((Valid) && (!TextBaseValid)) + { + TextBase = Tmp; + TextBaseValid = TRUE; + } + + if (Symbol != NULL) + { + Symbol->RelativeAddress -= TextBase; + + if (ModuleObject->Symbols.Symbols == NULL) + ModuleObject->Symbols.Symbols = Symbol; + else + CurrentSymbol->Next = Symbol; + + CurrentSymbol = Symbol; + + ModuleObject->Symbols.SymbolCount++; + } + } +} + +VOID LdrpLoadModuleSymbols( + PMODULE_OBJECT ModuleObject) { FILE_STANDARD_INFORMATION FileStdInfo; OBJECT_ATTRIBUTES ObjectAttributes; @@ -582,6 +629,101 @@ VOID LdrpLoadModuleSymbols(PMODULE_OBJECT ModuleObject) ExFreePool(FileBuffer); } +VOID LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject) +{ + FILE_STANDARD_INFORMATION FileStdInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + WCHAR TmpFileName[MAX_PATH]; + UNICODE_STRING Filename; + LPWSTR Start, Ext; + HANDLE FileHandle; + PVOID FileBuffer; + NTSTATUS Status; + ULONG Length; + + /* Get the path to the symbol store */ + wcscpy(TmpFileName, L"\\SystemRoot\\symbols\\"); + + /* Get the symbol filename from the module name */ + Start = wcsrchr(ModuleObject->BaseDllName.Buffer, L'\\'); + if (Start == NULL) + Start = ModuleObject->BaseDllName.Buffer; + else + Start++; + + Ext = wcsrchr(ModuleObject->BaseDllName.Buffer, L'.'); + if (Ext != NULL) + Length = Ext - Start; + else + Length = wcslen(Start); + + wcsncat(TmpFileName, Start, Length); + wcscat(TmpFileName, L".sym"); + RtlInitUnicodeString(&Filename, TmpFileName); + + /* Open the file */ + InitializeObjectAttributes(&ObjectAttributes, + &Filename, + 0, + NULL, + NULL); + + Status = ZwOpenFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + NULL, 0, 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("Could not open symbol file: %wZ\n", &Filename); + return; + } + + DbgPrint("Loading symbols from %wZ...\n", &Filename); + + /* Get the size of the file */ + Status = ZwQueryInformationFile(FileHandle, + NULL, + &FileStdInfo, + sizeof(FileStdInfo), + FileStandardInformation); + if (!NT_SUCCESS(Status)) + { + DPRINT("Could not get file size\n"); + return; + } + + /* Allocate nonpageable memory for symbol file */ + FileBuffer = ExAllocatePool(NonPagedPool, + FileStdInfo.EndOfFile.u.LowPart); + + if (FileBuffer == NULL) + { + DPRINT("Could not allocate memory for symbol file\n"); + return; + } + + /* Load file into memory chunk */ + Status = ZwReadFile(FileHandle, + 0, 0, 0, 0, + FileBuffer, + FileStdInfo.EndOfFile.u.LowPart, + 0, 0); + if (!NT_SUCCESS(Status)) + { + DPRINT("Could not read symbol file into memory\n"); + ExFreePool(FileBuffer); + return; + } + + ZwClose(FileHandle); + + LdrpLoadUserModuleSymbolsFromBuffer(ModuleObject, + FileBuffer, + FileStdInfo.EndOfFile.u.LowPart); + + ExFreePool(FileBuffer); +} + NTSTATUS LdrpFindModuleObject( PUNICODE_STRING ModuleName, PMODULE_OBJECT *ModuleObject) @@ -663,7 +805,7 @@ VOID LdrLoadAutoConfigDrivers (VOID) * */ LdrLoadAutoConfigDriver(L"vgamp.sys"); - +#if 0 /* * Minix filesystem driver */ @@ -678,7 +820,7 @@ VOID LdrLoadAutoConfigDrivers (VOID) * Named pipe filesystem driver */ LdrLoadAutoConfigDriver(L"npfs.sys"); - +#endif /* * Mouse drivers */ @@ -688,7 +830,7 @@ VOID LdrLoadAutoConfigDrivers (VOID) /* * Networking */ -#if 0 +#if 1 /* * NDIS library */ @@ -697,7 +839,7 @@ VOID LdrLoadAutoConfigDrivers (VOID) /* * Novell Eagle 2000 driver */ - LdrLoadAutoConfigDriver(L"ne2000.sys"); + //LdrLoadAutoConfigDriver(L"ne2000.sys"); /* * TCP/IP protocol driver @@ -707,7 +849,7 @@ VOID LdrLoadAutoConfigDrivers (VOID) /* * TDI test driver */ - LdrLoadAutoConfigDriver(L"tditest.sys"); + //LdrLoadAutoConfigDriver(L"tditest.sys"); /* * Ancillary Function Driver diff --git a/reactos/ntoskrnl/rtl/interlck.c b/reactos/ntoskrnl/rtl/interlck.c index 5dc9afe13f0..064123f2558 100644 --- a/reactos/ntoskrnl/rtl/interlck.c +++ b/reactos/ntoskrnl/rtl/interlck.c @@ -1,4 +1,4 @@ -/* $Id: interlck.c,v 1.6 1999/12/11 21:14:48 dwelch Exp $ +/* $Id: interlck.c,v 1.7 2001/06/04 11:26:12 chorns Exp $ * * reactos/ntoskrnl/rtl/interlck.c * @@ -27,11 +27,66 @@ LONG FASTCALL InterlockedDecrement(PLONG Addend) } #endif +#ifdef I386_FIX + +LONG FASTCALL InterlockedIncrement (PLONG Addend) +{ + *Addend = *Addend + 1; + return *Addend; +} + +LONG FASTCALL InterlockedDecrement (PLONG Addend) +{ + *Addend = *Addend - 1; + return *Addend; +} + +LONG +FASTCALL +InterlockedExchange ( + PLONG Target, + LONG Value + ) +{ + LONG Val = *Target; + *Target = Value; + return Val; +} + +LONG +FASTCALL +InterlockedExchangeAdd ( + PLONG Addend, + LONG Value + ) +{ + LONG Val = *Addend; + *Addend = Value; + return Val; +} + +PVOID +FASTCALL +InterlockedCompareExchange ( + PVOID * Destination, + PVOID Exchange, + PVOID Comperand + ) +{ + LONG Val = *((LONG*)Destination); + + if (*((LONG*)Destination) == (LONG)Comperand) { + *((LONG*)Destination) = (LONG)Exchange; + } + return (PVOID)Val; +} + +#else /* I386_FIX */ + /********************************************************************** * FASTCALL: @InterlockedIncrement@0 * STDCALL : _InterlockedIncrement@4 */ -#if 1 LONG FASTCALL InterlockedIncrement (PLONG Addend); /* * FUNCTION: Increments a caller supplied variable of type LONG as an @@ -53,7 +108,6 @@ __asm__("\n\t.global _InterlockedIncrement@4\n\t" "movl %ebp,%esp\n\t" "popl %ebp\n\t" "ret $4\n\t"); -#endif #if 0 /* @@ -80,7 +134,6 @@ __asm__( * FASTCALL: @InterlockedDecrement@0 * STDCALL : _InterlockedDecrement@4 */ -#if 1 LONG FASTCALL InterlockedDecrement(PLONG Addend); __asm__("\n\t.global _InterlockedDecrement@4\n\t" "_InterlockedDecrement@4:\n\t" @@ -95,12 +148,12 @@ __asm__("\n\t.global _InterlockedDecrement@4\n\t" "movl %ebp,%esp\n\t" "popl %ebp\n\t" "ret $4\n\t"); -#endif /********************************************************************** * FASTCALL: @InterlockedExchange@0 * STDCALL : _InterlockedExchange@8 */ + LONG FASTCALL InterlockedExchange ( @@ -229,5 +282,6 @@ __asm__( #endif */ +#endif /* I386_FIX */ /* EOF */