Raw IP and ICMP fixes

More work on winsock stack (not usable yet though)
Support for loading symbols for user mode modules

svn path=/trunk/; revision=1941
This commit is contained in:
Casper Hornstrup 2001-06-04 11:26:13 +00:00
parent 3d24d1f443
commit 514cb6a689
46 changed files with 1719 additions and 681 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -13,6 +13,10 @@ NTSTATUS RawIPSendDatagram(
PNDIS_BUFFER Buffer,
ULONG DataSize);
VOID RawIPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
NTSTATUS RawIPStartup(
VOID);

View file

@ -9,6 +9,7 @@
*/
#include <tcpip.h>
#include <icmp.h>
#include <rawip.h>
#include <checksum.h>
#include <routines.h>
#include <transmit.h>
@ -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:

View file

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

View file

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

View file

@ -244,6 +244,7 @@ NTSTATUS FileOpenAddress(
break;
default:
/* Use raw IP for all other protocols */
AddrFile->Port = 0;
AddrFile->Send = RawIPSendDatagram;
break;
}

View file

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

View file

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

View file

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

View file

@ -8,9 +8,10 @@
* 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>
@ -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)
/*

View file

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

View file

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

View file

@ -3,6 +3,8 @@
/* EXECUTIVE ROUTINES ******************************************************/
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
VOID
FASTCALL
ExAcquireFastMutex (

View file

@ -1,3 +1,6 @@
#include <ntos/kdbgsyms.h>
#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 */

View file

@ -0,0 +1,22 @@
#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

View file

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

View file

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

View file

@ -10,7 +10,7 @@
#include <msafd.h>
#include <helpers.h>
//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 */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -26,7 +26,10 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/ldr.h>
#define NDEBUG
#include <internal/debug.h>
/* 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;
}

View file

@ -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 <internal/ps.h>
#define NDEBUG
#include <internal/debug.h>
/* DEFINES *******************************************************************/
@ -89,7 +90,7 @@ static NTSTATUS ExWorkerThreadEntryPoint(PVOID context)
KernelMode,
FALSE,
NULL);
DPRINT1("Woke from wait\n");
DPRINT("Woke from wait\n");
}
}
}

View file

@ -10,6 +10,7 @@
#include <pe.h>
#include <internal/io.h>
#include <ntdll/ldr.h>
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 */

View file

@ -5,24 +5,7 @@
#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
{

View file

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

View file

@ -252,7 +252,7 @@ VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost)
if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE)
{
ObDereferenceObject(FileObject);
//ObDereferenceObject(FileObject);
}
IoFreeIrp(Irp);

View file

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

View file

@ -37,6 +37,7 @@
#include <internal/mm.h>
#include <internal/ps.h>
#include <internal/trap.h>
#include <ntdll/ldr.h>
#define NDEBUG
#include <internal/debug.h>
@ -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)>",
&current->BaseDllName, Offset, &Symbol->Name);
Printed = TRUE;
break;
}
Symbol = NextSymbol;
}
if (!Printed)
DbgPrint("<%wZ: %x>", &current->BaseDllName, Offset);
#else /* KDBG */
DbgPrint("<%wZ: %x>", &current->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));

View file

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

View file

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

View file

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