$(TARGETNAME).exe: $(OBJECTS) $(LIBS)
$(CC) $(OBJECTS) $(LIBS) -o $(TARGETNAME).exe
+ $(NM) --numeric-sort $(TARGETNAME).exe > $(TARGETNAME).sym
include ../../../rules.mak
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
+//DWORD DebugTraceLevel = DEBUG_ULTRA;
#endif /* DBG */
+NPAGED_LOOKASIDE_LIST BufferLookasideList;
+
+
NTSTATUS
STDCALL
AfdFileSystemControl(
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));
DriverObject->DriverUnload = (PDRIVER_UNLOAD)AfdUnload;
+/* ExInitializeNPagedLookasideList(
+ &BufferLookasideList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(AFD_BUFFER),
+ TAG('A', 'F', 'D', 'B'),
+ 0);*/
+
return STATUS_SUCCESS;
}
}
-
NTSTATUS AfdDispSendTo(
PIRP Irp,
PIO_STACK_LOCATION IrpSp)
PFILE_REPLY_SENDTO Reply;
PAFDFCB FCB;
PVOID SystemVirtualAddress;
+ PVOID DataBufferAddress;
ULONG BufferSize;
ULONG BytesCopied;
PMDL Mdl;
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)) {
BytesCopied = 0;
}
- AFD_DbgPrint(MAX_TRACE, ("KeGetCurrentIrql() 1 (%d).\n", KeGetCurrentIrql()));
-
Mdl = IoAllocateMdl(
SystemVirtualAddress, /* Virtual address of buffer */
BufferSize, /* Length of buffer */
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));
#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
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;
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;
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;
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;
}
{
NTSTATUS Status;
+ assert(FCB->TdiAddressObject);
+
+ /* Report errors for all types of sockets */
Status = TdiSetEventHandler(FCB->TdiAddressObject,
TDI_EVENT_ERROR,
(PVOID)AfdEventError,
(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,
break;
case SOCK_DGRAM:
+ case SOCK_RAW:
Status = TdiSetEventHandler(FCB->TdiAddressObject,
TDI_EVENT_RECEIVE_DATAGRAM,
NULL,
* 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);
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);
+
+ InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
- InitializeListHead(&NewFCB->CCBListHead);
+ InitializeListHead(&NewFCB->ReceiveQueue);
+ KeInitializeSpinLock(&NewFCB->ReceiveQueueLock);
- InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
+ 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;
}
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);
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;
-
- 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);*/
-
- RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
-
- AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
-
- /* Open address file now for raw sockets */
- if (FCB->SocketType == SOCK_RAW) {
- AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
-
- Status = TdiOpenAddressFile(
- &FCB->TdiDeviceName,
- &SocketInfo->Name,
- &FCB->TdiAddressObjectHandle,
- &FCB->TdiAddressObject);
-
- AFD_DbgPrint(MAX_TRACE, ("Status of open operation (0x%X).\n", Status));
-
- if (NT_SUCCESS(Status))
- FCB->State = SOCKET_STATE_BOUND;
+ FCB->CommandChannel = SocketInfo->CommandChannel;
+
+ 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;
+
+ if (RtlCreateUnicodeString(&FCB->TdiDeviceName, SocketInfo->TdiDeviceName.Buffer)) {
+
+ RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
+
+ AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
+
+ /* Open address file now for raw sockets */
+ if (FCB->SocketType == SOCK_RAW) {
+ AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
+
+ 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;
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;
}
PAFDFCB FCB;
PAFDCCB CCB;
- AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
+ AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
assert(DeviceObject);
assert(FileObject);
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;
- }
-
- /* Close TDI address file object */
- if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
- AfdDeregisterEventHandlers(FCB);
- TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
- FCB->TdiAddressObjectHandle = 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;
+ }
}
ExFreePool(FCB);
NTSTATUS AfdReadFile(
PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
- PVOID Buffer,
+ PVOID Buffer,
ULONG Length,
ULONG Offset)
/*
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;
}
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 */
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;
}
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));
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;
}
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;
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;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+ assert(FileObject);
+
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */
}
#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 */
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;
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));
+ TdiAddressSize = TdiAddressSizeFromName(Address);
-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);
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);
}
#endif
#endif
-CP
TdiBuildSendDatagram(Irp, /* I/O Request Packet */
DeviceObject, /* Device object */
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;
}
*BufferSize = Iosb.Information;
TdiBuildName(Address, ReturnInfo->RemoteAddress);
}
-CP
+
MmUnlockPages(Mdl);
-CP
+
IoFreeMdl(Mdl);
-CP
+
ExFreePool(ReceiveInfo);
return Status;
typedef struct _AFDFCB {
FsdNTRequiredFCB NTRequiredFCB;
LIST_ENTRY ListEntry;
+ BOOL CommandChannel;
PDEVICE_EXTENSION DeviceExt;
SHARE_ACCESS ShareAccess;
ULONG ReferenceCount;
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 */
#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;
#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 \
#endif /* i386 */
+extern NPAGED_LOOKASIDE_LIST BufferLookasideList;
+
/* Prototypes from dispatch.c */
NTSTATUS AfdDispBind(
PIRP Irp,
PIO_STACK_LOCATION IrpSp);
+NTSTATUS AfdDispSelect(
+ PIRP Irp,
+ PIO_STACK_LOCATION IrpSp);
+
/* Prototypes from event.c */
NTSTATUS AfdRegisterEventHandlers(
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(
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);
PNDIS_BUFFER Buffer,
ULONG DataSize);
+VOID RawIPReceive(
+ PNET_TABLE_ENTRY NTE,
+ PIP_PACKET IPPacket);
+
NTSTATUS RawIPStartup(
VOID);
*/
#include <tcpip.h>
#include <icmp.h>
+#include <rawip.h>
#include <checksum.h>
#include <routines.h>
#include <transmit.h>
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);
/* 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));
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);
}
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:
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;
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;
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);
break;
default:
/* Use raw IP for all other protocols */
+ AddrFile->Port = 0;
AddrFile->Send = RawIPSendDatagram;
break;
}
#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 */
PNDIS_BUFFER Buffer;
PNDIS_BUFFER NextBuffer;
+ if ((DebugTraceLevel & DEBUG_BUFFER) == 0) {
+ return;
+ }
+
if (!IPPacket) {
TI_DbgPrint(MIN_TRACE, ("Cannot display null packet.\n"));
return;
}
+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)
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
+#include <rawip.h>
#include <routines.h>
#include <datagram.h>
-#include <rawip.h>
+#include <address.h>
#include <pool.h>
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);
}
+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)
/*
}
-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,
&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 */
#define AFD_SOCKET_LENGTH (sizeof(AfdSocket) - 1)
typedef struct _AFD_SOCKET_INFORMATION {
+ BOOL CommandChannel;
INT AddressFamily;
INT SocketType;
INT Protocol;
#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;
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 */
/* EXECUTIVE ROUTINES ******************************************************/
+#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
+
VOID
FASTCALL
ExAcquireFastMutex (
+#include <ntos/kdbgsyms.h>
+#include "../ntoskrnl/include/internal/config.h"
+
typedef NTSTATUS (*PEPFUNC)(PPEB);
typedef struct _LDR_MODULE
HANDLE SectionHandle;
ULONG CheckSum;
ULONG TimeDateStamp;
+#ifdef KDBG
+ SYMBOL_TABLE Symbols;
+#endif /* KDBG */
} LDR_MODULE, *PLDR_MODULE;
NTSTATUS STDCALL
LdrUnloadDll (IN PVOID BaseAddress);
+VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject);
+
/* EOF */
--- /dev/null
+
+#ifndef __KDBGSYMS_H
+#define __KDBGSYMS_H
+
+#include <ddk/ntddk.h>
+
+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
+
} 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;
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
+//DWORD DebugTraceLevel = DEBUG_ULTRA;
#endif /* DBG */
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:
* 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"));
+ 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;
- EaShort = sizeof(FILE_FULL_EA_INFORMATION) +
- AFD_SOCKET_LENGTH +
- sizeof(AFD_SOCKET_INFORMATION);
+ AFD_DbgPrint(MAX_TRACE, ("Socket (0x%X) TdiDeviceName (%wZ)\n",
+ Socket, TdiDeviceName));
- EaLength = EaShort + TdiDeviceName->Length + sizeof(WCHAR);
+ AFD_DbgPrint(MAX_TRACE, ("Socket2 (0x%X) TdiDeviceName (%S)\n",
+ Socket, TdiDeviceName->Buffer));
- EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength);
- if (!EaInfo) {
- AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ EaShort = sizeof(FILE_FULL_EA_INFORMATION) +
+ AFD_SOCKET_LENGTH +
+ sizeof(AFD_SOCKET_INFORMATION);
- 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->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);
-
- 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);
-
- 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);
-
- if (!NT_SUCCESS(Status)) {
- AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n", (UINT)Status));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ EaLength = EaShort + TdiDeviceName->Length + sizeof(WCHAR);
+
+ EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength);
+ if (!EaInfo) {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
- *Socket = (SOCKET)FileHandle;
+ 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 = 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);
+
+ 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);
- return STATUS_SUCCESS;
+ 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);
+
+ if (!NT_SUCCESS(Status)) {
+ AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n",
+ (UINT)Status));
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ *Socket = (SOCKET)FileHandle;
+
+ 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:
* 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;
-
- AFD_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
- af, type, protocol));
-
- if (!lpProtocolInfo) {
- CP
- lpProtocolInfo = &ProtocolInfo;
- ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW));
-
- ProtocolInfo.iAddressFamily = af;
- ProtocolInfo.iSocketType = type;
- ProtocolInfo.iProtocol = protocol;
- }
+ 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));
+
+ if (!lpProtocolInfo) {
+ lpProtocolInfo = &ProtocolInfo;
+ ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW));
+
+ 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;
-
- Status = HelperDLL->EntryTable.lpWSHOpenSocket2(&AddressFamily,
- &SocketType,
- &Protocol,
- 0,
- 0,
- &TdiDeviceName,
- &HelperContext,
- &NotificationEvents);
- if (Status != NO_ERROR) {
- *lpErrno = Status;
- return INVALID_SOCKET;
- }
+ 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;
+ }
- NtStatus = OpenSocket(&Socket,
- AddressFamily,
- SocketType,
- Protocol,
- HelperContext,
- NotificationEvents,
- &TdiDeviceName);
-
- RtlFreeUnicodeString(&TdiDeviceName);
- if (!NT_SUCCESS(NtStatus)) {
- CP
- *lpErrno = RtlNtStatusToDosError(Status);
- return INVALID_SOCKET;
- }
+ NtStatus = OpenSocket(&Socket,
+ AddressFamily,
+ SocketType,
+ Protocol,
+ HelperContext,
+ NotificationEvents,
+ &TdiDeviceName);
+
+ 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:
* 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:
RtlCopyMemory(&Request.Name, name, sizeof(SOCKADDR));
- Status = NtDeviceIoControlFile((HANDLE)s,
+ Status = NtDeviceIoControlFile(
+ (HANDLE)s,
NULL,
NULL,
NULL,
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:
* 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",
- readfds, writefds, exceptfds));
+ PFILE_REQUEST_SELECT Request;
+ FILE_REPLY_SELECT Reply;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ DWORD Size;
+ DWORD ReadSize;
+ DWORD WriteSize;
+ DWORD ExceptSize;
+ PVOID Current;
- /* 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;
- }
+ AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n",
+ readfds, writefds, exceptfds));
- /* 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:
* Status of operation
*/
{
- HMODULE hWS2_32;
- INT Status;
-
- AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
+ HMODULE hWS2_32;
+ INT Status;
- //EnterCriticalSection(&InitCriticalSection);
+ AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
- Upcalls = UpcallTable;
-
- if (StartupCount == 0) {
- /* First time called */
+ EnterCriticalSection(&InitCriticalSection);
- Status = WSAVERNOTSUPPORTED;
+ Upcalls = UpcallTable;
- hWS2_32 = GetModuleHandle(L"ws2_32.dll");
+ if (StartupCount == 0) {
+ /* First time called */
- if (hWS2_32 != NULL) {
- lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST)
- GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest");
+ Status = WSAVERNOTSUPPORTED;
- 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);
-
- 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;
-
- lpWSPData->wVersion = MAKEWORD(2, 2);
- lpWSPData->wHighVersion = MAKEWORD(2, 2);
- }
+ LeaveCriticalSection(&InitCriticalSection);
+
+ 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);
+ }
- AFD_DbgPrint(MIN_TRACE, ("Status (%d).\n", Status));
+ AFD_DbgPrint(MAX_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:
* 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;
}
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:
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;
case DLL_PROCESS_DETACH:
DestroyHelperDLLDatabase();
- //HeapDestroy(GlobalHeap);
- //DeleteCriticalSection(&InitCriticalSection);
+ DeleteCriticalSection(&InitCriticalSection);
break;
}
#include <msafd.h>
#include <helpers.h>
-//CRITICAL_SECTION HelperDLLDatabaseLock;
+CRITICAL_SECTION HelperDLLDatabaseLock;
LIST_ENTRY HelperDLLDatabaseListHead;
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));
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);
if (HelperDLL->Mapping)
HeapFree(GlobalHeap, 0, HelperDLL->Mapping);
- //DeleteCriticalSection(&HelperDLL->Lock);
+ DeleteCriticalSection(&HelperDLL->Lock);
HeapFree(GlobalHeap, 0, HelperDLL);
PWSHELPER_DLL HelperDLL;
UINT i;
- //EnterCriticalSection(&HelperDLLDatabaseLock);
+ EnterCriticalSection(&HelperDLLDatabaseLock);
CurrentEntry = HelperDLLDatabaseListHead.Flink;
while (CurrentEntry != &HelperDLLDatabaseListHead) {
HelperDLL = CONTAINING_RECORD(CurrentEntry,
(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;
}
CurrentEntry = CurrentEntry->Flink;
}
- //LeaveCriticalSection(&HelperDLLDatabaseLock);
+ LeaveCriticalSection(&HelperDLLDatabaseLock);
AFD_DbgPrint(MAX_TRACE, ("Could not locate helper DLL.\n"));
} else
Status = NO_ERROR;
- AFD_DbgPrint(MIN_TRACE, ("Status (%d).\n", Status));
+ AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
return Status;
}
{
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;
CurrentEntry = NextEntry;
}
- //DeleteCriticalSection(&HelperDLLDatabaseLock);
+ DeleteCriticalSection(&HelperDLLDatabaseLock);
}
/* EOF */
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;
}
-/* $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
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,
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
&ExeModule->InLoadOrderModuleList);
+#ifdef KDBG
+ LdrLoadModuleSymbols(ExeModule);
+#endif /* KDBG */
+
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL);
ExeModule->EntryPoint = (ULONG)EntryPoint;
-/* $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
/* FUNCTIONS *****************************************************************/
+
+#ifdef KDBG
+
+VOID LdrLoadModuleSymbols(PLDR_MODULE ModuleObject)
+{
+ NtSystemDebugControl(
+ 0xffffffff,
+ (PVOID)ModuleObject,
+ 0,
+ NULL,
+ 0,
+ NULL);
+}
+
+#endif /* KDBG */
+
+
/***************************************************************************
* NAME LOCAL
* LdrAdjustDllName
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)
&Module->BaseDllName);
}
}
-
+
*BaseAddress = Module->BaseAddress;
return STATUS_SUCCESS;
}
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
CRITICAL_SECTION Lock;
- WCHAR LibraryName[MAX_PATH];
+ UNICODE_STRING LibraryName;
HMODULE hModule;
WSAPROTOCOL_INFOW ProtocolInfo;
PWINSOCK_MAPPING Mapping;
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);
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;
}
{
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
#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;
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
+//DWORD DebugTraceLevel = MAX_TRACE;
#endif /* DBG */
}
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));
+
+ assert(Provider->ProcTable.lpWSPSocket);
- Socket = Provider->ProcTable.lpWSPSocket(af,
+ Socket = Provider->ProcTable.lpWSPSocket(
+ af,
type,
protocol,
lpProtocolInfo,
g,
dwFlags,
&Status);
-
if (Status != NO_ERROR) {
WSASetLastError(Status);
return INVALID_SOCKET;
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));
WS_DbgPrint(MAX_TRACE, ("Thread block at 0x%X.\n", p));
if (!p) {
- WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
return FALSE;
}
DestroyCatalog();
FreeProviderHandleTable();
-
- //HeapDestroy(GlobalHeap);
break;
case DLL_THREAD_DETACH:
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);
Provider = DeleteProviderHandle(ProviderHandleTable, Handle);
if (!Provider) {
- WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
return FALSE;
- }
+ }
//LeaveCriticalSection(&ProviderHandleTableLock);
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));
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);
}
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;
}
return SOCKET_ERROR;
}
+ assert(Provider->ProcTable.lpWSPSendTo);
+
Code = Provider->ProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount,
lpNumberOfBytesSent, dwFlags, lpTo, iToLen, lpOverlapped,
lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
+#include <internal/config.h>
+#include <internal/ldr.h>
+#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
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;
}
-/* $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
#include <internal/ps.h>
+#define NDEBUG
#include <internal/debug.h>
/* DEFINES *******************************************************************/
KernelMode,
FALSE,
NULL);
- DPRINT1("Woke from wait\n");
+ DPRINT("Woke from wait\n");
}
}
}
#include <pe.h>
#include <internal/io.h>
+#include <ntdll/ldr.h>
NTSTATUS
LdrLoadDriver (
LdrInit1(VOID);
VOID
LdrInitDebug(PLOADER_MODULE Module, PWCH Name);
+VOID LdrLoadUserModuleSymbols(PLDR_MODULE ModuleObject);
#endif /* __INCLUDE_INTERNAL_LDR_H */
#include <ddk/ntddk.h>
#include <internal/config.h>
#include <pe.h>
-
-#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 <ntos/kdbgsyms.h>
typedef struct _MODULE_TEXT_SECTION
{
ULONG size,
ULONG Tag);
-#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
-
#endif /* __INTERNAL_POOL_H */
if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE)
{
- ObDereferenceObject(FileObject);
+ //ObDereferenceObject(FileObject);
}
IoFreeIrp(Irp);
-/* $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
}
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;
}
#include <internal/mm.h>
#include <internal/ps.h>
#include <internal/trap.h>
+#include <ntdll/ldr.h>
#define NDEBUG
#include <internal/debug.h>
extern unsigned int _text_start__, _text_end__;
STATIC BOOLEAN
-print_address(PVOID address)
+print_kernel_address(PVOID address)
{
#ifdef KDBG
ULONG Offset;
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)
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);
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
/* 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));
* 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
* 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;
-/* $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
PSYMBOL LdrpParseLine(PCHAR Line,
PULONG TextBase,
PBOOLEAN TextBaseValid,
- PULONG FileAlignment)
+ PULONG Alignment)
/*
Line format: [ADDRESS] <TYPE> <NAME>
TYPE:
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;
if (!(*TextBaseValid))
{
- *TextBase = Address - *FileAlignment;
+ *TextBase = Address - *Alignment;
*TextBaseValid = TRUE;
}
BOOLEAN TextBaseValid;
BOOLEAN Valid;
ULONG TextBase = 0;
- ULONG FileAlignment = 0;
+ ULONG Alignment = 0;
CHAR Line[256];
ULONG Tmp;
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))
{
}
}
-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;
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)
*
*/
LdrLoadAutoConfigDriver(L"vgamp.sys");
-
+#if 0
/*
* Minix filesystem driver
*/
* Named pipe filesystem driver
*/
LdrLoadAutoConfigDriver(L"npfs.sys");
-
+#endif
/*
* Mouse drivers
*/
/*
* Networking
*/
-#if 0
+#if 1
/*
* NDIS library
*/
/*
* Novell Eagle 2000 driver
*/
- LdrLoadAutoConfigDriver(L"ne2000.sys");
+ //LdrLoadAutoConfigDriver(L"ne2000.sys");
/*
* TCP/IP protocol driver
/*
* TDI test driver
*/
- LdrLoadAutoConfigDriver(L"tditest.sys");
+ //LdrLoadAutoConfigDriver(L"tditest.sys");
/*
* Ancillary Function Driver
-/* $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
*
}
#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
"movl %ebp,%esp\n\t"
"popl %ebp\n\t"
"ret $4\n\t");
-#endif
#if 0
/*
* 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"
"movl %ebp,%esp\n\t"
"popl %ebp\n\t"
"ret $4\n\t");
-#endif
/**********************************************************************
* FASTCALL: @InterlockedExchange@0
* STDCALL : _InterlockedExchange@8
*/
+
LONG
FASTCALL
InterlockedExchange (
#endif
*/
+#endif /* I386_FIX */
/* EOF */