mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Some work on winsock stack
svn path=/trunk/; revision=1514
This commit is contained in:
parent
2dd3473a90
commit
05ccbb2696
42 changed files with 5353 additions and 305 deletions
|
@ -16,41 +16,43 @@ include rules.mak
|
|||
# Required to run the system
|
||||
#
|
||||
COMPONENTS = iface_native iface_additional ntoskrnl
|
||||
DLLS = ntdll kernel32 crtdll advapi32 fmifs gdi32 secur32 user32 ws2_32 msvcrt
|
||||
DLLS = ntdll kernel32 crtdll advapi32 fmifs gdi32 secur32 user32 ws2_32 msafd msvcrt
|
||||
SUBSYS = smss win32k csrss
|
||||
|
||||
#
|
||||
# Select the server(s) you want to build
|
||||
#
|
||||
#SERVERS = posix linux os2
|
||||
SERVERS = win32
|
||||
# SERVERS = posix linux os2
|
||||
|
||||
#
|
||||
# Select the loader(s) you want to build
|
||||
#
|
||||
#LOADERS = boot dos
|
||||
LOADERS = dos
|
||||
# LOADERS = boot
|
||||
|
||||
#
|
||||
# Select the device drivers and filesystems you want
|
||||
#
|
||||
#DEVICE_DRIVERS = beep event floppy ide_test mouse sound test test1 parallel serial
|
||||
DEVICE_DRIVERS = vidport vga blue ide null floppy
|
||||
# DEVICE_DRIVERS = beep event floppy ide_test mouse sound test test1 parallel serial
|
||||
|
||||
#INPUT_DRIVERS = keyboard
|
||||
INPUT_DRIVERS = keyboard
|
||||
|
||||
FS_DRIVERS = vfat
|
||||
# FS_DRIVERS = minix ext2 template
|
||||
#FS_DRIVERS = vfat minix ext2 template
|
||||
FS_DRIVERS = vfat
|
||||
|
||||
# ndis tdi tcpip tditest wshtcpip
|
||||
NET_DRIVERS = ndis tcpip tditest wshtcpip
|
||||
#NET_DRIVERS = ndis tdi tcpip tditest wshtcpip afd
|
||||
NET_DRIVERS = ndis tcpip tditest wshtcpip afd
|
||||
|
||||
# ne2000
|
||||
#NET_DEVICE_DRIVERS = ne2000
|
||||
NET_DEVICE_DRIVERS = ne2000
|
||||
|
||||
#
|
||||
# system applications (required for startup)
|
||||
#
|
||||
#SYS_APPS = shell winlogon services
|
||||
SYS_APPS = shell winlogon services
|
||||
|
||||
APPS = args hello test cat bench apc shm lpc thread event file gditest \
|
||||
|
@ -58,8 +60,8 @@ APPS = args hello test cat bench apc shm lpc thread event file gditest \
|
|||
|
||||
# objdir
|
||||
|
||||
# ping
|
||||
NET_APPS = ping
|
||||
#NET_APPS = ping roshttpd
|
||||
NET_APPS = ping roshttpd
|
||||
|
||||
|
||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS) $(NET_DEVICE_DRIVERS)
|
||||
|
|
7
reactos/drivers/net/afd/afd.def
Normal file
7
reactos/drivers/net/afd/afd.def
Normal file
|
@ -0,0 +1,7 @@
|
|||
; Ancillary Function Driver - ReactOS Operating System
|
||||
|
||||
LIBRARY AFDTEST.SYS
|
||||
|
||||
EXPORTS
|
||||
|
||||
; EOF
|
38
reactos/drivers/net/afd/afd.rc
Normal file
38
reactos/drivers/net/afd/afd.rc
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "Ancillary Function Driver\0"
|
||||
VALUE "FileVersion", "0.0.0\0"
|
||||
VALUE "InternalName", "afd\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "afd.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
156
reactos/drivers/net/afd/afd/afd.c
Normal file
156
reactos/drivers/net/afd/afd/afd.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/afd.c
|
||||
* PURPOSE: MSAFD kernel mode module
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
NTSTATUS AfdFileSystemControl(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdDispatch(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: IOCTL dispatch routine
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Pointer to a device object for this driver
|
||||
* Irp = Pointer to a I/O request packet
|
||||
* RETURNS:
|
||||
* Status of the operation
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n",
|
||||
DeviceObject, Irp));
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
|
||||
case IOCTL_AFD_BIND:
|
||||
Status = AfdDispBind(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_LISTEN:
|
||||
Status = AfdDispListen(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_SENDTO:
|
||||
Status = AfdDispSendTo(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
case IOCTL_AFD_RECVFROM:
|
||||
Status = AfdDispRecvFrom(Irp, IrpSp);
|
||||
break;
|
||||
|
||||
default:
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unknown IOCTL (0x%X).\n",
|
||||
IrpSp->Parameters.DeviceIoControl.IoControlCode));
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status != STATUS_PENDING) {
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID AfdUnload(
|
||||
PDRIVER_OBJECT DriverObject)
|
||||
/*
|
||||
* FUNCTION: Unloads the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = Pointer to driver object created by the system
|
||||
*/
|
||||
{
|
||||
DbgPrint("Unloading Ancillary Function Driver\n");
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
#ifndef _MSC_VER
|
||||
STDCALL
|
||||
#endif
|
||||
DriverEntry(
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Called by the system to initialize the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName;
|
||||
NTSTATUS Status;
|
||||
|
||||
DbgPrint("Ancillary Function Driver\n");
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Afd");
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_NAMED_PIPE,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Could not create device (0x%X).\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
DeviceObject->Flags |= DO_DIRECT_IO;
|
||||
|
||||
DeviceExt = DeviceObject->DeviceExtension;
|
||||
KeInitializeSpinLock(&DeviceExt->FCBListLock);
|
||||
InitializeListHead(&DeviceExt->FCBListHead);
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = AfdRead;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = AfdWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AfdFileSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AfdDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AfdClose;
|
||||
|
||||
DriverObject->DriverUnload = (PDRIVER_UNLOAD)AfdUnload;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
186
reactos/drivers/net/afd/afd/dispatch.c
Normal file
186
reactos/drivers/net/afd/afd/dispatch.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/dispatch.c
|
||||
* PURPOSE: File object dispatch functions
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
NTSTATUS AfdDispBind(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
/*
|
||||
* FUNCTION: Binds to an address
|
||||
* 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_BIND Request;
|
||||
PFILE_REPLY_BIND Reply;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_BIND)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_BIND))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
switch (Request->Name.sa_family) {
|
||||
case AF_INET:
|
||||
Status = TdiOpenAddressFileIPv4(&FCB->TdiDeviceName,
|
||||
&Request->Name,
|
||||
&FCB->TdiAddressObjectHandle,
|
||||
&FCB->TdiAddressObject);
|
||||
break;
|
||||
default:
|
||||
AFD_DbgPrint(MIN_TRACE, ("Bad address family (%d).\n", Request->Name.sa_family));
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status)) {
|
||||
AfdRegisterEventHandlers(FCB);
|
||||
FCB->State = SOCKET_STATE_BOUND;
|
||||
}
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdDispListen(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
/*
|
||||
* FUNCTION: Starts listening for connections
|
||||
* 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_LISTEN Request;
|
||||
PFILE_REPLY_LISTEN Reply;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS AfdDispSendTo(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
/*
|
||||
* FUNCTION: Sends data to an address
|
||||
* 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_SENDTO Request;
|
||||
PFILE_REPLY_SENDTO Reply;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_SENDTO)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_SENDTO))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
Status = TdiSend(FCB->TdiAddressObject, Request);
|
||||
|
||||
Reply->NumberOfBytesSent = Request->ToLen;
|
||||
Reply->Status = Status;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdDispRecvFrom(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
/*
|
||||
* FUNCTION: Receives data from an address
|
||||
* 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_RECVFROM Request;
|
||||
PFILE_REPLY_RECVFROM Reply;
|
||||
PAFDFCB FCB;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if ((InputBufferLength >= sizeof(FILE_REQUEST_RECVFROM)) &&
|
||||
(OutputBufferLength >= sizeof(FILE_REPLY_RECVFROM))) {
|
||||
FCB = IrpSp->FileObject->FsContext;
|
||||
|
||||
Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
|
||||
Reply = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
|
||||
} else
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
203
reactos/drivers/net/afd/afd/event.c
Normal file
203
reactos/drivers/net/afd/afd/event.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/event.c
|
||||
* PURPOSE: TDI event handlers
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
NTSTATUS AfdEventError(
|
||||
IN PVOID TdiEventContext,
|
||||
IN NTSTATUS Status)
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdEventDisconnect(
|
||||
IN PVOID TdiEventContext,
|
||||
IN CONNECTION_CONTEXT ConnectionContext,
|
||||
IN LONG DisconnectDataLength,
|
||||
IN PVOID DisconnectData,
|
||||
IN LONG DisconnectInformationLength,
|
||||
IN PVOID DisconnectInformation,
|
||||
IN ULONG DisconnectFlags)
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdEventReceive(
|
||||
IN PVOID TdiEventContext,
|
||||
IN CONNECTION_CONTEXT ConnectionContext,
|
||||
IN ULONG ReceiveFlags,
|
||||
IN ULONG BytesIndicated,
|
||||
IN ULONG BytesAvailable,
|
||||
OUT ULONG *BytesTaken,
|
||||
IN PVOID Tsdu,
|
||||
OUT PIRP *IoRequestPacket)
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
TDI_STATUS ClientEventReceiveExpedited(
|
||||
IN PVOID TdiEventContext,
|
||||
IN CONNECTION_CONTEXT ConnectionContext,
|
||||
IN ULONG ReceiveFlags,
|
||||
IN ULONG BytesIndicated,
|
||||
IN ULONG BytesAvailable,
|
||||
OUT ULONG *BytesTaken,
|
||||
IN PVOID Tsdu,
|
||||
OUT PIRP *IoRequestPacket)
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS ClientEventChainedReceive(
|
||||
IN PVOID TdiEventContext,
|
||||
IN CONNECTION_CONTEXT ConnectionContext,
|
||||
IN ULONG ReceiveFlags,
|
||||
IN ULONG ReceiveLength,
|
||||
IN ULONG StartingOffset,
|
||||
IN PMDL Tsdu,
|
||||
IN PVOID TsduDescriptor)
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
AFD_DbgPrint(MID_TRACE, ("Receiving (%d) bytes from (0x%X).\n",
|
||||
BytesAvailable, *(PULONG)SourceAddress));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdRegisterEventHandlers(
|
||||
PAFDFCB FCB)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_ERROR,
|
||||
(PVOID)AfdEventError,
|
||||
(PVOID)FCB);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
switch (FCB->SocketType) {
|
||||
case SOCK_STREAM:
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_DISCONNECT,
|
||||
(PVOID)AfdEventDisconnect,
|
||||
(PVOID)FCB);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_RECEIVE,
|
||||
(PVOID)AfdEventReceive,
|
||||
(PVOID)FCB);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_RECEIVE_EXPEDITED,
|
||||
(PVOID)ClientEventReceiveExpedited,
|
||||
(PVOID)FCB);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_CHAINED_RECEIVE,
|
||||
(PVOID)ClientEventChainedReceive,
|
||||
(PVOID)FCB);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
break;
|
||||
case SOCK_DGRAM:
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_RECEIVE_DATAGRAM,
|
||||
(PVOID)AfdEventReceiveDatagramHandler,
|
||||
(PVOID)FCB);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdDeregisterEventHandlers(
|
||||
PAFDFCB FCB)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_ERROR,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
switch (FCB->SocketType) {
|
||||
case SOCK_STREAM:
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_DISCONNECT,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_RECEIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_RECEIVE_EXPEDITED,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_CHAINED_RECEIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
break;
|
||||
|
||||
case SOCK_DGRAM:
|
||||
Status = TdiSetEventHandler(FCB->TdiAddressObject,
|
||||
TDI_EVENT_RECEIVE_DATAGRAM,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) { return Status; }
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
202
reactos/drivers/net/afd/afd/opnclose.c
Normal file
202
reactos/drivers/net/afd/afd/opnclose.c
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/opnclose.c
|
||||
* PURPOSE: File object creation and destruction
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
PAFDFCB AfdInitializeFCB(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_OBJECT FileObject OPTIONAL)
|
||||
/*
|
||||
* FUNCTION: Allocates and initializes a File Control Block structure
|
||||
*/
|
||||
{
|
||||
PAFDFCB NewFCB;
|
||||
|
||||
NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
|
||||
if (!NewFCB)
|
||||
return NULL;
|
||||
|
||||
RtlZeroMemory(NewFCB, sizeof(AFDFCB));
|
||||
|
||||
ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource);
|
||||
ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource);
|
||||
|
||||
NewFCB->DeviceExt = DeviceExt;
|
||||
NewFCB->ReferenceCount = 1;
|
||||
NewFCB->OpenHandleCount = 1;
|
||||
|
||||
NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
|
||||
NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
InitializeListHead(&NewFCB->CCBListHead);
|
||||
|
||||
InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
|
||||
|
||||
if (FileObject)
|
||||
FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB;
|
||||
|
||||
return NewFCB;
|
||||
}
|
||||
|
||||
|
||||
PAFDCCB AfdInitializeCCB(
|
||||
PAFDFCB FCB,
|
||||
PFILE_OBJECT FileObject)
|
||||
/*
|
||||
* FUNCTION: Allocates and initializes a Context Control Block structure
|
||||
*/
|
||||
{
|
||||
PAFDCCB NewCCB;
|
||||
|
||||
NewCCB = ExAllocatePool(NonPagedPool, sizeof(AFDCCB));
|
||||
if (!NewCCB)
|
||||
return NULL;
|
||||
|
||||
RtlZeroMemory(NewCCB, sizeof(AFDCCB));
|
||||
|
||||
NewCCB->FileObject = FileObject;
|
||||
|
||||
FileObject->FsContext2 = (PVOID)NewCCB;
|
||||
|
||||
InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
|
||||
|
||||
return NewCCB;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdCreate(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PAFD_SOCKET_INFORMATION SocketInfo;
|
||||
PFILE_FULL_EA_INFORMATION EaInfo;
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
PTA_ADDRESS Address;
|
||||
NTSTATUS Status;
|
||||
ULONG EaLength;
|
||||
PAFDFCB FCB;
|
||||
PAFDCCB CCB;
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
|
||||
|
||||
DeviceExt = DeviceObject->DeviceExtension;
|
||||
|
||||
EaInfo = Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
/* Parameter check */
|
||||
if (!EaInfo) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + EaInfo->EaNameLength);
|
||||
|
||||
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
|
||||
EaInfo->EaNameLength +
|
||||
EaInfo->EaValueLength;
|
||||
|
||||
if (EaLength < sizeof(FILE_FULL_EA_INFORMATION) +
|
||||
AFD_SOCKET_LENGTH + sizeof(AFD_SOCKET_INFORMATION)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("EA information has invalid length.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) length is (%d).\n", EaInfo, EaLength));
|
||||
|
||||
/* FIXME: File/socket could already be open, do a search for it */
|
||||
|
||||
FCB = AfdInitializeFCB(DeviceExt, FileObject);
|
||||
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;
|
||||
RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
|
||||
} else {
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
/* FIXME: Cleanup */
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Leaving. Status (0x%X).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdClose(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
NTSTATUS Status;
|
||||
PAFDFCB FCB;
|
||||
PAFDCCB CCB;
|
||||
|
||||
FCB = FileObject->FsContext;
|
||||
CCB = FileObject->FsContext2;
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
|
||||
|
||||
switch (IrpSp->MajorFunction) {
|
||||
/* Close a file object */
|
||||
case IRP_MJ_CLOSE:
|
||||
FCB->ReferenceCount--;
|
||||
if (FCB->ReferenceCount < 1) {
|
||||
/* Close TDI connection file object */
|
||||
if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
|
||||
TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
|
||||
FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* Close TDI address file object */
|
||||
if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
|
||||
AfdDeregisterEventHandlers(FCB);
|
||||
TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
|
||||
FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ExFreePool(FCB);
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
/* Release resources bound to a file object */
|
||||
case IRP_MJ_CLEANUP:
|
||||
FCB->OpenHandleCount--;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
|
||||
ExFreePool(CCB);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
99
reactos/drivers/net/afd/afd/rdwr.c
Normal file
99
reactos/drivers/net/afd/afd/rdwr.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/rdwr.c
|
||||
* PURPOSE: File object read/write functions
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
NTSTATUS AfdReadFile(
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_OBJECT FileObject,
|
||||
PVOID Buffer,
|
||||
ULONG Length,
|
||||
ULONG Offset)
|
||||
/*
|
||||
* FUNCTION: Reads data from a file
|
||||
*/
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdRead(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
#if 1
|
||||
UNIMPLEMENTED
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
#else
|
||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION IoSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IoSp->FileObject;
|
||||
NTSTATUS Status;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG Offset;
|
||||
|
||||
Length = IoSp->Parameters.Read.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = IoSp->Parameters.Read.ByteOffset.u.LowPart;
|
||||
|
||||
Status = AfdReadFile(DeviceExt, FileObject, Buffer, Length, Offset);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS AfdWrite(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION IoSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = IoSp->FileObject;
|
||||
NTSTATUS Status;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG Offset;
|
||||
PAFDFCB FCB;
|
||||
PAFDCCB CCB;
|
||||
|
||||
FCB = FileObject->FsContext;
|
||||
CCB = FileObject->FsContext2;
|
||||
|
||||
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",
|
||||
Length, Buffer, Offset));
|
||||
|
||||
/* FIXME: Connectionless communication only */
|
||||
//Status = TdiSendDatagram(FCB->TdiAddressObject, WH2N(2000), 0x7F000001, Buffer, Length);
|
||||
//if (!NT_SUCCESS(Status))
|
||||
Length = 0;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Leaving.\n"));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
903
reactos/drivers/net/afd/afd/tdi.c
Normal file
903
reactos/drivers/net/afd/afd/tdi.c
Normal file
|
@ -0,0 +1,903 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: afd/tdi.c
|
||||
* PURPOSE: Transport Driver Interface functions
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <afd.h>
|
||||
|
||||
inline DWORD TdiAddressSizeFromName(
|
||||
LPSOCKADDR Name)
|
||||
/*
|
||||
* FUNCTION: Returns the size of a TDI style address equivalent to a
|
||||
* WinSock style name
|
||||
* ARGUMENTS:
|
||||
* Name = WinSock style name
|
||||
* RETURNS:
|
||||
* Size of TDI style address, 0 if Name is not valid
|
||||
*/
|
||||
{
|
||||
switch (Name->sa_family) {
|
||||
case AF_INET:
|
||||
return sizeof(TA_ADDRESS_IP);
|
||||
/* FIXME: More to come */
|
||||
}
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VOID TdiBuildAddressIPv4(
|
||||
PTA_ADDRESS_IP Address,
|
||||
LPSOCKADDR Name)
|
||||
/*
|
||||
* FUNCTION: Builds an IPv4 TDI style address
|
||||
* ARGUMENTS:
|
||||
* Address = Address of buffer to place TDI style IPv4 address
|
||||
* Name = Pointer to WinSock style IPv4 name
|
||||
*/
|
||||
{
|
||||
Address->TAAddressCount = 1;
|
||||
Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
|
||||
Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
|
||||
Address->Address[0].Address[0].sin_port = ((LPSOCKADDR_IN)Name)->sin_port;
|
||||
Address->Address[0].Address[0].in_addr = ((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr;
|
||||
}
|
||||
|
||||
|
||||
VOID TdiBuildAddress(
|
||||
PTA_ADDRESS Address,
|
||||
LPSOCKADDR Name)
|
||||
/*
|
||||
* FUNCTION: Builds a TDI style address
|
||||
* ARGUMENTS:
|
||||
* Address = Address of buffer to place TDI style address
|
||||
* Name = Pointer to WinSock style name
|
||||
*/
|
||||
{
|
||||
switch (Name->sa_family) {
|
||||
case AF_INET:
|
||||
TdiBuildAddressIPv4((PTA_ADDRESS_IP)Address, Name);
|
||||
break;
|
||||
/* FIXME: More to come */
|
||||
default:
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unknown address family (%d).\n", Name->sa_family));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID TdiBuildName(
|
||||
LPSOCKADDR Name,
|
||||
PTA_ADDRESS Address)
|
||||
/*
|
||||
* FUNCTION: Builds a WinSock style address
|
||||
* ARGUMENTS:
|
||||
* Name = Address of buffer to place WinSock style name
|
||||
* Address = Pointer to TDI style address
|
||||
*/
|
||||
{
|
||||
switch (Address->AddressType) {
|
||||
case TDI_ADDRESS_TYPE_IP:
|
||||
Name->sa_family = AF_INET;
|
||||
((LPSOCKADDR_IN)Name)->sin_port =
|
||||
((PTDI_ADDRESS_IP)&Address->Address[0])->sin_port;
|
||||
((LPSOCKADDR_IN)Name)->sin_addr.S_un.S_addr =
|
||||
((PTDI_ADDRESS_IP)&Address->Address[0])->in_addr;
|
||||
return;
|
||||
/* FIXME: More to come */
|
||||
}
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unknown TDI address type (%d).\n", Address->AddressType));
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiCall(
|
||||
PIRP Irp,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
BOOLEAN CanCancel,
|
||||
PKEVENT StopEvent)
|
||||
/*
|
||||
* FUNCTION: Calls a transport driver device
|
||||
* ARGUMENTS:
|
||||
* Irp = Pointer to I/O Request Packet
|
||||
* DeviceObject = Pointer to device object to call
|
||||
* IoStatusBlock = Address of buffer with I/O status block
|
||||
* CanCancel = TRUE if the IRP can be cancelled, FALSE if not
|
||||
* StopEvent = If CanCancel is TRUE, a pointer to an event handle
|
||||
* that, when signalled will cause the request to abort
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
* NOTES:
|
||||
* All requests are completed synchronously. A request can be cancelled
|
||||
*/
|
||||
{
|
||||
KEVENT Event;
|
||||
PKEVENT Events[2];
|
||||
NTSTATUS Status;
|
||||
Events[0] = StopEvent;
|
||||
Events[1] = &Event;
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp->UserEvent = &Event;
|
||||
Irp->UserIosb = IoStatusBlock;
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING) {
|
||||
if (CanCancel) {
|
||||
Status = KeWaitForMultipleObjects(2,
|
||||
(PVOID)&Events,
|
||||
WaitAny,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (KeReadStateEvent(StopEvent) != 0) {
|
||||
if (IoCancelIrp(Irp)) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Cancelled IRP.\n"));
|
||||
} else {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Could not cancel IRP.\n"));
|
||||
}
|
||||
return STATUS_CANCELLED;
|
||||
}
|
||||
} else
|
||||
Status = KeWaitForSingleObject(&Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Status (0x%X) Iosb.Status (0x%X).\n", Status, IoStatusBlock->Status));
|
||||
|
||||
return IoStatusBlock->Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiOpenDevice(
|
||||
PUNICODE_STRING DeviceName,
|
||||
ULONG EaLength,
|
||||
PFILE_FULL_EA_INFORMATION EaInfo,
|
||||
PHANDLE Handle,
|
||||
PFILE_OBJECT *Object)
|
||||
/*
|
||||
* FUNCTION: Opens a device
|
||||
* ARGUMENTS:
|
||||
* DeviceName = Pointer to counted string with name of device
|
||||
* EaLength = Length of EA information
|
||||
* EaInfo = Pointer to buffer with EA information
|
||||
* Handle = Address of buffer to place device handle
|
||||
* Object = Address of buffer to place device object
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
OBJECT_ATTRIBUTES Attr;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
|
||||
InitializeObjectAttributes(&Attr, /* Attribute buffer */
|
||||
DeviceName, /* Device name */
|
||||
OBJ_CASE_INSENSITIVE, /* Attributes */
|
||||
NULL, /* Root directory */
|
||||
NULL); /* Security descriptor */
|
||||
|
||||
Status = ZwCreateFile(Handle, /* Return file handle */
|
||||
GENERIC_READ | GENERIC_WRITE, /* Desired access */
|
||||
&Attr, /* Object attributes */
|
||||
&Iosb, /* IO status */
|
||||
0, /* Initial allocation size */
|
||||
FILE_ATTRIBUTE_NORMAL, /* File attributes */
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, /* Share access */
|
||||
FILE_OPEN_IF, /* Create disposition */
|
||||
0, /* Create options */
|
||||
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 */
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status));
|
||||
ZwClose(*Handle);
|
||||
}
|
||||
} else {
|
||||
AFD_DbgPrint(MIN_TRACE, ("ZwCreateFile() failed with status (0x%X)\n", Status));
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiCloseDevice(
|
||||
HANDLE Handle,
|
||||
PFILE_OBJECT FileObject)
|
||||
{
|
||||
if (FileObject)
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
if (Handle)
|
||||
ZwClose(Handle);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiOpenAddressFileIPv4(
|
||||
PUNICODE_STRING DeviceName,
|
||||
LPSOCKADDR Name,
|
||||
PHANDLE AddressHandle,
|
||||
PFILE_OBJECT *AddressObject)
|
||||
/*
|
||||
* FUNCTION: Opens an IPv4 address file object
|
||||
* ARGUMENTS:
|
||||
* DeviceName = Pointer to counted string with name of device
|
||||
* Name = Pointer to socket name (IPv4 address family)
|
||||
* AddressHandle = Address of buffer to place address file handle
|
||||
* AddressObject = Address of buffer to place address file object
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PFILE_FULL_EA_INFORMATION EaInfo;
|
||||
PTA_ADDRESS_IP Address;
|
||||
NTSTATUS Status;
|
||||
ULONG EaLength;
|
||||
|
||||
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
|
||||
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"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(EaInfo, EaLength);
|
||||
EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
|
||||
RtlCopyMemory(EaInfo->EaName,
|
||||
TdiTransportAddress,
|
||||
TDI_TRANSPORT_ADDRESS_LENGTH);
|
||||
EaInfo->EaValueLength = sizeof(TA_ADDRESS_IP);
|
||||
Address = (PTA_ADDRESS_IP)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH);
|
||||
TdiBuildAddressIPv4(Address, Name);
|
||||
|
||||
Status = TdiOpenDevice(DeviceName,
|
||||
EaLength,
|
||||
EaInfo,
|
||||
AddressHandle,
|
||||
AddressObject);
|
||||
ExFreePool(EaInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiSetEventHandler(
|
||||
PFILE_OBJECT FileObject,
|
||||
LONG EventType,
|
||||
PVOID Handler,
|
||||
PVOID Context)
|
||||
/*
|
||||
* FUNCTION: Sets or resets an event handler
|
||||
* ARGUMENTS:
|
||||
* FileObject = Pointer to file object
|
||||
* EventType = Event code
|
||||
* Handler = Event handler to be called when the event occurs
|
||||
* Context = Context input to handler when the event occurs
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
* NOTES:
|
||||
* Specify NULL for Handler to stop calling event handler
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, /* Sub function */
|
||||
DeviceObject, /* Device object */
|
||||
FileObject, /* File object */
|
||||
NULL, /* Event */
|
||||
NULL); /* Status */
|
||||
if (!Irp) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
TdiBuildSetEventHandler(Irp,
|
||||
DeviceObject,
|
||||
FileObject,
|
||||
NULL,
|
||||
NULL,
|
||||
EventType,
|
||||
Handler,
|
||||
Context);
|
||||
|
||||
Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiQueryDeviceControl(
|
||||
PFILE_OBJECT FileObject,
|
||||
ULONG IoControlCode,
|
||||
PVOID InputBuffer,
|
||||
ULONG InputBufferLength,
|
||||
PVOID OutputBuffer,
|
||||
ULONG OutputBufferLength,
|
||||
PULONG Return)
|
||||
/*
|
||||
* FUNCTION: Queries a device for information
|
||||
* ARGUMENTS:
|
||||
* FileObject = Pointer to file object
|
||||
* IoControlCode = I/O control code
|
||||
* InputBuffer = Pointer to buffer with input data
|
||||
* InputBufferLength = Length of InputBuffer
|
||||
* OutputBuffer = Address of buffer to place output data
|
||||
* OutputBufferLength = Length of OutputBuffer
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
|
||||
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
|
||||
DeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferLength,
|
||||
OutputBuffer,
|
||||
OutputBufferLength,
|
||||
FALSE,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!Irp) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("IoBuildDeviceIoControlRequest() failed.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
|
||||
if (Return)
|
||||
*Return = Iosb.Information;
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiQueryInformationEx(
|
||||
PFILE_OBJECT FileObject,
|
||||
ULONG Entity,
|
||||
ULONG Instance,
|
||||
ULONG Class,
|
||||
ULONG Type,
|
||||
ULONG Id,
|
||||
PVOID OutputBuffer,
|
||||
PULONG OutputLength)
|
||||
/*
|
||||
* FUNCTION: Extended query for information
|
||||
* ARGUMENTS:
|
||||
* FileObject = Pointer to file object
|
||||
* Entity = Entity
|
||||
* Instance = Instance
|
||||
* Class = Entity class
|
||||
* Type = Entity type
|
||||
* Id = Entity id
|
||||
* OutputBuffer = Address of buffer to place data
|
||||
* OutputLength = Address of buffer with length of OutputBuffer (updated)
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;
|
||||
|
||||
RtlZeroMemory(&QueryInfo, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
|
||||
QueryInfo.ID.toi_entity.tei_entity = Entity;
|
||||
QueryInfo.ID.toi_entity.tei_instance = Instance;
|
||||
QueryInfo.ID.toi_class = Class;
|
||||
QueryInfo.ID.toi_type = Type;
|
||||
QueryInfo.ID.toi_id = Id;
|
||||
|
||||
return TdiQueryDeviceControl(FileObject, /* Transport/connection object */
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX, /* Control code */
|
||||
&QueryInfo, /* Input buffer */
|
||||
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), /* Input buffer length */
|
||||
OutputBuffer, /* Output buffer */
|
||||
*OutputLength, /* Output buffer length */
|
||||
OutputLength); /* Return information */
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiQueryAddress(
|
||||
PFILE_OBJECT FileObject,
|
||||
PULONG Address)
|
||||
/*
|
||||
* FUNCTION: Queries for a local IP address
|
||||
* ARGUMENTS:
|
||||
* FileObject = Pointer to file object
|
||||
* Address = Address of buffer to place local address
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
UINT i;
|
||||
TDIEntityID *Entities;
|
||||
ULONG EntityCount;
|
||||
ULONG EntityType;
|
||||
IPSNMP_INFO SnmpInfo;
|
||||
PIPADDR_ENTRY IpAddress;
|
||||
ULONG BufferSize;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
|
||||
|
||||
BufferSize = sizeof(TDIEntityID) * 20;
|
||||
Entities = (TDIEntityID*)ExAllocatePool(NonPagedPool, BufferSize);
|
||||
if (!Entities) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Query device for supported entities */
|
||||
|
||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
||||
GENERIC_ENTITY, /* Entity */
|
||||
TL_INSTANCE, /* Instance */
|
||||
INFO_CLASS_GENERIC, /* Entity class */
|
||||
INFO_TYPE_PROVIDER, /* Entity type */
|
||||
ENTITY_LIST_ID, /* Entity id */
|
||||
Entities, /* Output buffer */
|
||||
&BufferSize); /* Output buffer size */
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unable to get list of supported entities (Status = 0x%X).\n", Status));
|
||||
ExFreePool(Entities);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Locate an IP entity */
|
||||
EntityCount = BufferSize / sizeof(TDIEntityID);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("EntityCount = %d\n", EntityCount));
|
||||
|
||||
for (i = 0; i < EntityCount; i++) {
|
||||
if (Entities[i].tei_entity == CL_NL_ENTITY) {
|
||||
/* Query device for entity type */
|
||||
|
||||
BufferSize = sizeof(EntityType);
|
||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
||||
CL_NL_ENTITY, /* Entity */
|
||||
Entities[i].tei_instance, /* Instance */
|
||||
INFO_CLASS_GENERIC, /* Entity class */
|
||||
INFO_TYPE_PROVIDER, /* Entity type */
|
||||
ENTITY_TYPE_ID, /* Entity id */
|
||||
&EntityType, /* Output buffer */
|
||||
&BufferSize); /* Output buffer size */
|
||||
if (!NT_SUCCESS(Status) || (EntityType != CL_NL_IP)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unable to get entity of type IP (Status = 0x%X).\n", Status));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Query device for SNMP information */
|
||||
|
||||
BufferSize = sizeof(SnmpInfo);
|
||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
||||
CL_NL_ENTITY, /* Entity */
|
||||
Entities[i].tei_instance, /* Instance */
|
||||
INFO_CLASS_PROTOCOL, /* Entity class */
|
||||
INFO_TYPE_PROVIDER, /* Entity type */
|
||||
IP_MIB_STATS_ID, /* Entity id */
|
||||
&SnmpInfo, /* Output buffer */
|
||||
&BufferSize); /* Output buffer size */
|
||||
if (!NT_SUCCESS(Status) || (SnmpInfo.NumAddr == 0)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Query device for all IP addresses */
|
||||
|
||||
if (SnmpInfo.NumAddr != 0) {
|
||||
BufferSize = SnmpInfo.NumAddr * sizeof(IPADDR_ENTRY);
|
||||
IpAddress = (PIPADDR_ENTRY)ExAllocatePool(NonPagedPool, BufferSize);
|
||||
if (!IpAddress) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
||||
CL_NL_ENTITY, /* Entity */
|
||||
Entities[i].tei_instance, /* Instance */
|
||||
INFO_CLASS_PROTOCOL, /* Entity class */
|
||||
INFO_TYPE_PROVIDER, /* Entity type */
|
||||
IP_MIB_ADDRTABLE_ENTRY_ID, /* Entity id */
|
||||
IpAddress, /* Output buffer */
|
||||
&BufferSize); /* Output buffer size */
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Unable to get IP address (Status = 0x%X).\n", Status));
|
||||
ExFreePool(IpAddress);
|
||||
break;
|
||||
}
|
||||
|
||||
if (SnmpInfo.NumAddr != 1) {
|
||||
/* Skip loopback address */
|
||||
*Address = DN2H(((PIPADDR_ENTRY)((ULONG)IpAddress + sizeof(IPADDR_ENTRY)))->Addr);
|
||||
} else {
|
||||
/* Select the first address returned */
|
||||
*Address = DN2H(IpAddress->Addr);
|
||||
}
|
||||
|
||||
ExFreePool(IpAddress);
|
||||
} else {
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(Entities);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Leaving\n"));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiSend(
|
||||
PFILE_OBJECT TransportObject,
|
||||
PFILE_REQUEST_SENDTO Request)
|
||||
/*
|
||||
* FUNCTION: Sends a block of data
|
||||
* ARGUMENTS:
|
||||
* TransportObject = Pointer to transport object
|
||||
* Request = Pointer to request
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PTDI_CONNECTION_INFORMATION ConnectInfo;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
DWORD TdiAddressSize;
|
||||
ULONG BufferSize;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
PMDL Mdl;
|
||||
|
||||
/* FIXME: Connectionless only */
|
||||
|
||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||
if (!DeviceObject) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
TdiAddressSize = TdiAddressSizeFromName(&Request->To);
|
||||
|
||||
ConnectInfo = (PTDI_CONNECTION_INFORMATION)
|
||||
ExAllocatePool(NonPagedPool,
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
TdiAddressSize);
|
||||
|
||||
if (!ConnectInfo) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(ConnectInfo,
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
TdiAddressSize);
|
||||
|
||||
ConnectInfo->RemoteAddressLength = TdiAddressSize;
|
||||
ConnectInfo->RemoteAddress = (PVOID)
|
||||
(ConnectInfo + sizeof(TDI_CONNECTION_INFORMATION));
|
||||
|
||||
TdiBuildAddress(ConnectInfo->RemoteAddress, &Request->To);
|
||||
|
||||
Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
|
||||
DeviceObject, /* Device object */
|
||||
TransportObject, /* File object */
|
||||
NULL, /* Event */
|
||||
NULL); /* Return buffer */
|
||||
if (!Irp) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
|
||||
ExFreePool(ConnectInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* FIXME: There may be more than one buffer */
|
||||
BufferSize = Request->Buffers->len;
|
||||
Mdl = IoAllocateMdl(
|
||||
Request->Buffers->buf, /* Virtual address of buffer */
|
||||
Request->Buffers->len, /* Length of buffer */
|
||||
FALSE, /* Not secondary */
|
||||
FALSE, /* Don't charge quota */
|
||||
NULL); /* Don't use IRP */
|
||||
if (!Mdl) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
|
||||
IoFreeIrp(Irp);
|
||||
ExFreePool(ConnectInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
try {
|
||||
#endif
|
||||
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
|
||||
#ifdef _MSC_VER
|
||||
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||
IoFreeMdl(Mdl);
|
||||
IoFreeIrp(Irp);
|
||||
ExFreePool(ConnectInfo);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
|
||||
TdiBuildSendDatagram(Irp, /* I/O Request Packet */
|
||||
DeviceObject, /* Device object */
|
||||
TransportObject, /* File object */
|
||||
NULL, /* Completion routine */
|
||||
NULL, /* Completion context */
|
||||
Mdl, /* Descriptor for data buffer */
|
||||
BufferSize, /* Size of data to send */
|
||||
ConnectInfo); /* Connection information */
|
||||
|
||||
Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
|
||||
|
||||
ExFreePool(ConnectInfo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiSendDatagram(
|
||||
PFILE_OBJECT TransportObject,
|
||||
LPSOCKADDR Address,
|
||||
PVOID Buffer,
|
||||
ULONG BufferSize)
|
||||
/*
|
||||
* FUNCTION: Sends a datagram
|
||||
* ARGUMENTS:
|
||||
* TransportObject = Pointer to transport object
|
||||
* Address = Remote address
|
||||
* Buffer = Pointer to buffer with data to send
|
||||
* BufferSize = Length of Buffer
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PTDI_CONNECTION_INFORMATION ConnectInfo;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
DWORD TdiAddressSize;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
PMDL Mdl;
|
||||
|
||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||
if (!DeviceObject) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
TdiAddressSize = TdiAddressSizeFromName(Address);
|
||||
|
||||
ConnectInfo = (PTDI_CONNECTION_INFORMATION)
|
||||
ExAllocatePool(NonPagedPool,
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
TdiAddressSize);
|
||||
|
||||
if (!ConnectInfo) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(ConnectInfo,
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
TdiAddressSize);
|
||||
|
||||
ConnectInfo->RemoteAddressLength = TdiAddressSize;
|
||||
ConnectInfo->RemoteAddress = (PVOID)
|
||||
(ConnectInfo + sizeof(TDI_CONNECTION_INFORMATION));
|
||||
|
||||
TdiBuildAddress(ConnectInfo->RemoteAddress, Address);
|
||||
|
||||
Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
|
||||
DeviceObject, /* Device object */
|
||||
TransportObject, /* File object */
|
||||
NULL, /* Event */
|
||||
NULL); /* Return buffer */
|
||||
if (!Irp) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
|
||||
ExFreePool(ConnectInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Mdl = IoAllocateMdl(Buffer, /* Virtual address of buffer */
|
||||
BufferSize, /* Length of buffer */
|
||||
FALSE, /* Not secondary */
|
||||
FALSE, /* Don't charge quota */
|
||||
NULL); /* Don't use IRP */
|
||||
if (!Mdl) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
|
||||
IoFreeIrp(Irp);
|
||||
ExFreePool(ConnectInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
try {
|
||||
#endif
|
||||
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
|
||||
#ifdef _MSC_VER
|
||||
} except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||
IoFreeMdl(Mdl);
|
||||
IoFreeIrp(Irp);
|
||||
ExFreePool(ConnectInfo);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
|
||||
TdiBuildSendDatagram(Irp, /* I/O Request Packet */
|
||||
DeviceObject, /* Device object */
|
||||
TransportObject, /* File object */
|
||||
NULL, /* Completion routine */
|
||||
NULL, /* Completion context */
|
||||
Mdl, /* Descriptor for data buffer */
|
||||
BufferSize, /* Size of data to send */
|
||||
ConnectInfo); /* Connection information */
|
||||
|
||||
Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE, NULL);
|
||||
|
||||
ExFreePool(ConnectInfo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS TdiReceiveDatagram(
|
||||
PFILE_OBJECT TransportObject,
|
||||
LPSOCKADDR From,
|
||||
LPSOCKADDR Address,
|
||||
PUCHAR Buffer,
|
||||
PULONG BufferSize)
|
||||
/*
|
||||
* FUNCTION: Receives a datagram
|
||||
* ARGUMENTS:
|
||||
* TransportObject = Pointer to transport object
|
||||
* From = Receive filter (NULL if none)
|
||||
* Address = Address of buffer to place remote address
|
||||
* Buffer = Address of buffer to place received data
|
||||
* BufferSize = Address of buffer with length of Buffer (updated)
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
PTDI_CONNECTION_INFORMATION ReceiveInfo;
|
||||
PTDI_CONNECTION_INFORMATION ReturnInfo;
|
||||
PTA_ADDRESS_IP ReturnAddress;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
DWORD TdiAddressSize;
|
||||
NTSTATUS Status;
|
||||
PIRP Irp;
|
||||
PMDL Mdl;
|
||||
|
||||
if (From != NULL) {
|
||||
/* FIXME: Check that the socket type match the socket */
|
||||
}
|
||||
|
||||
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
|
||||
if (!DeviceObject) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* FIXME: Get from socket information */
|
||||
TdiAddressSize = sizeof(TA_ADDRESS_IP);
|
||||
|
||||
ReceiveInfo = (PTDI_CONNECTION_INFORMATION)
|
||||
ExAllocatePool(NonPagedPool,
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
2 * TdiAddressSize);
|
||||
if (!ReceiveInfo) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
RtlZeroMemory(ReceiveInfo,
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
sizeof(TDI_CONNECTION_INFORMATION) +
|
||||
2 * TdiAddressSize);
|
||||
|
||||
if (From != NULL) {
|
||||
ReceiveInfo->RemoteAddressLength = TdiAddressSize;
|
||||
ReceiveInfo->RemoteAddress = (PVOID)
|
||||
(ReceiveInfo + sizeof(TDI_CONNECTION_INFORMATION));
|
||||
/* Filter datagrams */
|
||||
TdiBuildAddress(ReceiveInfo->RemoteAddress, From);
|
||||
} else {
|
||||
/* Receive from any address */
|
||||
ReceiveInfo->RemoteAddressLength = 0;
|
||||
ReceiveInfo->RemoteAddress = NULL;
|
||||
}
|
||||
|
||||
ReturnInfo = (PTDI_CONNECTION_INFORMATION)
|
||||
(ReceiveInfo + sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize);
|
||||
ReturnInfo->RemoteAddressLength = TdiAddressSize;
|
||||
ReturnInfo->RemoteAddress = (PVOID)
|
||||
(ReturnInfo + sizeof(TDI_CONNECTION_INFORMATION));
|
||||
|
||||
Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, /* Sub function */
|
||||
DeviceObject, /* Device object */
|
||||
TransportObject, /* File object */
|
||||
NULL, /* Event */
|
||||
NULL); /* Return buffer */
|
||||
if (!Irp) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
ExFreePool(ReceiveInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Mdl = IoAllocateMdl(Buffer, /* Virtual address */
|
||||
*BufferSize, /* Length of buffer */
|
||||
FALSE, /* Not secondary */
|
||||
FALSE, /* Don't charge quota */
|
||||
NULL); /* Don't use IRP */
|
||||
if (!Mdl) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
IoFreeIrp(Irp);
|
||||
ExFreePool(ReceiveInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
try {
|
||||
#endif
|
||||
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
|
||||
#ifdef _MSC_VER
|
||||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
|
||||
IoFreeMdl(Mdl);
|
||||
IoFreeIrp(Irp);
|
||||
ExFreePool(ReceiveInfo);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
#endif
|
||||
|
||||
TdiBuildReceiveDatagram(Irp, /* I/O Request Packet */
|
||||
DeviceObject, /* Device object */
|
||||
TransportObject, /* File object */
|
||||
NULL, /* Completion routine */
|
||||
NULL, /* Completion context */
|
||||
Mdl, /* Data buffer */
|
||||
*BufferSize, /* Size of data buffer */
|
||||
ReceiveInfo, /* Connection information */
|
||||
ReturnInfo, /* Connection information */
|
||||
TDI_RECEIVE_NORMAL); /* Flags */
|
||||
Status = TdiCall(Irp, DeviceObject, &Iosb, TRUE, NULL);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
*BufferSize = Iosb.Information;
|
||||
TdiBuildName(Address, ReturnInfo->RemoteAddress);
|
||||
}
|
||||
|
||||
IoFreeMdl(Mdl);
|
||||
ExFreePool(ReceiveInfo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
301
reactos/drivers/net/afd/include/afd.h
Normal file
301
reactos/drivers/net/afd/include/afd.h
Normal file
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: include/afd.h
|
||||
* PURPOSE: Main driver header
|
||||
*/
|
||||
#ifndef __AFD_H
|
||||
#define __AFD_H
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <net/tdikrnl.h>
|
||||
#include <net/tdiinfo.h>
|
||||
#include <afd/shared.h>
|
||||
#include <debug.h>
|
||||
|
||||
/* Forward declarations */
|
||||
struct _AFDFCB;
|
||||
|
||||
typedef struct _DEVICE_EXTENSION {
|
||||
PDEVICE_OBJECT StorageDevice;
|
||||
KSPIN_LOCK FCBListLock;
|
||||
LIST_ENTRY FCBListHead;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
/* Context Control Block structure */
|
||||
typedef struct _AFDCCB {
|
||||
struct _AFDFCB *FCB;
|
||||
LIST_ENTRY ListEntry;
|
||||
PFILE_OBJECT FileObject;
|
||||
ULONG Flags;
|
||||
LARGE_INTEGER CurrentByteOffset;
|
||||
} AFDCCB, *PAFDCCB;
|
||||
|
||||
/* Flags for CCB structure */
|
||||
#define CCB_CLEANED 0x00000001
|
||||
|
||||
/* Borrowed from http://www.acc.umu.se/~bosse/ntifs.h by Bo Branten */
|
||||
typedef struct _FSRTL_COMMON_FCB_HEADER {
|
||||
CSHORT NodeTypeCode;
|
||||
CSHORT NodeByteSize;
|
||||
UCHAR Flags;
|
||||
UCHAR IsFastIoPossible;
|
||||
UCHAR Flags2;
|
||||
UCHAR Reserved;
|
||||
PERESOURCE Resource;
|
||||
PERESOURCE PagingIoResource;
|
||||
LARGE_INTEGER AllocationSize;
|
||||
LARGE_INTEGER FileSize;
|
||||
LARGE_INTEGER ValidDataLength;
|
||||
} FSRTL_COMMON_FCB_HEADER, *PFSRTL_COMMON_FCB_HEADER;
|
||||
|
||||
typedef struct _FsdNTRequiredFCB {
|
||||
FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
|
||||
SECTION_OBJECT_POINTERS SectionObject;
|
||||
ERESOURCE MainResource;
|
||||
ERESOURCE PagingIoResource;
|
||||
} FsdNTRequiredFCB, *PFsdNTRequiredFCB;
|
||||
|
||||
typedef struct _AFDFCB {
|
||||
FsdNTRequiredFCB NTRequiredFCB;
|
||||
LIST_ENTRY ListEntry;
|
||||
PDEVICE_EXTENSION DeviceExt;
|
||||
SHARE_ACCESS ShareAccess;
|
||||
ULONG ReferenceCount;
|
||||
ULONG OpenHandleCount;
|
||||
HANDLE TdiAddressObjectHandle;
|
||||
PFILE_OBJECT TdiAddressObject;
|
||||
HANDLE TdiConnectionObjectHandle;
|
||||
PFILE_OBJECT TdiConnectionObject;
|
||||
LIST_ENTRY CCBListHead;
|
||||
INT AddressFamily;
|
||||
INT SocketType;
|
||||
INT Protocol;
|
||||
PVOID HelperContext;
|
||||
DWORD NotificationEvents;
|
||||
UNICODE_STRING TdiDeviceName;
|
||||
DWORD State;
|
||||
} AFDFCB, *PAFDFCB;
|
||||
|
||||
/* Socket states */
|
||||
#define SOCKET_STATE_CREATED 0
|
||||
#define SOCKET_STATE_BOUND 1
|
||||
#define SOCKET_STATE_LISTENING 2
|
||||
|
||||
typedef struct IPSNMP_INFO {
|
||||
ULONG Forwarding;
|
||||
ULONG DefaultTTL;
|
||||
ULONG InReceives;
|
||||
ULONG InHdrErrors;
|
||||
ULONG InAddrErrors;
|
||||
ULONG ForwDatagrams;
|
||||
ULONG InUnknownProtos;
|
||||
ULONG InDiscards;
|
||||
ULONG InDelivers;
|
||||
ULONG OutRequests;
|
||||
ULONG RoutingDiscards;
|
||||
ULONG OutDiscards;
|
||||
ULONG OutNoRoutes;
|
||||
ULONG ReasmTimeout;
|
||||
ULONG ReasmReqds;
|
||||
ULONG ReasmOks;
|
||||
ULONG ReasmFails;
|
||||
ULONG FragOks;
|
||||
ULONG FragFails;
|
||||
ULONG FragCreates;
|
||||
ULONG NumIf;
|
||||
ULONG NumAddr;
|
||||
ULONG NumRoutes;
|
||||
} IPSNMP_INFO, *PIPSNMP_INFO;
|
||||
|
||||
typedef struct IPADDR_ENTRY {
|
||||
ULONG Addr;
|
||||
ULONG Index;
|
||||
ULONG Mask;
|
||||
ULONG BcastAddr;
|
||||
ULONG ReasmSize;
|
||||
USHORT Context;
|
||||
USHORT Pad;
|
||||
} IPADDR_ENTRY, *PIPADDR_ENTRY;
|
||||
|
||||
|
||||
#define TL_INSTANCE 0
|
||||
|
||||
#define IP_MIB_STATS_ID 0x1
|
||||
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
|
||||
|
||||
|
||||
/* IOCTL codes */
|
||||
|
||||
#define IOCTL_TCP_QUERY_INFORMATION_EX \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_TCP_SET_INFORMATION_EX \
|
||||
CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
|
||||
|
||||
#ifdef i386
|
||||
|
||||
/* DWORD network to host byte order conversion for i386 */
|
||||
#define DN2H(dw) \
|
||||
((((dw) & 0xFF000000L) >> 24) | \
|
||||
(((dw) & 0x00FF0000L) >> 8) | \
|
||||
(((dw) & 0x0000FF00L) << 8) | \
|
||||
(((dw) & 0x000000FFL) << 24))
|
||||
|
||||
/* DWORD host to network byte order conversion for i386 */
|
||||
#define DH2N(dw) \
|
||||
((((dw) & 0xFF000000L) >> 24) | \
|
||||
(((dw) & 0x00FF0000L) >> 8) | \
|
||||
(((dw) & 0x0000FF00L) << 8) | \
|
||||
(((dw) & 0x000000FFL) << 24))
|
||||
|
||||
/* WORD network to host order conversion for i386 */
|
||||
#define WN2H(w) \
|
||||
((((w) & 0xFF00) >> 8) | \
|
||||
(((w) & 0x00FF) << 8))
|
||||
|
||||
/* WORD host to network byte order conversion for i386 */
|
||||
#define WH2N(w) \
|
||||
((((w) & 0xFF00) >> 8) | \
|
||||
(((w) & 0x00FF) << 8))
|
||||
|
||||
#else /* i386 */
|
||||
|
||||
/* DWORD network to host byte order conversion for other architectures */
|
||||
#define DN2H(dw) \
|
||||
(dw)
|
||||
|
||||
/* DWORD host to network byte order conversion for other architectures */
|
||||
#define DH2N(dw) \
|
||||
(dw)
|
||||
|
||||
/* WORD network to host order conversion for other architectures */
|
||||
#define WN2H(w) \
|
||||
(w)
|
||||
|
||||
/* WORD host to network byte order conversion for other architectures */
|
||||
#define WH2N(w) \
|
||||
(w)
|
||||
|
||||
#endif /* i386 */
|
||||
|
||||
|
||||
/* Prototypes from dispatch.c */
|
||||
|
||||
NTSTATUS AfdDispBind(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp);
|
||||
|
||||
NTSTATUS AfdDispListen(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp);
|
||||
|
||||
NTSTATUS AfdDispSendTo(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp);
|
||||
|
||||
NTSTATUS AfdDispRecvFrom(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp);
|
||||
|
||||
/* Prototypes from event.c */
|
||||
|
||||
NTSTATUS AfdRegisterEventHandlers(
|
||||
PAFDFCB FCB);
|
||||
|
||||
NTSTATUS AfdDeregisterEventHandlers(
|
||||
PAFDFCB FCB);
|
||||
|
||||
/* Prototypes from opnclose.c */
|
||||
|
||||
NTSTATUS AfdCreate(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS AfdCreateNamedPipe(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS AfdClose(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
/* Prototypes from rdwr.c */
|
||||
|
||||
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);
|
||||
|
||||
NTSTATUS AfdRead(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
NTSTATUS AfdWrite(
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp);
|
||||
|
||||
/* Prototypes from tdi.c */
|
||||
|
||||
NTSTATUS TdiCloseDevice(
|
||||
HANDLE Handle,
|
||||
PFILE_OBJECT FileObject);
|
||||
|
||||
NTSTATUS TdiOpenAddressFileIPv4(
|
||||
PUNICODE_STRING DeviceName,
|
||||
LPSOCKADDR Name,
|
||||
PHANDLE AddressHandle,
|
||||
PFILE_OBJECT *AddressObject);
|
||||
|
||||
NTSTATUS TdiSetEventHandler(
|
||||
PFILE_OBJECT FileObject,
|
||||
LONG EventType,
|
||||
PVOID Handler,
|
||||
PVOID Context);
|
||||
|
||||
NTSTATUS TdiQueryDeviceControl(
|
||||
PFILE_OBJECT FileObject,
|
||||
ULONG IoControlCode,
|
||||
PVOID InputBuffer,
|
||||
ULONG InputBufferLength,
|
||||
PVOID OutputBuffer,
|
||||
ULONG OutputBufferLength,
|
||||
PULONG Return);
|
||||
|
||||
NTSTATUS TdiQueryInformationEx(
|
||||
PFILE_OBJECT FileObject,
|
||||
ULONG Entity,
|
||||
ULONG Instance,
|
||||
ULONG Class,
|
||||
ULONG Type,
|
||||
ULONG Id,
|
||||
PVOID OutputBuffer,
|
||||
PULONG OutputLength);
|
||||
|
||||
NTSTATUS TdiQueryAddress(
|
||||
PFILE_OBJECT FileObject,
|
||||
PULONG Address);
|
||||
|
||||
NTSTATUS TdiSend(
|
||||
PFILE_OBJECT TransportObject,
|
||||
PFILE_REQUEST_SENDTO Request);
|
||||
|
||||
NTSTATUS TdiSendDatagram(
|
||||
PFILE_OBJECT TransportObject,
|
||||
LPSOCKADDR Address,
|
||||
PVOID Buffer,
|
||||
ULONG BufferSize);
|
||||
|
||||
#endif /*__AFD_H */
|
||||
|
||||
/* EOF */
|
92
reactos/drivers/net/afd/include/debug.h
Normal file
92
reactos/drivers/net/afd/include/debug.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: include/debug.h
|
||||
* PURPOSE: Debugging support macros
|
||||
* DEFINES: DBG - Enable debug output
|
||||
* NASSERT - Disable assertions
|
||||
*/
|
||||
#ifndef __DEBUG_H
|
||||
#define __DEBUG_H
|
||||
|
||||
#define NORMAL_MASK 0x000000FF
|
||||
#define SPECIAL_MASK 0xFFFFFF00
|
||||
#define MIN_TRACE 0x00000001
|
||||
#define MID_TRACE 0x00000002
|
||||
#define MAX_TRACE 0x00000003
|
||||
|
||||
#define DEBUG_IRP 0x00000100
|
||||
|
||||
#define DEBUG_ULTRA 0xFFFFFFFF
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
extern DWORD DebugTraceLevel;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define AFD_DbgPrint(_t_, _x_) \
|
||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||
DbgPrint("(%s:%d) ", __FILE__, __LINE__); \
|
||||
DbgPrint _x_ ; \
|
||||
}
|
||||
|
||||
#else /* _MSC_VER */
|
||||
|
||||
#define AFD_DbgPrint(_t_, _x_) \
|
||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||
DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
DbgPrint _x_ ; \
|
||||
}
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef ASSERT
|
||||
#undef ASSERT
|
||||
#endif
|
||||
|
||||
#ifdef NASSERT
|
||||
#define ASSERT(x)
|
||||
#else /* NASSERT */
|
||||
#define ASSERT(x) if (!(x)) { AFD_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
|
||||
#endif /* NASSERT */
|
||||
|
||||
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
|
||||
|
||||
#else /* DBG */
|
||||
|
||||
#define AFD_DbgPrint(_t_, _x_)
|
||||
|
||||
#define ASSERT_IRQL(x)
|
||||
#define ASSERT(x)
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
#define assert(x) ASSERT(x)
|
||||
#define assert_irql(x) ASSERT_IRQL(x)
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define UNIMPLEMENTED \
|
||||
AFD_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \
|
||||
but come back another day.\n", __FILE__, __LINE__));
|
||||
|
||||
#else /* _MSC_VER */
|
||||
|
||||
#define UNIMPLEMENTED \
|
||||
AFD_DbgPrint(MIN_TRACE, ("%s at %s:%d is unimplemented, " \
|
||||
"but come back another day.\n", __FUNCTION__, __FILE__, __LINE__));
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
#define CHECKPOINT \
|
||||
do { AFD_DbgPrint(MIN_TRACE, ("%s:%d\n", __FILE__, __LINE__)); } while(0);
|
||||
|
||||
#endif /* __DEBUG_H */
|
||||
|
||||
/* EOF */
|
87
reactos/drivers/net/afd/makefile
Normal file
87
reactos/drivers/net/afd/makefile
Normal file
|
@ -0,0 +1,87 @@
|
|||
# AFD.SYS - Ancillary Function Driver
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGETNAME=afd
|
||||
|
||||
CFLAGS = -I./include
|
||||
|
||||
RESOURCE_OBJECT = $(TARGETNAME).coff
|
||||
AFD_OBJECTS = afd/afd.o afd/dispatch.o afd/event.o afd/opnclose.o afd/rdwr.o afd/tdi.o
|
||||
|
||||
all: $(TARGETNAME).sys
|
||||
|
||||
$(TARGETNAME).coff: $(TARGETNAME).rc ../../../include/reactos/resource.h
|
||||
|
||||
OBJECTS = $(AFD_OBJECTS) $(RESOURCE_OBJECT) ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
|
||||
ifeq ($(DOSCLI),yes)
|
||||
CLEAN_FILES = *.o afd\*.o $(TARGETNAME).coff $(TARGETNAME).o \
|
||||
junk.tmp base.tmp temp.exp $(TARGETNAME).sys $(TARGETNAME).sym
|
||||
else
|
||||
CLEAN_FILES = *.o afd/*.o $(TARGETNAME).coff $(TARGETNAME).o \
|
||||
junk.tmp base.tmp temp.exp $(TARGETNAME).sys $(TARGETNAME).sym
|
||||
endif
|
||||
|
||||
$(TARGETNAME).sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-nostartfiles -nostdlib \
|
||||
--subsystem=native \
|
||||
-mdll \
|
||||
--dll \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,--base-file,base.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
$(OBJECTS) \
|
||||
-o junk.tmp
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGETNAME).sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
-nostartfiles -nostdlib \
|
||||
--subsystem=native \
|
||||
-mdll \
|
||||
--dll \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
$(OBJECTS) \
|
||||
-o $(TARGETNAME).sys
|
||||
- $(RM) temp.exp
|
||||
$(NM) --numeric-sort $(TARGETNAME).sys > $(TARGETNAME).sym
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||
- $(RM) $*
|
||||
|
||||
.PHONY: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
install: $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)\drivers\$(TARGETNAME).sys
|
||||
else
|
||||
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
|
||||
endif
|
||||
|
||||
dist: $(DIST_DIR)/drivers/$(TARGETNAME).sys
|
||||
|
||||
$(DIST_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGETNAME).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGETNAME).sys
|
||||
else
|
||||
$(CP) $(TARGETNAME).sys ../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys
|
||||
endif
|
||||
|
||||
#WITH_DEBUGGING = yes
|
||||
#WIN32_LEAN_AND_MEAN = yes
|
||||
#WARNINGS_ARE_ERRORS = yes
|
||||
include ../../../rules.mak
|
|
@ -21,16 +21,11 @@
|
|||
|
||||
extern DWORD DebugTraceLevel;
|
||||
|
||||
#define Get_DbgPrint(quote...) L##quote
|
||||
|
||||
#define WSH_DbgPrint(_t_, _x_) \
|
||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||
WCHAR _buffer[256]; \
|
||||
swprintf(_buffer, L"(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
OutputDebugStringW(_buffer); \
|
||||
swprintf(_buffer, Get_DbgPrint _x_); \
|
||||
OutputDebugStringW(_buffer); \
|
||||
DbgPrint("(%hS:%d)(%hS) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
DbgPrint _x_; \
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
|
@ -64,7 +59,9 @@ extern DWORD DebugTraceLevel;
|
|||
please try again later.\n", __FILE__, __LINE__, __FUNCTION__));
|
||||
|
||||
#define CHECKPOINT \
|
||||
do { WSH_DbgPrint(MIN_TRACE, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0);
|
||||
WSH_DbgPrint(MIN_TRACE, ("\n"));
|
||||
|
||||
#define CP CHECKPOINT
|
||||
|
||||
#endif /* __DEBUG_H */
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
|||
$(CC) \
|
||||
$(TARGETNAME).o \
|
||||
$(LIBS) \
|
||||
-specs=$(TARGETNAME)_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--base-file,base.tmp
|
||||
|
@ -50,10 +49,9 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
|||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
$(OBJECTS) $(LIBS) \
|
||||
-specs=$(TARGETNAME)_specs \
|
||||
-mdll \
|
||||
-o $(TARGETNAME).dll \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,--image-base,0x777C0000 \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,temp.exp
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifdef DBG
|
||||
|
||||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = MIN_TRACE;
|
||||
DWORD DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
@ -22,11 +22,10 @@ VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
|
|||
|
||||
BOOL
|
||||
EXPORT
|
||||
DllMain(PVOID hInstDll,
|
||||
DllMain(HANDLE hInstDll,
|
||||
ULONG dwReason,
|
||||
PVOID Reserved)
|
||||
{
|
||||
OutputDebugString(_T("Hello from wshtcpip.dll\n"));
|
||||
WSH_DbgPrint(MIN_TRACE, ("DllMain of wshtcpip.dll\n"));
|
||||
|
||||
switch (dwReason) {
|
||||
|
@ -289,6 +288,8 @@ WSHOpenSocket2(
|
|||
UNICODE_STRING String;
|
||||
NTSTATUS Status;
|
||||
|
||||
WSH_DbgPrint(MAX_TRACE, ("\n"));
|
||||
|
||||
/* FIXME: Raw IP only. Support UDP and TCP */
|
||||
ASSERT(*SocketType == SOCK_RAW);
|
||||
|
||||
|
|
90
reactos/include/afd/shared.h
Normal file
90
reactos/include/afd/shared.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver
|
||||
* FILE: include/afd/shared.h
|
||||
* PURPOSE: Shared definitions for AFD.SYS and MSAFD.DLL
|
||||
*/
|
||||
#ifndef __AFD_SHARED_H
|
||||
#define __AFD_SHARED_H
|
||||
|
||||
#define AfdSocket "AfdSocket"
|
||||
#define AFD_SOCKET_LENGTH (sizeof(AfdSocket) - 1)
|
||||
|
||||
typedef struct _AFD_SOCKET_INFORMATION {
|
||||
INT AddressFamily;
|
||||
INT SocketType;
|
||||
INT Protocol;
|
||||
PVOID HelperContext;
|
||||
DWORD NotificationEvents;
|
||||
UNICODE_STRING TdiDeviceName;
|
||||
} AFD_SOCKET_INFORMATION, *PAFD_SOCKET_INFORMATION;
|
||||
|
||||
|
||||
/* AFD IOCTL code definitions */
|
||||
|
||||
#define FSCTL_AFD_BASE FILE_DEVICE_NAMED_PIPE // ???
|
||||
|
||||
#define AFD_CTL_CODE(Function, Method, Access) \
|
||||
CTL_CODE(FSCTL_AFD_BASE, Function, Method, Access)
|
||||
|
||||
#define IOCTL_AFD_BIND \
|
||||
AFD_CTL_CODE(0, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_AFD_LISTEN \
|
||||
AFD_CTL_CODE(1, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_AFD_SENDTO \
|
||||
AFD_CTL_CODE(2, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_AFD_RECVFROM \
|
||||
AFD_CTL_CODE(3, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _FILE_REQUEST_BIND {
|
||||
SOCKADDR Name;
|
||||
} FILE_REQUEST_BIND, *PFILE_REQUEST_BIND;
|
||||
|
||||
typedef struct _FILE_REPLY_BIND {
|
||||
INT Status;
|
||||
HANDLE TdiAddressObjectHandle;
|
||||
HANDLE TdiConnectionObjectHandle;
|
||||
} FILE_REPLY_BIND, *PFILE_REPLY_BIND;
|
||||
|
||||
typedef struct _FILE_REQUEST_LISTEN {
|
||||
INT Backlog;
|
||||
} FILE_REQUEST_LISTEN, *PFILE_REQUEST_LISTEN;
|
||||
|
||||
typedef struct _FILE_REPLY_LISTEN {
|
||||
INT Status;
|
||||
} FILE_REPLY_LISTEN, *PFILE_REPLY_LISTEN;
|
||||
|
||||
|
||||
typedef struct _FILE_REQUEST_SENDTO {
|
||||
LPWSABUF Buffers;
|
||||
DWORD BufferCount;
|
||||
DWORD Flags;
|
||||
SOCKADDR To;
|
||||
INT ToLen;
|
||||
} FILE_REQUEST_SENDTO, *PFILE_REQUEST_SENDTO;
|
||||
|
||||
typedef struct _FILE_REPLY_SENDTO {
|
||||
INT Status;
|
||||
DWORD NumberOfBytesSent;
|
||||
} FILE_REPLY_SENDTO, *PFILE_REPLY_SENDTO;
|
||||
|
||||
|
||||
typedef struct _FILE_REQUEST_RECVFROM {
|
||||
LPWSABUF Buffers;
|
||||
DWORD BufferCount;
|
||||
LPDWORD Flags;
|
||||
LPSOCKADDR From;
|
||||
LPINT FromLen;
|
||||
} FILE_REQUEST_RECVFROM, *PFILE_REQUEST_RECVFROM;
|
||||
|
||||
typedef struct _FILE_REPLY_RECVFROM {
|
||||
INT Status;
|
||||
DWORD NumberOfBytesRecvd;
|
||||
} FILE_REPLY_RECVFROM, *PFILE_REPLY_RECVFROM;
|
||||
|
||||
#endif /*__AFD_SHARED_H */
|
||||
|
||||
/* EOF */
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
/* FIXME: Missed some definitions in ntddk.h */
|
||||
|
||||
/* Could be defined in ndis.h */
|
||||
#ifndef __NDIS_H
|
||||
typedef signed int INT, *PINT;
|
||||
#endif
|
||||
/* Could be defined elsewhere */
|
||||
//#ifndef INT
|
||||
//typedef signed int INT, *PINT;
|
||||
//#endif
|
||||
|
||||
|
||||
|
||||
|
|
6
reactos/lib/msafd/.cvsignore
Normal file
6
reactos/lib/msafd/.cvsignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
msafd.a
|
||||
msafd.dll
|
||||
msafd.coff
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
67
reactos/lib/msafd/include/debug.h
Normal file
67
reactos/lib/msafd/include/debug.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: include/debug.h
|
||||
* PURPOSE: Debugging support macros
|
||||
* DEFINES: DBG - Enable debug output
|
||||
* NASSERT - Disable assertions
|
||||
*/
|
||||
#ifndef __DEBUG_H
|
||||
#define __DEBUG_H
|
||||
|
||||
#define NORMAL_MASK 0x000000FF
|
||||
#define SPECIAL_MASK 0xFFFFFF00
|
||||
#define MIN_TRACE 0x00000001
|
||||
#define MID_TRACE 0x00000002
|
||||
#define MAX_TRACE 0x00000003
|
||||
|
||||
#define DEBUG_ULTRA 0xFFFFFFFF
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
extern DWORD DebugTraceLevel;
|
||||
|
||||
#define AFD_DbgPrint(_t_, _x_) \
|
||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||
DbgPrint("(%hS:%d)(%hS) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
DbgPrint _x_; \
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
#undef ASSERT
|
||||
#endif
|
||||
|
||||
#ifdef NASSERT
|
||||
#define ASSERT(x)
|
||||
#else /* NASSERT */
|
||||
#define ASSERT(x) if (!(x)) { AFD_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
|
||||
#endif /* NASSERT */
|
||||
|
||||
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
|
||||
|
||||
#else /* DBG */
|
||||
|
||||
#define AFD_DbgPrint(_t_, _x_)
|
||||
|
||||
#define ASSERT_IRQL(x)
|
||||
#define ASSERT(x)
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
#define assert(x) ASSERT(x)
|
||||
#define assert_irql(x) ASSERT_IRQL(x)
|
||||
|
||||
|
||||
#define UNIMPLEMENTED \
|
||||
AFD_DbgPrint(MIN_TRACE, ("is unimplemented, please try again later.\n"));
|
||||
|
||||
#define CHECKPOINT \
|
||||
AFD_DbgPrint(MIN_TRACE, ("\n"));
|
||||
|
||||
#define CP CHECKPOINT
|
||||
|
||||
#endif /* __DEBUG_H */
|
||||
|
||||
/* EOF */
|
62
reactos/lib/msafd/include/helpers.h
Normal file
62
reactos/lib/msafd/include/helpers.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: include/helpers.h
|
||||
* PURPOSE: Definitions for helper DLL management
|
||||
*/
|
||||
#ifndef __HELPERS_H
|
||||
#define __HELPERS_H
|
||||
|
||||
#include <msafd.h>
|
||||
|
||||
typedef struct _WSHELPER_DLL_ENTRIES {
|
||||
PWSH_ADDRESS_TO_STRING lpWSHAddressToString;
|
||||
PWSH_ENUM_PROTOCOLS lpWSHEnumProtocols;
|
||||
PWSH_GET_BROADCAST_SOCKADDR lpWSHGetBroadcastSockaddr;
|
||||
PWSH_GET_PROVIDER_GUID lpWSHGetProviderGuid;
|
||||
PWSH_GET_SOCKADDR_TYPE lpWSHGetSockaddrType;
|
||||
PWSH_GET_SOCKET_INFORMATION lpWSHGetSocketInformation;
|
||||
PWSH_GET_WILDCARD_SOCKEADDR lpWSHGetWildcardSockaddr;
|
||||
PWSH_GET_WINSOCK_MAPPING lpWSHGetWinsockMapping;
|
||||
PWSH_GET_WSAPROTOCOL_INFO lpWSHGetWSAProtocolInfo;
|
||||
PWSH_IOCTL lpWSHIoctl;
|
||||
PWSH_JOIN_LEAF lpWSHJoinLeaf;
|
||||
PWSH_NOTIFY lpWSHNotify;
|
||||
PWSH_OPEN_SOCKET lpWSHOpenSocket;
|
||||
PWSH_OPEN_SOCKET2 lpWSHOpenSocket2;
|
||||
PWSH_SET_SOCKET_INFORMATION lpWSHSetSocketInformation;
|
||||
PWSH_STRING_TO_ADDRESS lpWSHStringToAddress;
|
||||
} WSHELPER_DLL_ENTRIES, *PWSHELPER_DLL_ENTRIES;
|
||||
|
||||
typedef struct _WSHELPER_DLL {
|
||||
LIST_ENTRY ListEntry;
|
||||
CRITICAL_SECTION Lock;
|
||||
WCHAR LibraryName[MAX_PATH];
|
||||
HMODULE hModule;
|
||||
WSHELPER_DLL_ENTRIES EntryTable;
|
||||
PWINSOCK_MAPPING Mapping;
|
||||
} WSHELPER_DLL, *PWSHELPER_DLL;
|
||||
|
||||
|
||||
PWSHELPER_DLL CreateHelperDLL(
|
||||
LPWSTR LibraryName);
|
||||
|
||||
INT DestroyHelperDLL(
|
||||
PWSHELPER_DLL HelperDLL);
|
||||
|
||||
PWSHELPER_DLL LocateHelperDLL(
|
||||
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
||||
|
||||
INT LoadHelperDLL(
|
||||
PWSHELPER_DLL HelperDLL);
|
||||
|
||||
INT UnloadHelperDLL(
|
||||
PWSHELPER_DLL HelperDLL);
|
||||
|
||||
VOID CreateHelperDLLDatabase(VOID);
|
||||
|
||||
VOID DestroyHelperDLLDatabase(VOID);
|
||||
|
||||
#endif /* __HELPERS_H */
|
||||
|
||||
/* EOF */
|
310
reactos/lib/msafd/include/msafd.h
Normal file
310
reactos/lib/msafd/include/msafd.h
Normal file
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: include/msafd.h
|
||||
* PURPOSE: Ancillary Function Driver DLL header
|
||||
*/
|
||||
#ifndef __MSAFD_H
|
||||
#define __MSAFD_H
|
||||
|
||||
#include <wsahelp.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2spi.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <windows.h>
|
||||
#include <net/tdi.h>
|
||||
#include <afd/shared.h>
|
||||
#include <debug.h>
|
||||
|
||||
extern HANDLE GlobalHeap;
|
||||
extern WSPUPCALLTABLE Upcalls;
|
||||
extern LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
|
||||
|
||||
SOCKET
|
||||
WSPAPI
|
||||
WSPAccept(
|
||||
IN SOCKET s,
|
||||
OUT LPSOCKADDR addr,
|
||||
IN OUT LPINT addrlen,
|
||||
IN LPCONDITIONPROC lpfnCondition,
|
||||
IN DWORD dwCallbackData,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPAddressToString(
|
||||
IN LPSOCKADDR lpsaAddress,
|
||||
IN DWORD dwAddressLength,
|
||||
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
OUT LPWSTR lpszAddressString,
|
||||
IN OUT LPDWORD lpdwAddressStringLength,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPAsyncSelect(
|
||||
IN SOCKET s,
|
||||
IN HWND hWnd,
|
||||
IN UINT wMsg,
|
||||
IN LONG lEvent,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI WSPBind(
|
||||
IN SOCKET s,
|
||||
IN CONST LPSOCKADDR name,
|
||||
IN INT namelen,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPCancelBlockingCall(
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPCleanup(
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPCloseSocket(
|
||||
IN SOCKET s,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPConnect(
|
||||
IN SOCKET s,
|
||||
IN CONST LPSOCKADDR name,
|
||||
IN INT namelen,
|
||||
IN LPWSABUF lpCallerData,
|
||||
OUT LPWSABUF lpCalleeData,
|
||||
IN LPQOS lpSQOS,
|
||||
IN LPQOS lpGQOS,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPDuplicateSocket(
|
||||
IN SOCKET s,
|
||||
IN DWORD dwProcessId,
|
||||
OUT LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPEnumNetworkEvents(
|
||||
IN SOCKET s,
|
||||
IN WSAEVENT hEventObject,
|
||||
OUT LPWSANETWORKEVENTS lpNetworkEvents,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPEventSelect(
|
||||
IN SOCKET s,
|
||||
IN WSAEVENT hEventObject,
|
||||
IN LONG lNetworkEvents,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
BOOL
|
||||
WSPAPI
|
||||
WSPGetOverlappedResult(
|
||||
IN SOCKET s,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
OUT LPDWORD lpcbTransfer,
|
||||
IN BOOL fWait,
|
||||
OUT LPDWORD lpdwFlags,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPGetPeerName(
|
||||
IN SOCKET s,
|
||||
OUT LPSOCKADDR name,
|
||||
IN OUT LPINT namelen,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
BOOL
|
||||
WSPAPI
|
||||
WSPGetQOSByName(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpQOSName,
|
||||
OUT LPQOS lpQOS,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPGetSockName(
|
||||
IN SOCKET s,
|
||||
OUT LPSOCKADDR name,
|
||||
IN OUT LPINT namelen,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPGetSockOpt(
|
||||
IN SOCKET s,
|
||||
IN INT level,
|
||||
IN INT optname,
|
||||
OUT CHAR FAR* optval,
|
||||
IN OUT LPINT optlen,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPIoctl(
|
||||
IN SOCKET s,
|
||||
IN DWORD dwIoControlCode,
|
||||
IN LPVOID lpvInBuffer,
|
||||
IN DWORD cbInBuffer,
|
||||
OUT LPVOID lpvOutBuffer,
|
||||
IN DWORD cbOutBuffer,
|
||||
OUT LPDWORD lpcbBytesReturned,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
SOCKET
|
||||
WSPAPI
|
||||
WSPJoinLeaf(
|
||||
IN SOCKET s,
|
||||
IN CONST LPSOCKADDR name,
|
||||
IN INT namelen,
|
||||
IN LPWSABUF lpCallerData,
|
||||
OUT LPWSABUF lpCalleeData,
|
||||
IN LPQOS lpSQOS,
|
||||
IN LPQOS lpGQOS,
|
||||
IN DWORD dwFlags,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPListen(
|
||||
IN SOCKET s,
|
||||
IN INT backlog,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPRecv(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPRecvDisconnect(
|
||||
IN SOCKET s,
|
||||
OUT LPWSABUF lpInboundDisconnectData,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPRecvFrom(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
OUT LPSOCKADDR lpFrom,
|
||||
IN OUT LPINT lpFromlen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
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);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSend(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSendDisconnect(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpOutboundDisconnectData,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSendTo(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN CONST LPSOCKADDR lpTo,
|
||||
IN INT iTolen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSetSockOpt(
|
||||
IN SOCKET s,
|
||||
IN INT level,
|
||||
IN INT optname,
|
||||
IN CONST CHAR FAR* optval,
|
||||
IN INT optlen,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPShutdown(
|
||||
IN SOCKET s,
|
||||
IN INT how,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
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);
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPStringToAddress(
|
||||
IN LPWSTR AddressString,
|
||||
IN INT AddressFamily,
|
||||
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
OUT LPSOCKADDR lpAddress,
|
||||
IN OUT LPINT lpAddressLength,
|
||||
OUT LPINT lpErrno);
|
||||
|
||||
#endif /* __MSAFD_H */
|
||||
|
||||
/* EOF */
|
94
reactos/lib/msafd/makefile
Normal file
94
reactos/lib/msafd/makefile
Normal file
|
@ -0,0 +1,94 @@
|
|||
# Makefile for ReactOS Ancillary Function Driver DLL
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
CFLAGS = -I./include -DUNICODE
|
||||
|
||||
TARGETNAME=msafd
|
||||
|
||||
MISC_OBJECTS = misc/dllmain.o misc/helpers.o misc/sndrcv.o misc/stubs.o
|
||||
|
||||
RESOURCE_OBJECT = $(TARGETNAME).coff
|
||||
|
||||
OBJECTS = $(MISC_OBJECTS) $(RESOURCE_OBJECT)
|
||||
|
||||
LIBS = ../ntdll/ntdll.a \
|
||||
../kernel32/kernel32.a
|
||||
|
||||
ifeq ($(DOSCLI),yes)
|
||||
CLEAN_FILES = misc\*.o \
|
||||
$(TARGETNAME).o $(TARGETNAME).a junk.tmp base.tmp temp.exp \
|
||||
$(TARGETNAME).dll $(TARGETNAME).sym $(TARGETNAME).coff
|
||||
else
|
||||
CLEAN_FILES = misc/*.o \
|
||||
$(TARGETNAME).o $(TARGETNAME).a junk.tmp base.tmp temp.exp \
|
||||
$(TARGETNAME).dll $(TARGETNAME).sym $(TARGETNAME).coff
|
||||
endif
|
||||
|
||||
all: $(TARGETNAME).dll
|
||||
|
||||
$(TARGETNAME).coff: $(TARGETNAME).rc ../../include/reactos/resource.h
|
||||
|
||||
$(TARGETNAME).a: $(OBJECTS)
|
||||
$(LD) -r $(OBJECTS) -o $(TARGETNAME).a
|
||||
|
||||
$(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
||||
$(LD) -r $(OBJECTS) -o $(TARGETNAME).o
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGETNAME).dll \
|
||||
--def $(TARGETNAME).def \
|
||||
--kill-at \
|
||||
--output-lib $(TARGETNAME).a
|
||||
$(CC) \
|
||||
$(TARGETNAME).o \
|
||||
$(LIBS) \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--base-file,base.tmp
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGETNAME).dll \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--def $(TARGETNAME).edf
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
$(TARGETNAME).o \
|
||||
$(LIBS) \
|
||||
-mdll \
|
||||
-o $(TARGETNAME).dll \
|
||||
-Wl,--image-base,0x777A0000 \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,temp.exp
|
||||
- $(RM) temp.exp
|
||||
$(NM) --numeric-sort $(TARGETNAME).dll > $(TARGETNAME).sym
|
||||
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||
- $(RM) $*
|
||||
|
||||
.PHONY: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
install: $(FLOPPY_DIR)/dlls/$(TARGETNAME).dll
|
||||
|
||||
$(FLOPPY_DIR)/dlls/$(TARGETNAME).dll: $(TARGETNAME).dll
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGETNAME).dll $(FLOPPY_DIR)\dlls\$(TARGETNAME).dll
|
||||
else
|
||||
$(CP) $(TARGETNAME).dll $(FLOPPY_DIR)/dlls/$(TARGETNAME).dll
|
||||
endif
|
||||
|
||||
dist: $(DIST_DIR)/dlls/$(TARGETNAME).dll
|
||||
|
||||
$(DIST_DIR)/dlls/$(TARGETNAME).dll: $(TARGETNAME).dll
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGETNAME).dll ..\..\$(DIST_DIR)\dlls\$(TARGETNAME).dll
|
||||
else
|
||||
$(CP) $(TARGETNAME).dll ../../$(DIST_DIR)/dlls/$(TARGETNAME).dll
|
||||
endif
|
||||
|
||||
include ../../rules.mak
|
||||
|
561
reactos/lib/msafd/misc/dllmain.c
Normal file
561
reactos/lib/msafd/misc/dllmain.c
Normal file
|
@ -0,0 +1,561 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: misc/dllmain.c
|
||||
* PURPOSE: DLL entry point
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <msafd.h>
|
||||
#include <helpers.h>
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
/* To make the linker happy */
|
||||
VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
|
||||
|
||||
|
||||
HANDLE GlobalHeap;
|
||||
WSPUPCALLTABLE Upcalls;
|
||||
LPWPUCOMPLETEOVERLAPPEDREQUEST lpWPUCompleteOverlappedRequest;
|
||||
CRITICAL_SECTION InitCriticalSection;
|
||||
DWORD StartupCount = 0;
|
||||
|
||||
NTSTATUS OpenSocket(
|
||||
SOCKET *Socket,
|
||||
INT AddressFamily,
|
||||
INT SocketType,
|
||||
INT Protocol,
|
||||
PVOID HelperContext,
|
||||
DWORD NotificationEvents,
|
||||
PUNICODE_STRING TdiDeviceName)
|
||||
/*
|
||||
* FUNCTION: Opens a socket
|
||||
* ARGUMENTS:
|
||||
* Socket = Address of buffer to place socket descriptor
|
||||
* AddressFamily = Address family
|
||||
* SocketType = Type of socket
|
||||
* Protocol = Protocol type
|
||||
* HelperContext = Pointer to context information for helper DLL
|
||||
* NotificationEvents = Events for which helper DLL is to be notified
|
||||
* TdiDeviceName = Pointer to name of TDI device to use
|
||||
* 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;
|
||||
|
||||
CP
|
||||
|
||||
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
|
||||
AFD_SOCKET_LENGTH +
|
||||
sizeof(AFD_SOCKET_INFORMATION) +
|
||||
TdiDeviceName->Length + 1;
|
||||
|
||||
EaInfo = (PFILE_FULL_EA_INFORMATION)HeapAlloc(GlobalHeap, 0, EaLength);
|
||||
if (!EaInfo) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
RtlZeroMemory(EaInfo, EaLength);
|
||||
EaInfo->EaNameLength = AFD_SOCKET_LENGTH;
|
||||
RtlCopyMemory(EaInfo->EaName,
|
||||
AfdSocket,
|
||||
AFD_SOCKET_LENGTH);
|
||||
EaInfo->EaValueLength = sizeof(AFD_SOCKET_INFORMATION);
|
||||
|
||||
CP
|
||||
|
||||
SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + AFD_SOCKET_LENGTH);
|
||||
|
||||
SocketInfo->AddressFamily = AddressFamily;
|
||||
SocketInfo->SocketType = SocketType;
|
||||
SocketInfo->Protocol = Protocol;
|
||||
SocketInfo->HelperContext = HelperContext;
|
||||
SocketInfo->NotificationEvents = NotificationEvents;
|
||||
|
||||
/* Store TDI device name last in buffer */
|
||||
SocketInfo->TdiDeviceName.Buffer = (PWCHAR)(EaInfo + EaLength);
|
||||
//SocketInfo->TdiDeviceName.Length = TdiDeviceName.Length;
|
||||
SocketInfo->TdiDeviceName.MaximumLength = TdiDeviceName->Length;
|
||||
RtlCopyUnicodeString(&SocketInfo->TdiDeviceName, TdiDeviceName);
|
||||
/*RtlCopyMemory(SocketInfo->TdiDeviceName.Buffer,
|
||||
TdiDeviceName.Buffer,
|
||||
TdiDeviceName.Length + 1);*/
|
||||
|
||||
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);
|
||||
|
||||
CP
|
||||
|
||||
Status = NtCreateFile(&FileHandle,
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
&ObjectAttributes,
|
||||
&Iosb,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
FILE_OPEN,
|
||||
FILE_SYNCHRONOUS_IO_ALERT,
|
||||
EaInfo,
|
||||
EaLength);
|
||||
|
||||
CP
|
||||
|
||||
HeapFree(GlobalHeap, 0, EaInfo);
|
||||
|
||||
CP
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Error opening device (Status 0x%X).\n", (UINT)Status));
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
*Socket = (SOCKET)FileHandle;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SOCKET
|
||||
WSPAPI
|
||||
WSPSocket(
|
||||
IN INT af,
|
||||
IN INT type,
|
||||
IN INT protocol,
|
||||
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
IN GROUP g,
|
||||
IN DWORD dwFlags,
|
||||
OUT LPINT lpErrno)
|
||||
/*
|
||||
* FUNCTION: Creates a new socket
|
||||
* ARGUMENTS:
|
||||
* af = Address family
|
||||
* type = Socket type
|
||||
* protocol = Protocol type
|
||||
* lpProtocolInfo = Pointer to protocol information
|
||||
* g = Reserved
|
||||
* dwFlags = Socket flags
|
||||
* lpErrno = Address of buffer for error information
|
||||
* RETURNS:
|
||||
* Created socket, or INVALID_SOCKET if it could not be created
|
||||
*/
|
||||
{
|
||||
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||
UNICODE_STRING TdiDeviceName;
|
||||
DWORD NotificationEvents;
|
||||
PWSHELPER_DLL HelperDLL;
|
||||
PVOID HelperContext;
|
||||
INT AddressFamily;
|
||||
NTSTATUS NtStatus;
|
||||
INT SocketType;
|
||||
SOCKET Socket2;
|
||||
SOCKET Socket;
|
||||
INT Protocol;
|
||||
INT Status;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
|
||||
af, type, protocol));
|
||||
|
||||
if (!lpProtocolInfo) {
|
||||
CP
|
||||
lpProtocolInfo = &ProtocolInfo;
|
||||
ZeroMemory(&ProtocolInfo, sizeof(WSAPROTOCOL_INFOW));
|
||||
|
||||
ProtocolInfo.iAddressFamily = af;
|
||||
ProtocolInfo.iSocketType = type;
|
||||
ProtocolInfo.iProtocol = protocol;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
HelperDLL = LocateHelperDLL(lpProtocolInfo);
|
||||
if (!HelperDLL) {
|
||||
*lpErrno = WSAEAFNOSUPPORT;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
CP
|
||||
AddressFamily = lpProtocolInfo->iAddressFamily;
|
||||
SocketType = lpProtocolInfo->iSocketType;
|
||||
Protocol = lpProtocolInfo->iProtocol;
|
||||
CP
|
||||
Status = HelperDLL->EntryTable.lpWSHOpenSocket2(&AddressFamily,
|
||||
&SocketType,
|
||||
&Protocol,
|
||||
0,
|
||||
0,
|
||||
&TdiDeviceName,
|
||||
&HelperContext,
|
||||
&NotificationEvents);
|
||||
if (Status != NO_ERROR) {
|
||||
*lpErrno = Status;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
CP
|
||||
NtStatus = OpenSocket(&Socket,
|
||||
AddressFamily,
|
||||
SocketType,
|
||||
Protocol,
|
||||
HelperContext,
|
||||
NotificationEvents,
|
||||
&TdiDeviceName);
|
||||
CP
|
||||
RtlFreeUnicodeString(&TdiDeviceName);
|
||||
if (!NT_SUCCESS(NtStatus)) {
|
||||
CP
|
||||
*lpErrno = RtlNtStatusToDosError(Status);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
CP
|
||||
/* FIXME: Assumes catalog entry id to be 1 */
|
||||
Socket2 = Upcalls.lpWPUModifyIFSHandle(1, Socket, lpErrno);
|
||||
CP
|
||||
if (Socket2 == INVALID_SOCKET) {
|
||||
/* FIXME: Cleanup */
|
||||
AFD_DbgPrint(MIN_TRACE, ("FIXME: Cleanup.\n"));
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
*lpErrno = NO_ERROR;
|
||||
|
||||
AFD_DbgPrint(MID_TRACE, ("Returning socket descriptor (0x%X).\n", Socket2));
|
||||
|
||||
return Socket2;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPCloseSocket(
|
||||
IN SOCKET s,
|
||||
OUT LPINT lpErrno)
|
||||
/*
|
||||
* FUNCTION: Closes an open socket
|
||||
* ARGUMENTS:
|
||||
* s = Socket descriptor
|
||||
* lpErrno = Address of buffer for error information
|
||||
* RETURNS:
|
||||
* NO_ERROR, or SOCKET_ERROR if the socket could not be closed
|
||||
*/
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
|
||||
|
||||
Status = NtClose((HANDLE)s);
|
||||
CP
|
||||
if (NT_SUCCESS(Status)) {
|
||||
*lpErrno = NO_ERROR;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
*lpErrno = WSAENOTSOCK;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPBind(
|
||||
IN SOCKET s,
|
||||
IN CONST LPSOCKADDR name,
|
||||
IN INT namelen,
|
||||
OUT LPINT lpErrno)
|
||||
/*
|
||||
* FUNCTION: Associates a local address with a socket
|
||||
* ARGUMENTS:
|
||||
* s = Socket descriptor
|
||||
* name = Pointer to local address
|
||||
* namelen = Length of name
|
||||
* lpErrno = Address of buffer for error information
|
||||
* RETURNS:
|
||||
* 0, or SOCKET_ERROR if the socket could not be bound
|
||||
*/
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("s (0x%X) name (0x%X) namelen (%d).\n", s, name, namelen));
|
||||
|
||||
#if 0
|
||||
FILE_REQUEST_BIND Request;
|
||||
FILE_REPLY_BIND Reply;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
|
||||
RtlCopyMemory(&Request.Name, name, sizeof(SOCKADDR));
|
||||
|
||||
Status = NtDeviceIoControlFile((HANDLE)s,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
IOCTL_AFD_BIND,
|
||||
&Request,
|
||||
sizeof(FILE_REQUEST_BIND),
|
||||
&Reply,
|
||||
sizeof(FILE_REPLY_BIND));
|
||||
|
||||
if (Status == STATUS_PENDING) {
|
||||
if (!NT_SUCCESS(NtWaitForSingleObject((HANDLE)s, FALSE, NULL))) {
|
||||
/* FIXME: What error code should be returned? */
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
/*
|
||||
* FUNCTION: Returns status of one or more sockets
|
||||
* ARGUMENTS:
|
||||
* nfds = Always ignored
|
||||
* readfds = Pointer to socket set to be checked for readability (optional)
|
||||
* writefds = Pointer to socket set to be checked for writability (optional)
|
||||
* exceptfds = Pointer to socket set to be checked for errors (optional)
|
||||
* timeout = Pointer to a TIMEVAL structure indicating maximum wait time
|
||||
* (NULL means wait forever)
|
||||
* lpErrno = Address of buffer for error information
|
||||
* RETURNS:
|
||||
* Number of ready socket descriptors, or SOCKET_ERROR if an error ocurred
|
||||
*/
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n",
|
||||
readfds, writefds, exceptfds));
|
||||
|
||||
/* FIXME: For now, always allow write */
|
||||
if (writefds != NULL) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Setting one socket writeable.\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPStartup(
|
||||
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:
|
||||
* wVersionRequested = Highest WinSock SPI version that the caller can use
|
||||
* lpWSPData = Address of WSPDATA structure to initialize
|
||||
* lpProtocolInfo = Pointer to structure that defines the desired protocol
|
||||
* UpcallTable = Pointer to upcall table of the WinSock DLL
|
||||
* lpProcTable = Address of procedure table to initialize
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
HMODULE hWS2_32;
|
||||
INT Status;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("wVersionRequested (0x%X) \n", wVersionRequested));
|
||||
|
||||
//EnterCriticalSection(&InitCriticalSection);
|
||||
|
||||
Upcalls = UpcallTable;
|
||||
|
||||
if (StartupCount == 0) {
|
||||
/* First time called */
|
||||
|
||||
Status = WSAVERNOTSUPPORTED;
|
||||
|
||||
CP
|
||||
|
||||
hWS2_32 = GetModuleHandle(L"ws2_32.dll");
|
||||
|
||||
CP
|
||||
|
||||
if (hWS2_32) {
|
||||
CP
|
||||
lpWPUCompleteOverlappedRequest = (LPWPUCOMPLETEOVERLAPPEDREQUEST)
|
||||
GetProcAddress(hWS2_32, "WPUCompleteOverlappedRequest");
|
||||
CP
|
||||
if (lpWPUCompleteOverlappedRequest) {
|
||||
Status = NO_ERROR;
|
||||
StartupCount++;
|
||||
}
|
||||
CP
|
||||
}
|
||||
} else {
|
||||
Status = NO_ERROR;
|
||||
StartupCount++;
|
||||
}
|
||||
|
||||
//LeaveCriticalSection(&InitCriticalSection);
|
||||
|
||||
if (Status == NO_ERROR) {
|
||||
CP
|
||||
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);
|
||||
CP
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Status (%d).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPCleanup(
|
||||
OUT LPINT lpErrno)
|
||||
/*
|
||||
* FUNCTION: Cleans up service provider for a client
|
||||
* ARGUMENTS:
|
||||
* lpErrno = Address of buffer for error information
|
||||
* RETURNS:
|
||||
* 0 if successful, or SOCKET_ERROR if not
|
||||
*/
|
||||
{
|
||||
AFD_DbgPrint(MAX_TRACE, ("\n"));
|
||||
|
||||
//EnterCriticalSection(&InitCriticalSection);
|
||||
|
||||
if (StartupCount > 0) {
|
||||
StartupCount--;
|
||||
|
||||
if (StartupCount == 0) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Cleaning up msafd.dll.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
//LeaveCriticalSection(&InitCriticalSection);
|
||||
|
||||
*lpErrno = NO_ERROR;
|
||||
|
||||
CP
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
DllMain(HANDLE hInstDll,
|
||||
ULONG dwReason,
|
||||
PVOID Reserved)
|
||||
{
|
||||
AFD_DbgPrint(MIN_TRACE, ("DllMain of msafd.dll\n"));
|
||||
|
||||
switch (dwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
CP
|
||||
/* Don't need thread attach notifications
|
||||
so disable them to improve performance */
|
||||
DisableThreadLibraryCalls(hInstDll);
|
||||
|
||||
CP
|
||||
|
||||
//InitializeCriticalSection(&InitCriticalSection);
|
||||
|
||||
GlobalHeap = GetProcessHeap();
|
||||
//GlobalHeap = HeapCreate(0, 0, 0);
|
||||
if (!GlobalHeap) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
CreateHelperDLLDatabase();
|
||||
|
||||
CP
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
CP
|
||||
DestroyHelperDLLDatabase();
|
||||
//HeapDestroy(GlobalHeap);
|
||||
|
||||
//DeleteCriticalSection(&InitCriticalSection);
|
||||
break;
|
||||
}
|
||||
CP
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
251
reactos/lib/msafd/misc/helpers.c
Normal file
251
reactos/lib/msafd/misc/helpers.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: misc/helpers.c
|
||||
* PURPOSE: Helper DLL management
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <msafd.h>
|
||||
#include <helpers.h>
|
||||
|
||||
//CRITICAL_SECTION HelperDLLDatabaseLock;
|
||||
LIST_ENTRY HelperDLLDatabaseListHead;
|
||||
|
||||
PWSHELPER_DLL CreateHelperDLL(
|
||||
LPWSTR LibraryName)
|
||||
{
|
||||
PWSHELPER_DLL HelperDLL;
|
||||
|
||||
HelperDLL = HeapAlloc(GlobalHeap, 0, sizeof(WSHELPER_DLL));
|
||||
if (!HelperDLL) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//InitializeCriticalSection(&HelperDLL->Lock);
|
||||
HelperDLL->hModule = NULL;
|
||||
lstrcpyW(HelperDLL->LibraryName, LibraryName);
|
||||
HelperDLL->Mapping = NULL;
|
||||
|
||||
//EnterCriticalSection(&HelperDLLDatabaseLock);
|
||||
InsertTailList(&HelperDLLDatabaseListHead, &HelperDLL->ListEntry);
|
||||
//LeaveCriticalSection(&HelperDLLDatabaseLock);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Returning helper at (0x%X).\n", HelperDLL));
|
||||
|
||||
return HelperDLL;
|
||||
}
|
||||
|
||||
|
||||
INT DestroyHelperDLL(
|
||||
PWSHELPER_DLL HelperDLL)
|
||||
{
|
||||
INT Status;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X).\n", HelperDLL));
|
||||
|
||||
//EnterCriticalSection(&HelperDLLDatabaseLock);
|
||||
RemoveEntryList(&HelperDLL->ListEntry);
|
||||
//LeaveCriticalSection(&HelperDLLDatabaseLock);
|
||||
|
||||
CP
|
||||
|
||||
if (HelperDLL->hModule) {
|
||||
Status = UnloadHelperDLL(HelperDLL);
|
||||
} else {
|
||||
Status = NO_ERROR;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
if (HelperDLL->Mapping)
|
||||
HeapFree(GlobalHeap, 0, HelperDLL->Mapping);
|
||||
|
||||
//DeleteCriticalSection(&HelperDLL->Lock);
|
||||
|
||||
HeapFree(GlobalHeap, 0, HelperDLL);
|
||||
|
||||
CP
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
PWSHELPER_DLL LocateHelperDLL(
|
||||
LPWSAPROTOCOL_INFOW lpProtocolInfo)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PWSHELPER_DLL HelperDLL;
|
||||
UINT i;
|
||||
|
||||
//EnterCriticalSection(&HelperDLLDatabaseLock);
|
||||
CurrentEntry = HelperDLLDatabaseListHead.Flink;
|
||||
while (CurrentEntry != &HelperDLLDatabaseListHead) {
|
||||
HelperDLL = CONTAINING_RECORD(CurrentEntry,
|
||||
WSHELPER_DLL,
|
||||
ListEntry);
|
||||
|
||||
for (i = 0; i < HelperDLL->Mapping->Rows; i++) {
|
||||
if ((lpProtocolInfo->iAddressFamily == HelperDLL->Mapping->Mapping[i].AddressFamily) &&
|
||||
(lpProtocolInfo->iSocketType == HelperDLL->Mapping->Mapping[i].SocketType) &&
|
||||
((lpProtocolInfo->iProtocol == HelperDLL->Mapping->Mapping[i].Protocol) ||
|
||||
(lpProtocolInfo->iSocketType == SOCK_RAW))) {
|
||||
//LeaveCriticalSection(&HelperDLLDatabaseLock);
|
||||
AFD_DbgPrint(MAX_TRACE, ("Returning helper DLL at (0x%X).\n", HelperDLL));
|
||||
return HelperDLL;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
//LeaveCriticalSection(&HelperDLLDatabaseLock);
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Could not locate helper DLL.\n"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#define GET_ENTRY_POINT(helper, name) { \
|
||||
PVOID entry; \
|
||||
\
|
||||
entry = GetProcAddress(helper->hModule, "##name"); \
|
||||
if (!entry) \
|
||||
return ERROR_BAD_PROVIDER; \
|
||||
(*(PULONG*)helper->EntryTable.lp##name) = entry; \
|
||||
}
|
||||
|
||||
|
||||
INT GetHelperDLLEntries(
|
||||
PWSHELPER_DLL HelperDLL)
|
||||
{
|
||||
GET_ENTRY_POINT(HelperDLL, WSHAddressToString);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHEnumProtocols);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetBroadcastSockaddr);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetProviderGuid);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetSockaddrType);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetSocketInformation);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetWildcardSockaddr);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetWinsockMapping);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHGetWSAProtocolInfo);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHIoctl);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHJoinLeaf);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHNotify);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHOpenSocket);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHOpenSocket2);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHSetSocketInformation);
|
||||
GET_ENTRY_POINT(HelperDLL, WSHStringToAddress);
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
INT LoadHelperDLL(
|
||||
PWSHELPER_DLL HelperDLL)
|
||||
{
|
||||
INT Status = NO_ERROR;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Loading helper dll at (0x%X).\n", HelperDLL));
|
||||
|
||||
if (!HelperDLL->hModule) {
|
||||
/* DLL is not loaded so load it now */
|
||||
HelperDLL->hModule = LoadLibrary(HelperDLL->LibraryName);
|
||||
if (HelperDLL->hModule) {
|
||||
Status = GetHelperDLLEntries(HelperDLL);
|
||||
} else
|
||||
Status = ERROR_DLL_NOT_FOUND;
|
||||
} else
|
||||
Status = NO_ERROR;
|
||||
|
||||
AFD_DbgPrint(MIN_TRACE, ("Status (%d).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
INT UnloadHelperDLL(
|
||||
PWSHELPER_DLL HelperDLL)
|
||||
{
|
||||
INT Status = NO_ERROR;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X).\n", HelperDLL));
|
||||
|
||||
if (HelperDLL->hModule) {
|
||||
if (!FreeLibrary(HelperDLL->hModule))
|
||||
Status = GetLastError();
|
||||
|
||||
HelperDLL->hModule = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID CreateHelperDLLDatabase(VOID)
|
||||
{
|
||||
PWSHELPER_DLL HelperDLL;
|
||||
|
||||
CP
|
||||
|
||||
//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"));
|
||||
return;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
HelperDLL->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
|
||||
if (!HelperDLL->Mapping) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
HelperDLL->Mapping->Rows = 1;
|
||||
HelperDLL->Mapping->Columns = 3;
|
||||
HelperDLL->Mapping->Mapping[0].AddressFamily = AF_INET;
|
||||
HelperDLL->Mapping->Mapping[0].SocketType = SOCK_RAW;
|
||||
HelperDLL->Mapping->Mapping[0].Protocol = 0;
|
||||
|
||||
CP
|
||||
|
||||
LoadHelperDLL(HelperDLL);
|
||||
|
||||
CP
|
||||
}
|
||||
|
||||
|
||||
VOID DestroyHelperDLLDatabase(VOID)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PWSHELPER_DLL HelperDLL;
|
||||
|
||||
CP
|
||||
|
||||
CurrentEntry = HelperDLLDatabaseListHead.Flink;
|
||||
while (CurrentEntry != &HelperDLLDatabaseListHead) {
|
||||
NextEntry = CurrentEntry->Flink;
|
||||
HelperDLL = CONTAINING_RECORD(CurrentEntry,
|
||||
WSHELPER_DLL,
|
||||
ListEntry);
|
||||
|
||||
DestroyHelperDLL(HelperDLL);
|
||||
|
||||
CurrentEntry = NextEntry;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
//DeleteCriticalSection(&HelperDLLDatabaseLock);
|
||||
}
|
||||
|
||||
/* EOF */
|
247
reactos/lib/msafd/misc/sndrcv.c
Normal file
247
reactos/lib/msafd/misc/sndrcv.c
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: misc/sndrcv.c
|
||||
* PURPOSE: Send/receive routines
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <msafd.h>
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPAsyncSelect(
|
||||
IN SOCKET s,
|
||||
IN HWND hWnd,
|
||||
IN UINT wMsg,
|
||||
IN LONG lEvent,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPRecv(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPRecvDisconnect(
|
||||
IN SOCKET s,
|
||||
OUT LPWSABUF lpInboundDisconnectData,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPRecvFrom(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
OUT LPSOCKADDR lpFrom,
|
||||
IN OUT LPINT lpFromLen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
PFILE_REQUEST_RECVFROM Request;
|
||||
FILE_REPLY_RECVFROM Reply;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
DWORD Size;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
Size = dwBufferCount * sizeof(WSABUF);
|
||||
|
||||
Request = (PFILE_REQUEST_RECVFROM)HeapAlloc(
|
||||
GlobalHeap, 0, sizeof(FILE_REQUEST_RECVFROM) + Size);
|
||||
if (!Request) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
/* Put buffer pointers after request structure */
|
||||
Request->Buffers = (LPWSABUF)(Request + sizeof(FILE_REQUEST_RECVFROM));
|
||||
Request->BufferCount = dwBufferCount;
|
||||
Request->Flags = lpFlags;
|
||||
Request->From = lpFrom;
|
||||
Request->FromLen = lpFromLen;
|
||||
|
||||
RtlCopyMemory(Request->Buffers, lpBuffers, Size);
|
||||
|
||||
Status = NtDeviceIoControlFile((HANDLE)s,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
IOCTL_AFD_RECVFROM,
|
||||
Request,
|
||||
sizeof(FILE_REQUEST_RECVFROM) + Size,
|
||||
&Reply,
|
||||
sizeof(FILE_REPLY_RECVFROM));
|
||||
|
||||
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((HANDLE)s, FALSE, NULL))) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Wait failed.\n"));
|
||||
/* FIXME: What error code should be returned? */
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Status (0x%X).\n", Status));
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Receive successful.\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSend(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSendDisconnect(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpOutboundDisconnectData,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSendTo(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN CONST LPSOCKADDR lpTo,
|
||||
IN INT iToLen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
PFILE_REQUEST_SENDTO Request;
|
||||
FILE_REPLY_SENDTO Reply;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
DWORD Size;
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
Size = dwBufferCount * sizeof(WSABUF);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Put buffer pointers after request structure */
|
||||
Request->Buffers = (LPWSABUF)(Request + sizeof(FILE_REQUEST_SENDTO));
|
||||
Request->BufferCount = dwBufferCount;
|
||||
Request->Flags = dwFlags;
|
||||
Request->ToLen = iToLen;
|
||||
|
||||
RtlCopyMemory(&Request->To, lpTo, sizeof(SOCKADDR));
|
||||
|
||||
RtlCopyMemory(Request->Buffers, lpBuffers, Size);
|
||||
|
||||
Status = NtDeviceIoControlFile((HANDLE)s,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&Iosb,
|
||||
IOCTL_AFD_SENDTO,
|
||||
Request,
|
||||
sizeof(FILE_REQUEST_SENDTO) + Size,
|
||||
&Reply,
|
||||
sizeof(FILE_REPLY_SENDTO));
|
||||
|
||||
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((HANDLE)s, FALSE, NULL))) {
|
||||
AFD_DbgPrint(MAX_TRACE, ("Wait failed.\n"));
|
||||
/* FIXME: What error code should be returned? */
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
AFD_DbgPrint(MIN_TRACE, ("Status (0x%X).\n", Status));
|
||||
*lpErrno = WSAENOBUFS;
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
AFD_DbgPrint(MAX_TRACE, ("Send successful.\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
287
reactos/lib/msafd/misc/stubs.c
Normal file
287
reactos/lib/msafd/misc/stubs.c
Normal file
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Ancillary Function Driver DLL
|
||||
* FILE: misc/stubs.c
|
||||
* PURPOSE: Stubs
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <msafd.h>
|
||||
|
||||
|
||||
SOCKET
|
||||
WSPAPI
|
||||
WSPAccept(
|
||||
IN SOCKET s,
|
||||
OUT LPSOCKADDR addr,
|
||||
IN OUT LPINT addrlen,
|
||||
IN LPCONDITIONPROC lpfnCondition,
|
||||
IN DWORD dwCallbackData,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPAddressToString(
|
||||
IN LPSOCKADDR lpsaAddress,
|
||||
IN DWORD dwAddressLength,
|
||||
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
OUT LPWSTR lpszAddressString,
|
||||
IN OUT LPDWORD lpdwAddressStringLength,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPCancelBlockingCall(
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPConnect(
|
||||
IN SOCKET s,
|
||||
IN CONST LPSOCKADDR name,
|
||||
IN INT namelen,
|
||||
IN LPWSABUF lpCallerData,
|
||||
OUT LPWSABUF lpCalleeData,
|
||||
IN LPQOS lpSQOS,
|
||||
IN LPQOS lpGQOS,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPDuplicateSocket(
|
||||
IN SOCKET s,
|
||||
IN DWORD dwProcessId,
|
||||
OUT LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPEnumNetworkEvents(
|
||||
IN SOCKET s,
|
||||
IN WSAEVENT hEventObject,
|
||||
OUT LPWSANETWORKEVENTS lpNetworkEvents,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPEventSelect(
|
||||
IN SOCKET s,
|
||||
IN WSAEVENT hEventObject,
|
||||
IN LONG lNetworkEvents,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
WSPAPI
|
||||
WSPGetOverlappedResult(
|
||||
IN SOCKET s,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
OUT LPDWORD lpcbTransfer,
|
||||
IN BOOL fWait,
|
||||
OUT LPDWORD lpdwFlags,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPGetPeerName(
|
||||
IN SOCKET s,
|
||||
OUT LPSOCKADDR name,
|
||||
IN OUT LPINT namelen,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
WSPAPI
|
||||
WSPGetQOSByName(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpQOSName,
|
||||
OUT LPQOS lpQOS,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPGetSockName(
|
||||
IN SOCKET s,
|
||||
OUT LPSOCKADDR name,
|
||||
IN OUT LPINT namelen,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPGetSockOpt(
|
||||
IN SOCKET s,
|
||||
IN INT level,
|
||||
IN INT optname,
|
||||
OUT CHAR FAR* optval,
|
||||
IN OUT LPINT optlen,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPIoctl(
|
||||
IN SOCKET s,
|
||||
IN DWORD dwIoControlCode,
|
||||
IN LPVOID lpvInBuffer,
|
||||
IN DWORD cbInBuffer,
|
||||
OUT LPVOID lpvOutBuffer,
|
||||
IN DWORD cbOutBuffer,
|
||||
OUT LPDWORD lpcbBytesReturned,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
|
||||
IN LPWSATHREADID lpThreadId,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SOCKET
|
||||
WSPAPI
|
||||
WSPJoinLeaf(
|
||||
IN SOCKET s,
|
||||
IN CONST LPSOCKADDR name,
|
||||
IN INT namelen,
|
||||
IN LPWSABUF lpCallerData,
|
||||
OUT LPWSABUF lpCalleeData,
|
||||
IN LPQOS lpSQOS,
|
||||
IN LPQOS lpGQOS,
|
||||
IN DWORD dwFlags,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return (SOCKET)0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPListen(
|
||||
IN SOCKET s,
|
||||
IN INT backlog,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPSetSockOpt(
|
||||
IN SOCKET s,
|
||||
IN INT level,
|
||||
IN INT optname,
|
||||
IN CONST CHAR FAR* optval,
|
||||
IN INT optlen,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPShutdown(
|
||||
IN SOCKET s,
|
||||
IN INT how,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
WSPAPI
|
||||
WSPStringToAddress(
|
||||
IN LPWSTR AddressString,
|
||||
IN INT AddressFamily,
|
||||
IN LPWSAPROTOCOL_INFOW lpProtocolInfo,
|
||||
OUT LPSOCKADDR lpAddress,
|
||||
IN OUT LPINT lpAddressLength,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
10
reactos/lib/msafd/msafd.def
Normal file
10
reactos/lib/msafd/msafd.def
Normal file
|
@ -0,0 +1,10 @@
|
|||
; MSAFD.DLL - Ancillary Function Driver DLL
|
||||
|
||||
LIBRARY msafd.dll
|
||||
|
||||
EXPORTS
|
||||
WSPGetSockOpt@24
|
||||
WSPSetSockOpt@24
|
||||
WSPStartup@76
|
||||
|
||||
; EOF
|
10
reactos/lib/msafd/msafd.edf
Normal file
10
reactos/lib/msafd/msafd.edf
Normal file
|
@ -0,0 +1,10 @@
|
|||
; MSAFD.DLL - Ancillary Function Driver DLL
|
||||
|
||||
LIBRARY msafd.dll
|
||||
|
||||
EXPORTS
|
||||
WSPGetSockOpt=WSPGetSockOpt@24
|
||||
WSPSetSockOpt=WSPSetSockOpt@24
|
||||
WSPStartup=WSPStartup@76
|
||||
|
||||
; EOF
|
39
reactos/lib/msafd/msafd.rc
Normal file
39
reactos/lib/msafd/msafd.rc
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "Ancillary Function Driver DLL\0"
|
||||
VALUE "FileVersion", RES_STR_FILE_VERSION
|
||||
VALUE "InternalName", "msafd\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "msafd.dll\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
|
|
@ -12,9 +12,11 @@
|
|||
|
||||
typedef struct _CATALOG_ENTRY {
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG ReferenceCount;
|
||||
CRITICAL_SECTION Lock;
|
||||
WCHAR LibraryName[MAX_PATH];
|
||||
HMODULE hModule;
|
||||
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||
PWINSOCK_MAPPING Mapping;
|
||||
LPWSPSTARTUP WSPStartup;
|
||||
WSPDATA WSPData;
|
||||
|
@ -23,6 +25,13 @@ typedef struct _CATALOG_ENTRY {
|
|||
|
||||
extern LIST_ENTRY Catalog;
|
||||
|
||||
|
||||
VOID ReferenceProviderByPointer(
|
||||
PCATALOG_ENTRY Provider);
|
||||
|
||||
VOID DereferenceProviderByPointer(
|
||||
PCATALOG_ENTRY Provider);
|
||||
|
||||
PCATALOG_ENTRY CreateCatalogEntry(
|
||||
LPWSTR LibraryName);
|
||||
|
||||
|
@ -32,6 +41,9 @@ INT DestroyCatalogEntry(
|
|||
PCATALOG_ENTRY LocateProvider(
|
||||
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
||||
|
||||
PCATALOG_ENTRY LocateProviderById(
|
||||
DWORD CatalogEntryId);
|
||||
|
||||
INT LoadProvider(
|
||||
PCATALOG_ENTRY Provider,
|
||||
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
||||
|
|
|
@ -21,16 +21,11 @@
|
|||
|
||||
extern DWORD DebugTraceLevel;
|
||||
|
||||
#define Get_DbgPrint(quote...) L##quote
|
||||
|
||||
#define WS_DbgPrint(_t_, _x_) \
|
||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||
WCHAR _buffer[256]; \
|
||||
swprintf(_buffer, L"(%S:%d)(%S) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
OutputDebugStringW(_buffer); \
|
||||
swprintf(_buffer, Get_DbgPrint _x_); \
|
||||
OutputDebugStringW(_buffer); \
|
||||
DbgPrint("(%hS:%d)(%hS) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
DbgPrint _x_; \
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
|
@ -63,7 +58,9 @@ extern DWORD DebugTraceLevel;
|
|||
WS_DbgPrint(MIN_TRACE, ("is unimplemented, please try again later.\n"));
|
||||
|
||||
#define CHECKPOINT \
|
||||
do { WS_DbgPrint(MIN_TRACE, ("\n")); } while(0);
|
||||
WS_DbgPrint(MIN_TRACE, ("\n"));
|
||||
|
||||
#define CP CHECKPOINT
|
||||
|
||||
#endif /* __DEBUG_H */
|
||||
|
||||
|
|
47
reactos/lib/ws2_32/include/handle.h
Normal file
47
reactos/lib/ws2_32/include/handle.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: include/handle.h
|
||||
* PURPOSE: Provider handle definitions
|
||||
*/
|
||||
#ifndef __HANDLE_H
|
||||
#define __HANDLE_H
|
||||
|
||||
#include <ws2_32.h>
|
||||
#include <catalog.h>
|
||||
|
||||
typedef struct _PROVIDER_HANDLE {
|
||||
HANDLE Handle;
|
||||
PCATALOG_ENTRY Provider;
|
||||
} PROVIDER_HANDLE, *PPROVIDER_HANDLE;
|
||||
|
||||
#define HANDLE_BLOCK_ENTRIES ((PAGESIZE-sizeof(LIST_ENTRY))/sizeof(PROVIDER_HANDLE))
|
||||
|
||||
typedef struct _PROVIDER_HANDLE_BLOCK {
|
||||
LIST_ENTRY Entry;
|
||||
PROVIDER_HANDLE Handles[HANDLE_BLOCK_ENTRIES];
|
||||
} PROVIDER_HANDLE_BLOCK, *PPROVIDER_HANDLE_BLOCK;
|
||||
|
||||
extern PPROVIDER_HANDLE_BLOCK ProviderHandleTable;
|
||||
|
||||
|
||||
HANDLE
|
||||
CreateProviderHandle(HANDLE Handle,
|
||||
PCATALOG_ENTRY Provider);
|
||||
|
||||
BOOL
|
||||
ReferenceProviderByHandle(HANDLE Handle,
|
||||
PCATALOG_ENTRY* Provider);
|
||||
|
||||
BOOL
|
||||
CloseProviderHandle(HANDLE Handle);
|
||||
|
||||
BOOL
|
||||
InitProviderHandleTable(VOID);
|
||||
|
||||
VOID
|
||||
FreeProviderHandleTable(VOID);
|
||||
|
||||
#endif /* __HANDLE_H */
|
||||
|
||||
/* EOF */
|
|
@ -26,6 +26,7 @@ extern WSPUPCALLTABLE UpcallTable;
|
|||
typedef struct _WINSOCK_THREAD_BLOCK {
|
||||
INT LastErrorValue; /* Error value from last function that failed */
|
||||
BOOL Initialized; /* TRUE if WSAStartup() has been successfully called */
|
||||
CHAR Intoa[16]; /* Buffer for inet_ntoa() */
|
||||
} WINSOCK_THREAD_BLOCK, *PWINSOCK_THREAD_BLOCK;
|
||||
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
CFLAGS = -Iinclude -DUNICODE
|
||||
CFLAGS = -Iinclude -DUNICODE -DDBG
|
||||
|
||||
TARGETNAME=ws2_32
|
||||
|
||||
MISC_OBJECTS = misc/dllmain.o misc/catalog.o misc/event.o misc/ns.o \
|
||||
misc/stubs.o misc/upcall.o
|
||||
MISC_OBJECTS = misc/dllmain.o misc/catalog.o misc/event.o misc/handle.o \
|
||||
misc/ns.o misc/sndrcv.o misc/stubs.o misc/upcall.o
|
||||
|
||||
RESOURCE_OBJECT = $(TARGETNAME).coff
|
||||
|
||||
|
@ -44,7 +44,6 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
|||
$(CC) \
|
||||
$(TARGETNAME).o \
|
||||
$(LIBS) \
|
||||
-specs=$(TARGETNAME)_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--base-file,base.tmp
|
||||
|
@ -58,10 +57,9 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
|||
$(CC) \
|
||||
$(TARGETNAME).o \
|
||||
$(LIBS) \
|
||||
-specs=$(TARGETNAME)_specs \
|
||||
-mdll \
|
||||
-o $(TARGETNAME).dll \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,--image-base,0x77780000 \
|
||||
-Wl,--file-alignment,0x1000 \
|
||||
-Wl,--section-alignment,0x1000 \
|
||||
-Wl,temp.exp
|
||||
|
|
|
@ -14,23 +14,74 @@
|
|||
LIST_ENTRY CatalogListHead;
|
||||
CRITICAL_SECTION CatalogLock;
|
||||
|
||||
VOID ReferenceProviderByPointer(
|
||||
PCATALOG_ENTRY Provider)
|
||||
{
|
||||
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
||||
|
||||
//EnterCriticalSection(&Provider->Lock);
|
||||
Provider->ReferenceCount++;
|
||||
//LeaveCriticalSection(&Provider->Lock);
|
||||
}
|
||||
|
||||
|
||||
VOID DereferenceProviderByPointer(
|
||||
PCATALOG_ENTRY Provider)
|
||||
{
|
||||
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
||||
|
||||
#ifdef DBG
|
||||
if (Provider->ReferenceCount <= 0) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Provider at 0x%X has invalid reference count (%ld).\n",
|
||||
Provider, Provider->ReferenceCount));
|
||||
}
|
||||
#endif
|
||||
|
||||
//EnterCriticalSection(&Provider->Lock);
|
||||
Provider->ReferenceCount--;
|
||||
//LeaveCriticalSection(&Provider->Lock);
|
||||
|
||||
if (Provider->ReferenceCount == 0) {
|
||||
DestroyCatalogEntry(Provider);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PCATALOG_ENTRY CreateCatalogEntry(
|
||||
LPWSTR LibraryName)
|
||||
{
|
||||
PCATALOG_ENTRY Provider;
|
||||
|
||||
Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
|
||||
if (!Provider)
|
||||
return NULL;
|
||||
WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
|
||||
|
||||
InitializeCriticalSection(&Provider->Lock);
|
||||
Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
|
||||
Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
|
||||
if (!Provider) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
ZeroMemory(Provider, sizeof(CATALOG_ENTRY));
|
||||
|
||||
CP
|
||||
Provider->ReferenceCount = 1;
|
||||
|
||||
//InitializeCriticalSection(&Provider->Lock);
|
||||
CP
|
||||
Provider->hModule = NULL;
|
||||
CP
|
||||
lstrcpyW(Provider->LibraryName, LibraryName);
|
||||
CP
|
||||
Provider->Mapping = NULL;
|
||||
|
||||
EnterCriticalSection(&CatalogLock);
|
||||
CP
|
||||
//EnterCriticalSection(&CatalogLock);
|
||||
CP
|
||||
InsertTailList(&CatalogListHead, &Provider->ListEntry);
|
||||
LeaveCriticalSection(&CatalogLock);
|
||||
CP
|
||||
//LeaveCriticalSection(&CatalogLock);
|
||||
CP
|
||||
|
||||
return Provider;
|
||||
}
|
||||
|
@ -41,22 +92,27 @@ INT DestroyCatalogEntry(
|
|||
{
|
||||
INT Status;
|
||||
|
||||
EnterCriticalSection(&CatalogLock);
|
||||
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
||||
|
||||
CP
|
||||
//EnterCriticalSection(&CatalogLock);
|
||||
RemoveEntryList(&Provider->ListEntry);
|
||||
LeaveCriticalSection(&CatalogLock);
|
||||
|
||||
//LeaveCriticalSection(&CatalogLock);
|
||||
CP
|
||||
HeapFree(GlobalHeap, 0, Provider->Mapping);
|
||||
|
||||
if (Provider->hModule != (HMODULE)INVALID_HANDLE_VALUE) {
|
||||
CP
|
||||
if (Provider->hModule) {
|
||||
CP
|
||||
Status = UnloadProvider(Provider);
|
||||
CP
|
||||
} else {
|
||||
Status = NO_ERROR;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&Provider->Lock);
|
||||
CP
|
||||
//DeleteCriticalSection(&Provider->Lock);
|
||||
|
||||
HeapFree(GlobalHeap, 0, Provider);
|
||||
|
||||
CP
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -68,7 +124,9 @@ PCATALOG_ENTRY LocateProvider(
|
|||
PCATALOG_ENTRY Provider;
|
||||
UINT i;
|
||||
|
||||
EnterCriticalSection(&CatalogLock);
|
||||
WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
|
||||
|
||||
//EnterCriticalSection(&CatalogLock);
|
||||
CurrentEntry = CatalogListHead.Flink;
|
||||
while (CurrentEntry != &CatalogListHead) {
|
||||
Provider = CONTAINING_RECORD(CurrentEntry,
|
||||
|
@ -80,14 +138,50 @@ PCATALOG_ENTRY LocateProvider(
|
|||
(lpProtocolInfo->iSocketType == Provider->Mapping->Mapping[i].SocketType) &&
|
||||
((lpProtocolInfo->iProtocol == Provider->Mapping->Mapping[i].Protocol) ||
|
||||
(lpProtocolInfo->iSocketType == SOCK_RAW))) {
|
||||
LeaveCriticalSection(&CatalogLock);
|
||||
//LeaveCriticalSection(&CatalogLock);
|
||||
WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
|
||||
return Provider;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
LeaveCriticalSection(&CatalogLock);
|
||||
//LeaveCriticalSection(&CatalogLock);
|
||||
|
||||
WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PCATALOG_ENTRY LocateProviderById(
|
||||
DWORD CatalogEntryId)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PCATALOG_ENTRY Provider;
|
||||
UINT i;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("CatalogEntryId (%d).\n", CatalogEntryId));
|
||||
|
||||
//EnterCriticalSection(&CatalogLock);
|
||||
CurrentEntry = CatalogListHead.Flink;
|
||||
while (CurrentEntry != &CatalogListHead) {
|
||||
Provider = CONTAINING_RECORD(CurrentEntry,
|
||||
CATALOG_ENTRY,
|
||||
ListEntry);
|
||||
|
||||
if (Provider->ProtocolInfo.dwCatalogEntryId == CatalogEntryId) {
|
||||
//LeaveCriticalSection(&CatalogLock);
|
||||
WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X) Name (%s).\n",
|
||||
Provider, Provider->LibraryName));
|
||||
return Provider;
|
||||
}
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
//LeaveCriticalSection(&CatalogLock);
|
||||
|
||||
WS_DbgPrint(MID_TRACE, ("Provider was not found.\n"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -97,22 +191,30 @@ INT LoadProvider(
|
|||
PCATALOG_ENTRY Provider,
|
||||
LPWSAPROTOCOL_INFOW lpProtocolInfo)
|
||||
{
|
||||
INT Status = NO_ERROR;
|
||||
INT Status;
|
||||
|
||||
WS_DbgPrint(MIN_TRACE, ("Loading provider...\n"));
|
||||
WS_DbgPrint(MAX_TRACE, ("Loading provider at (0x%X) Name (%S).\n",
|
||||
Provider, Provider->LibraryName));
|
||||
|
||||
if (Provider->hModule == (HMODULE)INVALID_HANDLE_VALUE) {
|
||||
if (!Provider->hModule) {
|
||||
CP
|
||||
/* DLL is not loaded so load it now */
|
||||
Provider->hModule = LoadLibrary(Provider->LibraryName);
|
||||
if (Provider->hModule != (HMODULE)INVALID_HANDLE_VALUE) {
|
||||
|
||||
CP
|
||||
if (Provider->hModule) {
|
||||
CP
|
||||
Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
|
||||
"WSPStartup");
|
||||
CP
|
||||
if (Provider->WSPStartup) {
|
||||
Status = WSPStartup(MAKEWORD(2, 2),
|
||||
&Provider->WSPData,
|
||||
lpProtocolInfo,
|
||||
UpcallTable,
|
||||
&Provider->ProcTable);
|
||||
WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n", Provider->WSPStartup));
|
||||
Status = Provider->WSPStartup(MAKEWORD(2, 2),
|
||||
&Provider->WSPData,
|
||||
lpProtocolInfo,
|
||||
UpcallTable,
|
||||
&Provider->ProcTable);
|
||||
CP
|
||||
} else
|
||||
Status = ERROR_BAD_PROVIDER;
|
||||
} else
|
||||
|
@ -120,7 +222,7 @@ INT LoadProvider(
|
|||
} else
|
||||
Status = NO_ERROR;
|
||||
|
||||
WS_DbgPrint(MIN_TRACE, ("Status %d\n", Status));
|
||||
WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@ -131,15 +233,23 @@ INT UnloadProvider(
|
|||
{
|
||||
INT Status = NO_ERROR;
|
||||
|
||||
if (Provider->hModule != (HMODULE)INVALID_HANDLE_VALUE) {
|
||||
WS_DbgPrint(MAX_TRACE, ("Unloading provider at (0x%X)\n", Provider));
|
||||
|
||||
if (Provider->hModule) {
|
||||
WS_DbgPrint(MAX_TRACE, ("Calling WSPCleanup at (0x%X).\n",
|
||||
Provider->ProcTable.lpWSPCleanup));
|
||||
Provider->ProcTable.lpWSPCleanup(&Status);
|
||||
|
||||
if (!FreeLibrary(Provider->hModule))
|
||||
if (!FreeLibrary(Provider->hModule)) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Could not free library.\n"));
|
||||
Status = GetLastError();
|
||||
}
|
||||
|
||||
Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -148,25 +258,46 @@ VOID CreateCatalog(VOID)
|
|||
{
|
||||
PCATALOG_ENTRY Provider;
|
||||
|
||||
InitializeCriticalSection(&CatalogLock);
|
||||
CP
|
||||
|
||||
// FIXME: Crash
|
||||
//InitializeCriticalSection(&CatalogLock);
|
||||
|
||||
CP
|
||||
|
||||
InitializeListHead(&CatalogListHead);
|
||||
|
||||
CP
|
||||
|
||||
/* FIXME: Read service provider catalog from registry */
|
||||
#if 1
|
||||
Provider = CreateCatalogEntry(L"msafd.dll");
|
||||
if (!Provider)
|
||||
if (!Provider) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
CP
|
||||
/* Assume one Service Provider with id 1 */
|
||||
Provider->ProtocolInfo.dwCatalogEntryId = 1;
|
||||
|
||||
CP
|
||||
|
||||
Provider->Mapping = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
|
||||
if (!Provider->Mapping)
|
||||
if (!Provider->Mapping) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
CP
|
||||
|
||||
Provider->Mapping->Rows = 1;
|
||||
Provider->Mapping->Columns = 3;
|
||||
Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
|
||||
Provider->Mapping->Mapping[0].SocketType = SOCK_RAW;
|
||||
Provider->Mapping->Mapping[0].Protocol = 0;
|
||||
|
||||
CP
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -174,20 +305,19 @@ VOID CreateCatalog(VOID)
|
|||
VOID DestroyCatalog(VOID)
|
||||
{
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PLIST_ENTRY NextEntry;
|
||||
PCATALOG_ENTRY Provider;
|
||||
|
||||
CurrentEntry = CatalogListHead.Flink;
|
||||
while (CurrentEntry != &CatalogListHead) {
|
||||
NextEntry = CurrentEntry->Flink;
|
||||
Provider = CONTAINING_RECORD(CurrentEntry,
|
||||
CATALOG_ENTRY,
|
||||
ListEntry);
|
||||
|
||||
DestroyCatalogEntry(Provider);
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
CurrentEntry = NextEntry;
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&CatalogLock);
|
||||
//DeleteCriticalSection(&CatalogLock);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -9,12 +9,13 @@
|
|||
*/
|
||||
#include <ws2_32.h>
|
||||
#include <catalog.h>
|
||||
#include <handle.h>
|
||||
#include <upcall.h>
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
/* See debug.h for debug/trace constants */
|
||||
DWORD DebugTraceLevel = MIN_TRACE;
|
||||
DWORD DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
@ -59,18 +60,25 @@ WSAStartup(
|
|||
IN WORD wVersionRequested,
|
||||
OUT LPWSADATA lpWSAData)
|
||||
{
|
||||
WS_DbgPrint(MIN_TRACE, ("WSAStartup of ws2_32.dll\n"));
|
||||
WS_DbgPrint(MAX_TRACE, ("WSAStartup of ws2_32.dll\n"));
|
||||
|
||||
lpWSAData->wVersion = wVersionRequested;
|
||||
lpWSAData->wHighVersion = 2;
|
||||
CP
|
||||
lstrcpyA(lpWSAData->szDescription, "WinSock 2.0");
|
||||
CP
|
||||
lstrcpyA(lpWSAData->szSystemStatus, "Running");
|
||||
CP
|
||||
lpWSAData->iMaxSockets = 0;
|
||||
lpWSAData->iMaxUdpDg = 0;
|
||||
lpWSAData->lpVendorInfo = NULL;
|
||||
|
||||
CP
|
||||
|
||||
WSASETINITIALIZED;
|
||||
|
||||
CP
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -79,13 +87,15 @@ INT
|
|||
EXPORT
|
||||
WSACleanup(VOID)
|
||||
{
|
||||
WS_DbgPrint(MIN_TRACE, ("WSACleanup of ws2_32.dll\n"));
|
||||
WS_DbgPrint(MAX_TRACE, ("WSACleanup of ws2_32.dll\n"));
|
||||
|
||||
if (!WSAINITIALIZED) {
|
||||
CP
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return WSANOTINITIALISED;
|
||||
}
|
||||
|
||||
CP
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
@ -108,18 +118,24 @@ WSASocketA(
|
|||
UNICODE_STRING StringU;
|
||||
ANSI_STRING StringA;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
|
||||
af, type, protocol));
|
||||
|
||||
if (lpProtocolInfo) {
|
||||
CP
|
||||
memcpy(&ProtocolInfoW,
|
||||
lpProtocolInfo,
|
||||
sizeof(WSAPROTOCOL_INFOA) -
|
||||
sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
|
||||
|
||||
CP
|
||||
RtlInitAnsiString(&StringA, (LPSTR)lpProtocolInfo->szProtocol);
|
||||
CP
|
||||
RtlInitUnicodeString(&StringU, (LPWSTR)&ProtocolInfoW.szProtocol);
|
||||
RtlAnsiStringToUnicodeString(&StringU,
|
||||
&StringA,
|
||||
FALSE);
|
||||
CP
|
||||
RtlAnsiStringToUnicodeString(&StringU, &StringA, FALSE);
|
||||
CP
|
||||
p = &ProtocolInfoW;
|
||||
CP
|
||||
} else {
|
||||
p = NULL;
|
||||
}
|
||||
|
@ -143,7 +159,7 @@ WSASocketW(
|
|||
IN GROUP g,
|
||||
IN DWORD dwFlags)
|
||||
/*
|
||||
* FUNCTION: Creates a new socket
|
||||
* FUNCTION: Creates a new socket descriptor
|
||||
* ARGUMENTS:
|
||||
* af = Address family
|
||||
* type = Socket type
|
||||
|
@ -152,7 +168,7 @@ WSASocketW(
|
|||
* g = Reserved
|
||||
* dwFlags = Socket flags
|
||||
* RETURNS:
|
||||
* Created socket, or INVALID_SOCKET if it could not be created
|
||||
* Created socket descriptor, or INVALID_SOCKET if it could not be created
|
||||
*/
|
||||
{
|
||||
INT Status;
|
||||
|
@ -160,6 +176,9 @@ WSASocketW(
|
|||
PCATALOG_ENTRY Provider;
|
||||
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
|
||||
af, type, protocol));
|
||||
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return INVALID_SOCKET;
|
||||
|
@ -188,12 +207,12 @@ WSASocketW(
|
|||
}
|
||||
|
||||
Socket = Provider->ProcTable.lpWSPSocket(af,
|
||||
type,
|
||||
protocol,
|
||||
lpProtocolInfo,
|
||||
g,
|
||||
dwFlags,
|
||||
&Status);
|
||||
type,
|
||||
protocol,
|
||||
lpProtocolInfo,
|
||||
g,
|
||||
dwFlags,
|
||||
&Status);
|
||||
if (Status != NO_ERROR) {
|
||||
WSASetLastError(Status);
|
||||
return INVALID_SOCKET;
|
||||
|
@ -203,24 +222,146 @@ WSASocketW(
|
|||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
closesocket(
|
||||
IN SOCKET s)
|
||||
/*
|
||||
* FUNCTION: Closes a socket descriptor
|
||||
* ARGUMENTS:
|
||||
* s = Socket descriptor
|
||||
* RETURNS:
|
||||
* 0, or SOCKET_ERROR if an error ocurred
|
||||
*/
|
||||
{
|
||||
PCATALOG_ENTRY Provider;
|
||||
INT Errno;
|
||||
INT Code;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("s (0x%X).\n", s));
|
||||
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
CloseProviderHandle((HANDLE)s);
|
||||
|
||||
DereferenceProviderByPointer(Provider);
|
||||
|
||||
Code = Provider->ProcTable.lpWSPCloseSocket(s, &Errno);
|
||||
if (Code == SOCKET_ERROR)
|
||||
WSASetLastError(Errno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
select(
|
||||
IN INT nfds,
|
||||
IN OUT LPFD_SET readfds,
|
||||
IN OUT LPFD_SET writefds,
|
||||
IN OUT LPFD_SET exceptfds,
|
||||
IN CONST LPTIMEVAL timeout)
|
||||
/*
|
||||
* FUNCTION: Returns status of one or more sockets
|
||||
* ARGUMENTS:
|
||||
* nfds = Always ignored
|
||||
* readfds = Pointer to socket set to be checked for readability (optional)
|
||||
* writefds = Pointer to socket set to be checked for writability (optional)
|
||||
* exceptfds = Pointer to socket set to be checked for errors (optional)
|
||||
* timeout = Pointer to a TIMEVAL structure indicating maximum wait time
|
||||
* (NULL means wait forever)
|
||||
* RETURNS:
|
||||
* Number of ready socket descriptors, or SOCKET_ERROR if an error ocurred
|
||||
*/
|
||||
{
|
||||
PCATALOG_ENTRY Provider;
|
||||
INT Count;
|
||||
INT Errno;
|
||||
ULONG i;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("readfds (0x%X) writefds (0x%X) exceptfds (0x%X).\n",
|
||||
readfds, writefds, exceptfds));
|
||||
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
/* FIXME: Sockets in FD_SETs should be sorted by their provider */
|
||||
|
||||
/* FIXME: For now, assume only one service provider */
|
||||
if ((readfds != NULL) && (readfds->fd_count > 0)) {
|
||||
if (!ReferenceProviderByHandle((HANDLE)readfds->fd_array[0], &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
} else if ((writefds != NULL) && (writefds->fd_count > 0)) {
|
||||
if (!ReferenceProviderByHandle((HANDLE)writefds->fd_array[0], &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
} else if ((exceptfds != NULL) && (exceptfds->fd_count > 0)) {
|
||||
if (!ReferenceProviderByHandle((HANDLE)exceptfds->fd_array[0], &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
} else {
|
||||
WSASetLastError(WSAEINVAL);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
Count = Provider->ProcTable.lpWSPSelect(nfds, readfds, writefds, exceptfds, timeout, &Errno);
|
||||
|
||||
DereferenceProviderByPointer(Provider);
|
||||
|
||||
WSASetLastError(Errno);
|
||||
|
||||
if (Errno != NO_ERROR)
|
||||
return SOCKET_ERROR;
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
DllMain(PVOID hInstDll,
|
||||
DllMain(HANDLE hInstDll,
|
||||
ULONG dwReason,
|
||||
PVOID Reserved)
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
WS_DbgPrint(MIN_TRACE, ("DllMain of ws2_32.dll\n"));
|
||||
WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll.\n"));
|
||||
|
||||
CP
|
||||
|
||||
#if 0
|
||||
switch (dwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
GlobalHeap = HeapCreate(0, 0, 0);
|
||||
if (!GlobalHeap)
|
||||
return FALSE;
|
||||
case DLL_PROCESS_ATTACH: {
|
||||
CP
|
||||
GlobalHeap = GetProcessHeap();
|
||||
//GlobalHeap = HeapCreate(0, 0, 0);
|
||||
if (!GlobalHeap) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ReadCatalog() != NO_ERROR)
|
||||
return FALSE;
|
||||
CP
|
||||
|
||||
CreateCatalog();
|
||||
|
||||
CP
|
||||
|
||||
InitProviderHandleTable();
|
||||
|
||||
CP
|
||||
/* FIXME: Causes trap
|
||||
UpcallTable.lpWPUCloseEvent = WPUCloseEvent;
|
||||
UpcallTable.lpWPUCloseSocketHandle = WPUCloseSocketHandle;
|
||||
UpcallTable.lpWPUCreateEvent = WPUCreateEvent;
|
||||
|
@ -235,37 +376,64 @@ DllMain(PVOID hInstDll,
|
|||
UpcallTable.lpWPUResetEvent = WPUResetEvent;
|
||||
UpcallTable.lpWPUSetEvent = WPUSetEvent;
|
||||
UpcallTable.lpWPUOpenCurrentThread = WPUOpenCurrentThread;
|
||||
UpcallTable.lpWPUCloseThread = WPUCloseThread;
|
||||
break;
|
||||
UpcallTable.lpWPUCloseThread = WPUCloseThread;*/
|
||||
|
||||
/* Fall through to thread attachment handler */
|
||||
}
|
||||
|
||||
case DLL_THREAD_ATTACH: {
|
||||
PWINSOCK_THREAD_BLOCK p;
|
||||
|
||||
p = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_THREAD_BLOCK));
|
||||
if (p) {
|
||||
p->LastErrorValue = NO_ERROR;
|
||||
p->Initialized = FALSE;
|
||||
NtCurrentTeb()->WinSockData = p;
|
||||
}
|
||||
CP
|
||||
|
||||
p = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_THREAD_BLOCK));
|
||||
CP
|
||||
if (!p) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CP
|
||||
p->LastErrorValue = NO_ERROR;
|
||||
p->Initialized = FALSE;
|
||||
CP
|
||||
|
||||
NtCurrentTeb()->WinSockData = p;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_PROCESS_DETACH: {
|
||||
CP
|
||||
|
||||
HeapFree(GlobalHeap, 0, NtCurrentTeb()->WinSockData);
|
||||
|
||||
DestroyCatalog();
|
||||
|
||||
CP
|
||||
|
||||
FreeProviderHandleTable();
|
||||
|
||||
CP
|
||||
|
||||
//HeapDestroy(GlobalHeap);
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_THREAD_DETACH: {
|
||||
PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
|
||||
|
||||
CP
|
||||
|
||||
if (p)
|
||||
HeapFree(GlobalHeap, 0, p);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
DestroyCatalog();
|
||||
HeapDestroy(GlobalHeap);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
CP
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,19 @@ EXPORT
|
|||
WSACloseEvent(
|
||||
IN WSAEVENT hEvent)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
BOOL Success;
|
||||
|
||||
return FALSE;
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = CloseHandle((HANDLE)hEvent);
|
||||
|
||||
if (!Success)
|
||||
WSASetLastError(WSA_INVALID_HANDLE);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,9 +34,19 @@ WSAEVENT
|
|||
EXPORT
|
||||
WSACreateEvent(VOID)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
HANDLE Event;
|
||||
|
||||
return (WSAEVENT)0;
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
if (Event == INVALID_HANDLE_VALUE)
|
||||
WSASetLastError(WSA_INVALID_HANDLE);
|
||||
|
||||
return (WSAEVENT)Event;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,9 +55,19 @@ EXPORT
|
|||
WSAResetEvent(
|
||||
IN WSAEVENT hEvent)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
BOOL Success;
|
||||
|
||||
return FALSE;
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = ResetEvent((HANDLE)hEvent);
|
||||
|
||||
if (!Success)
|
||||
WSASetLastError(WSA_INVALID_HANDLE);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,9 +76,19 @@ EXPORT
|
|||
WSASetEvent(
|
||||
IN WSAEVENT hEvent)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
BOOL Success;
|
||||
|
||||
return FALSE;
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Success = SetEvent((HANDLE)hEvent);
|
||||
|
||||
if (!Success)
|
||||
WSASetLastError(WSA_INVALID_HANDLE);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,9 +101,28 @@ WSAWaitForMultipleEvents(
|
|||
IN DWORD dwTimeout,
|
||||
IN BOOL fAlertable)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
DWORD Status;
|
||||
|
||||
return 0;
|
||||
if (!WSAINITIALIZED) {
|
||||
WSASetLastError(WSANOTINITIALISED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = WaitForMultipleObjectsEx(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable);
|
||||
if (Status == WAIT_FAILED) {
|
||||
Status = GetLastError();
|
||||
|
||||
if (Status == ERROR_NOT_ENOUGH_MEMORY)
|
||||
WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
|
||||
else if (Status == ERROR_INVALID_HANDLE)
|
||||
WSASetLastError(WSA_INVALID_HANDLE);
|
||||
else
|
||||
WSASetLastError(WSA_INVALID_PARAMETER);
|
||||
|
||||
return WSA_WAIT_FAILED;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
281
reactos/lib/ws2_32/misc/handle.c
Normal file
281
reactos/lib/ws2_32/misc/handle.c
Normal file
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: misc/handle.c
|
||||
* PURPOSE: Provider handle management
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <ws2_32.h>
|
||||
#include <handle.h>
|
||||
#include <catalog.h>
|
||||
|
||||
PPROVIDER_HANDLE_BLOCK ProviderHandleTable;
|
||||
CRITICAL_SECTION ProviderHandleTableLock;
|
||||
|
||||
PPROVIDER_HANDLE
|
||||
GetProviderByHandle(
|
||||
PPROVIDER_HANDLE_BLOCK HandleTable,
|
||||
HANDLE Handle)
|
||||
/*
|
||||
* FUNCTION: Get the data structure for a handle
|
||||
* ARGUMENTS:
|
||||
* HandleTable = Pointer to handle table
|
||||
* Handle = Handle to get data structure for
|
||||
* RETURNS:
|
||||
* Pointer to the data structure identified by the handle on success,
|
||||
* NULL on failure
|
||||
*/
|
||||
{
|
||||
PPROVIDER_HANDLE_BLOCK Current;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
ULONG i;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
|
||||
|
||||
CurrentEntry = HandleTable->Entry.Flink;
|
||||
|
||||
while (CurrentEntry != &HandleTable->Entry) {
|
||||
Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
|
||||
|
||||
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
|
||||
if ((Current->Handles[i].Provider != NULL) &&
|
||||
(Current->Handles[i].Handle == Handle)) {
|
||||
|
||||
return &Current->Handles[i];
|
||||
}
|
||||
}
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
CloseAllHandles(PPROVIDER_HANDLE_BLOCK HandleTable)
|
||||
{
|
||||
PPROVIDER_HANDLE_BLOCK Current;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PCATALOG_ENTRY Provider;
|
||||
ULONG i;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable));
|
||||
|
||||
CurrentEntry = HandleTable->Entry.Flink;
|
||||
|
||||
while (CurrentEntry != &HandleTable->Entry) {
|
||||
Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
|
||||
|
||||
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
|
||||
Provider = Current->Handles[i].Provider;
|
||||
|
||||
if (Provider != NULL) {
|
||||
DereferenceProviderByPointer(Provider);
|
||||
Current->Handles[i].Handle = (HANDLE)0;
|
||||
Current->Handles[i].Provider = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
DeleteHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable)
|
||||
{
|
||||
PPROVIDER_HANDLE_BLOCK Current;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
|
||||
CloseAllHandles(HandleTable);
|
||||
|
||||
CurrentEntry = RemoveHeadList(&HandleTable->Entry);
|
||||
|
||||
while (CurrentEntry != &HandleTable->Entry) {
|
||||
Current = CONTAINING_RECORD(CurrentEntry,
|
||||
PROVIDER_HANDLE_BLOCK,
|
||||
Entry);
|
||||
|
||||
HeapFree(GlobalHeap, 0, Current);
|
||||
|
||||
CurrentEntry = RemoveHeadList(&HandleTable->Entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PCATALOG_ENTRY
|
||||
DeleteProviderHandle(PPROVIDER_HANDLE_BLOCK HandleTable,
|
||||
HANDLE Handle)
|
||||
{
|
||||
PPROVIDER_HANDLE Entry;
|
||||
PCATALOG_ENTRY Provider;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle));
|
||||
|
||||
Entry = GetProviderByHandle(HandleTable, Handle);
|
||||
if (!Entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Provider = Entry->Provider;
|
||||
|
||||
if (Provider != NULL) {
|
||||
Entry->Handle = (HANDLE)0;
|
||||
Entry->Provider = NULL;
|
||||
}
|
||||
|
||||
return Provider;
|
||||
}
|
||||
|
||||
|
||||
HANDLE
|
||||
CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable,
|
||||
HANDLE Handle,
|
||||
PCATALOG_ENTRY Provider)
|
||||
{
|
||||
PPROVIDER_HANDLE_BLOCK NewBlock;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
ULONG i;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X) Provider (0x%X).\n", HandleTable, Handle, Provider));
|
||||
|
||||
/* Scan through the currently allocated handle blocks looking for a free slot */
|
||||
CurrentEntry = HandleTable->Entry.Flink;
|
||||
while (CurrentEntry != &HandleTable->Entry) {
|
||||
PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(
|
||||
CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry);
|
||||
|
||||
for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) {
|
||||
WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n", i, Block->Handles[i].Provider));
|
||||
if (!Block->Handles[i].Provider) {
|
||||
Block->Handles[i].Handle = Handle;
|
||||
Block->Handles[i].Provider = Provider;
|
||||
return Handle;
|
||||
}
|
||||
}
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
/* Add a new handle block to the end of the list */
|
||||
NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(
|
||||
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);
|
||||
|
||||
NewBlock->Handles[0].Handle = Handle;
|
||||
NewBlock->Handles[0].Provider = Provider;
|
||||
|
||||
return Handle;
|
||||
}
|
||||
|
||||
|
||||
HANDLE
|
||||
CreateProviderHandle(HANDLE Handle,
|
||||
PCATALOG_ENTRY Provider)
|
||||
{
|
||||
HANDLE h;
|
||||
|
||||
//EnterCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
h = CreateProviderHandleTable(ProviderHandleTable, Handle, Provider);
|
||||
|
||||
//LeaveCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
if (h != NULL) {
|
||||
ReferenceProviderByPointer(Provider);
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
ReferenceProviderByHandle(HANDLE Handle,
|
||||
PCATALOG_ENTRY* Provider)
|
||||
/*
|
||||
* FUNCTION: Increments the reference count for a provider and returns a pointer to it
|
||||
* ARGUMENTS:
|
||||
* Handle = Handle for the provider
|
||||
* Provider = Address of buffer to place pointer to provider
|
||||
* RETURNS:
|
||||
* TRUE if handle was valid, FALSE if not
|
||||
*/
|
||||
{
|
||||
PPROVIDER_HANDLE ProviderHandle;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("Handle (0x%X) Provider (0x%X).\n", Handle, Provider));
|
||||
|
||||
//EnterCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
ProviderHandle = GetProviderByHandle(ProviderHandleTable, Handle);
|
||||
|
||||
//LeaveCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
if (ProviderHandle) {
|
||||
ReferenceProviderByPointer(ProviderHandle->Provider);
|
||||
*Provider = ProviderHandle->Provider;
|
||||
}
|
||||
|
||||
return (ProviderHandle != NULL);
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
CloseProviderHandle(HANDLE Handle)
|
||||
{
|
||||
PCATALOG_ENTRY Provider;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle));
|
||||
|
||||
//EnterCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
Provider = DeleteProviderHandle(ProviderHandleTable, Handle);
|
||||
if (!Provider) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//LeaveCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
DereferenceProviderByPointer(Provider);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
InitProviderHandleTable(VOID)
|
||||
{
|
||||
ProviderHandleTable = (PPROVIDER_HANDLE_BLOCK)
|
||||
HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK));
|
||||
if (!ProviderHandleTable) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK));
|
||||
InitializeListHead(&ProviderHandleTable->Entry);
|
||||
|
||||
//InitializeCriticalSection(&ProviderHandleTableLock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
FreeProviderHandleTable(VOID)
|
||||
{
|
||||
DeleteHandleTable(ProviderHandleTable);
|
||||
|
||||
//DeleteCriticalSection(&ProviderHandleTableLock);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -402,9 +402,19 @@ EXPORT
|
|||
inet_ntoa(
|
||||
IN IN_ADDR in)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
CHAR b[10];
|
||||
PCHAR p;
|
||||
|
||||
return (CHAR FAR*)NULL;
|
||||
p = ((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Intoa;
|
||||
_itoa(in.S_un.S_addr >> 24, b, 10);
|
||||
strcpy(p, b);
|
||||
_itoa(in.S_un.S_addr >> 16, b, 10);
|
||||
strcat(p, b);
|
||||
_itoa(in.S_un.S_addr >> 8, b, 10);
|
||||
strcat(p, b);
|
||||
_itoa(in.S_un.S_addr & 0xFF, b, 10);
|
||||
strcat(p, b);
|
||||
return (CHAR FAR*)p;
|
||||
}
|
||||
|
||||
|
||||
|
|
193
reactos/lib/ws2_32/misc/sndrcv.c
Normal file
193
reactos/lib/ws2_32/misc/sndrcv.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS WinSock 2 DLL
|
||||
* FILE: misc/sndrcv.c
|
||||
* PURPOSE: Send/receive functions
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <ws2_32.h>
|
||||
#include <catalog.h>
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
recv(
|
||||
IN SOCKET s,
|
||||
OUT CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
recvfrom(
|
||||
IN SOCKET s,
|
||||
OUT CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags,
|
||||
OUT LPSOCKADDR from,
|
||||
IN OUT INT FAR* fromlen)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
send(
|
||||
IN SOCKET s,
|
||||
IN CONST CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
sendto(
|
||||
IN SOCKET s,
|
||||
IN CONST CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags,
|
||||
IN CONST LPSOCKADDR to,
|
||||
IN INT tolen)
|
||||
{
|
||||
DWORD BytesSent;
|
||||
WSABUF WSABuf;
|
||||
|
||||
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 WSASendTo(s, &WSABuf, 1, &BytesSent, flags, to, tolen, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSARecv(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSARecvDisconnect(
|
||||
IN SOCKET s,
|
||||
OUT LPWSABUF lpInboundDisconnectData)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSARecvFrom(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
OUT LPSOCKADDR lpFrom,
|
||||
IN OUT LPINT lpFromlen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSASend(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSASendDisconnect(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpOutboundDisconnectData)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSASendTo(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN CONST LPSOCKADDR lpTo,
|
||||
IN INT iToLen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
PCATALOG_ENTRY Provider;
|
||||
INT Errno;
|
||||
INT Code;
|
||||
|
||||
WS_DbgPrint(MAX_TRACE, ("Called.\n"));
|
||||
|
||||
if (!ReferenceProviderByHandle((HANDLE)s, &Provider)) {
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
Code = Provider->ProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount,
|
||||
lpNumberOfBytesSent, dwFlags, lpTo, iToLen, lpOverlapped,
|
||||
lpCompletionRoutine, NULL /* lpThreadId */, &Errno);
|
||||
|
||||
DereferenceProviderByPointer(Provider);
|
||||
|
||||
if (Code == SOCKET_ERROR)
|
||||
WSASetLastError(Errno);
|
||||
|
||||
return Code;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -33,16 +33,6 @@ bind(
|
|||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
closesocket(
|
||||
IN SOCKET s)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
connect(
|
||||
|
@ -156,76 +146,6 @@ ntohs(
|
|||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
recv(
|
||||
IN SOCKET s,
|
||||
OUT CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
recvfrom(
|
||||
IN SOCKET s,
|
||||
OUT CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags,
|
||||
OUT LPSOCKADDR from,
|
||||
IN OUT INT FAR* fromlen)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
select(
|
||||
IN INT nfds,
|
||||
IN OUT LPFD_SET readfds,
|
||||
IN OUT LPFD_SET writefds,
|
||||
IN OUT LPFD_SET exceptfds,
|
||||
IN CONST LPTIMEVAL timeout)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
send(
|
||||
IN SOCKET s,
|
||||
IN CONST CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
sendto(
|
||||
IN SOCKET s,
|
||||
IN CONST CHAR FAR* buf,
|
||||
IN INT len,
|
||||
IN INT flags,
|
||||
IN CONST LPSOCKADDR to,
|
||||
IN INT tolen)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
setsockopt(
|
||||
|
@ -505,96 +425,6 @@ WSANtohs(
|
|||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSARecv(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSARecvDisconnect(
|
||||
IN SOCKET s,
|
||||
OUT LPWSABUF lpInboundDisconnectData)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSARecvFrom(
|
||||
IN SOCKET s,
|
||||
IN OUT LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesRecvd,
|
||||
IN OUT LPDWORD lpFlags,
|
||||
OUT LPSOCKADDR lpFrom,
|
||||
IN OUT LPINT lpFromlen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSASend(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSASendDisconnect(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpOutboundDisconnectData)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT
|
||||
EXPORT
|
||||
WSASendTo(
|
||||
IN SOCKET s,
|
||||
IN LPWSABUF lpBuffers,
|
||||
IN DWORD dwBufferCount,
|
||||
OUT LPDWORD lpNumberOfBytesSent,
|
||||
IN DWORD dwFlags,
|
||||
IN CONST LPSOCKADDR lpTo,
|
||||
IN INT iToLen,
|
||||
IN LPWSAOVERLAPPED lpOverlapped,
|
||||
IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FARPROC
|
||||
EXPORT
|
||||
WSASetBlockingHook(
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* CSH 01/09-2000 Created
|
||||
*/
|
||||
#include <ws2_32.h>
|
||||
#include <catalog.h>
|
||||
|
||||
BOOL
|
||||
WSPAPI
|
||||
|
@ -78,7 +79,6 @@ WPUFDIsSet(
|
|||
UNIMPLEMENTED
|
||||
|
||||
return (SOCKET)0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,9 +103,25 @@ WPUModifyIFSHandle(
|
|||
IN SOCKET ProposedHandle,
|
||||
OUT LPINT lpErrno)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
PCATALOG_ENTRY Provider;
|
||||
SOCKET Socket;
|
||||
|
||||
return (SOCKET)0;
|
||||
WS_DbgPrint(MAX_TRACE, ("dwCatalogEntryId (%d) ProposedHandle (0x%X).\n",
|
||||
dwCatalogEntryId, ProposedHandle));
|
||||
|
||||
Provider = LocateProviderById(dwCatalogEntryId);
|
||||
if (!Provider) {
|
||||
WS_DbgPrint(MIN_TRACE, ("Provider with catalog entry id (%d) was not found.\n",
|
||||
dwCatalogEntryId));
|
||||
*lpErrno = WSAEINVAL;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
Socket = (SOCKET)CreateProviderHandle(ProposedHandle, Provider);
|
||||
|
||||
*lpErrno = NO_ERROR;
|
||||
|
||||
return Socket;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue