mirror of
https://github.com/reactos/reactos.git
synced 2024-06-20 11:48:13 +00:00
Some work on winsock stack
svn path=/trunk/; revision=1514
This commit is contained in:
parent
2dd3473a90
commit
05ccbb2696
|
@ -16,41 +16,43 @@ include rules.mak
|
||||||
# Required to run the system
|
# Required to run the system
|
||||||
#
|
#
|
||||||
COMPONENTS = iface_native iface_additional ntoskrnl
|
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
|
SUBSYS = smss win32k csrss
|
||||||
|
|
||||||
#
|
#
|
||||||
# Select the server(s) you want to build
|
# Select the server(s) you want to build
|
||||||
#
|
#
|
||||||
|
#SERVERS = posix linux os2
|
||||||
SERVERS = win32
|
SERVERS = win32
|
||||||
# SERVERS = posix linux os2
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Select the loader(s) you want to build
|
# Select the loader(s) you want to build
|
||||||
#
|
#
|
||||||
|
#LOADERS = boot dos
|
||||||
LOADERS = dos
|
LOADERS = dos
|
||||||
# LOADERS = boot
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Select the device drivers and filesystems you want
|
# 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 = 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
|
INPUT_DRIVERS = keyboard
|
||||||
|
|
||||||
FS_DRIVERS = vfat
|
#FS_DRIVERS = vfat minix ext2 template
|
||||||
# FS_DRIVERS = minix ext2 template
|
FS_DRIVERS = vfat
|
||||||
|
|
||||||
# ndis tdi tcpip tditest wshtcpip
|
#NET_DRIVERS = ndis tdi tcpip tditest wshtcpip afd
|
||||||
NET_DRIVERS = ndis tcpip tditest wshtcpip
|
NET_DRIVERS = ndis tcpip tditest wshtcpip afd
|
||||||
|
|
||||||
# ne2000
|
#NET_DEVICE_DRIVERS = ne2000
|
||||||
NET_DEVICE_DRIVERS = ne2000
|
NET_DEVICE_DRIVERS = ne2000
|
||||||
|
|
||||||
#
|
#
|
||||||
# system applications (required for startup)
|
# system applications (required for startup)
|
||||||
#
|
#
|
||||||
|
#SYS_APPS = shell winlogon services
|
||||||
SYS_APPS = shell winlogon services
|
SYS_APPS = shell winlogon services
|
||||||
|
|
||||||
APPS = args hello test cat bench apc shm lpc thread event file gditest \
|
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
|
# objdir
|
||||||
|
|
||||||
# ping
|
#NET_APPS = ping roshttpd
|
||||||
NET_APPS = ping
|
NET_APPS = ping roshttpd
|
||||||
|
|
||||||
|
|
||||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(INPUT_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS) $(NET_DEVICE_DRIVERS)
|
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;
|
extern DWORD DebugTraceLevel;
|
||||||
|
|
||||||
#define Get_DbgPrint(quote...) L##quote
|
|
||||||
|
|
||||||
#define WSH_DbgPrint(_t_, _x_) \
|
#define WSH_DbgPrint(_t_, _x_) \
|
||||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||||
WCHAR _buffer[256]; \
|
DbgPrint("(%hS:%d)(%hS) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||||
swprintf(_buffer, L"(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
|
DbgPrint _x_; \
|
||||||
OutputDebugStringW(_buffer); \
|
|
||||||
swprintf(_buffer, Get_DbgPrint _x_); \
|
|
||||||
OutputDebugStringW(_buffer); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
@ -64,7 +59,9 @@ extern DWORD DebugTraceLevel;
|
||||||
please try again later.\n", __FILE__, __LINE__, __FUNCTION__));
|
please try again later.\n", __FILE__, __LINE__, __FUNCTION__));
|
||||||
|
|
||||||
#define CHECKPOINT \
|
#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 */
|
#endif /* __DEBUG_H */
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
||||||
$(CC) \
|
$(CC) \
|
||||||
$(TARGETNAME).o \
|
$(TARGETNAME).o \
|
||||||
$(LIBS) \
|
$(LIBS) \
|
||||||
-specs=$(TARGETNAME)_specs \
|
|
||||||
-mdll \
|
-mdll \
|
||||||
-o junk.tmp \
|
-o junk.tmp \
|
||||||
-Wl,--base-file,base.tmp
|
-Wl,--base-file,base.tmp
|
||||||
|
@ -50,10 +49,9 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
||||||
- $(RM) base.tmp
|
- $(RM) base.tmp
|
||||||
$(CC) \
|
$(CC) \
|
||||||
$(OBJECTS) $(LIBS) \
|
$(OBJECTS) $(LIBS) \
|
||||||
-specs=$(TARGETNAME)_specs \
|
|
||||||
-mdll \
|
-mdll \
|
||||||
-o $(TARGETNAME).dll \
|
-o $(TARGETNAME).dll \
|
||||||
-Wl,--image-base,0x10000 \
|
-Wl,--image-base,0x777C0000 \
|
||||||
-Wl,--file-alignment,0x1000 \
|
-Wl,--file-alignment,0x1000 \
|
||||||
-Wl,--section-alignment,0x1000 \
|
-Wl,--section-alignment,0x1000 \
|
||||||
-Wl,temp.exp
|
-Wl,temp.exp
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
|
|
||||||
/* See debug.h for debug/trace constants */
|
/* See debug.h for debug/trace constants */
|
||||||
DWORD DebugTraceLevel = MIN_TRACE;
|
DWORD DebugTraceLevel = MAX_TRACE;
|
||||||
|
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
|
@ -22,11 +22,10 @@ VOID STDCALL KeBugCheck (ULONG BugCheckCode) {}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
EXPORT
|
EXPORT
|
||||||
DllMain(PVOID hInstDll,
|
DllMain(HANDLE hInstDll,
|
||||||
ULONG dwReason,
|
ULONG dwReason,
|
||||||
PVOID Reserved)
|
PVOID Reserved)
|
||||||
{
|
{
|
||||||
OutputDebugString(_T("Hello from wshtcpip.dll\n"));
|
|
||||||
WSH_DbgPrint(MIN_TRACE, ("DllMain of wshtcpip.dll\n"));
|
WSH_DbgPrint(MIN_TRACE, ("DllMain of wshtcpip.dll\n"));
|
||||||
|
|
||||||
switch (dwReason) {
|
switch (dwReason) {
|
||||||
|
@ -289,6 +288,8 @@ WSHOpenSocket2(
|
||||||
UNICODE_STRING String;
|
UNICODE_STRING String;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
WSH_DbgPrint(MAX_TRACE, ("\n"));
|
||||||
|
|
||||||
/* FIXME: Raw IP only. Support UDP and TCP */
|
/* FIXME: Raw IP only. Support UDP and TCP */
|
||||||
ASSERT(*SocketType == SOCK_RAW);
|
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 */
|
/* FIXME: Missed some definitions in ntddk.h */
|
||||||
|
|
||||||
/* Could be defined in ndis.h */
|
/* Could be defined elsewhere */
|
||||||
#ifndef __NDIS_H
|
//#ifndef INT
|
||||||
typedef signed int INT, *PINT;
|
//typedef signed int INT, *PINT;
|
||||||
#endif
|
//#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 {
|
typedef struct _CATALOG_ENTRY {
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
ULONG ReferenceCount;
|
||||||
CRITICAL_SECTION Lock;
|
CRITICAL_SECTION Lock;
|
||||||
WCHAR LibraryName[MAX_PATH];
|
WCHAR LibraryName[MAX_PATH];
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
|
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||||
PWINSOCK_MAPPING Mapping;
|
PWINSOCK_MAPPING Mapping;
|
||||||
LPWSPSTARTUP WSPStartup;
|
LPWSPSTARTUP WSPStartup;
|
||||||
WSPDATA WSPData;
|
WSPDATA WSPData;
|
||||||
|
@ -23,6 +25,13 @@ typedef struct _CATALOG_ENTRY {
|
||||||
|
|
||||||
extern LIST_ENTRY Catalog;
|
extern LIST_ENTRY Catalog;
|
||||||
|
|
||||||
|
|
||||||
|
VOID ReferenceProviderByPointer(
|
||||||
|
PCATALOG_ENTRY Provider);
|
||||||
|
|
||||||
|
VOID DereferenceProviderByPointer(
|
||||||
|
PCATALOG_ENTRY Provider);
|
||||||
|
|
||||||
PCATALOG_ENTRY CreateCatalogEntry(
|
PCATALOG_ENTRY CreateCatalogEntry(
|
||||||
LPWSTR LibraryName);
|
LPWSTR LibraryName);
|
||||||
|
|
||||||
|
@ -32,6 +41,9 @@ INT DestroyCatalogEntry(
|
||||||
PCATALOG_ENTRY LocateProvider(
|
PCATALOG_ENTRY LocateProvider(
|
||||||
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
||||||
|
|
||||||
|
PCATALOG_ENTRY LocateProviderById(
|
||||||
|
DWORD CatalogEntryId);
|
||||||
|
|
||||||
INT LoadProvider(
|
INT LoadProvider(
|
||||||
PCATALOG_ENTRY Provider,
|
PCATALOG_ENTRY Provider,
|
||||||
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
LPWSAPROTOCOL_INFOW lpProtocolInfo);
|
||||||
|
|
|
@ -21,16 +21,11 @@
|
||||||
|
|
||||||
extern DWORD DebugTraceLevel;
|
extern DWORD DebugTraceLevel;
|
||||||
|
|
||||||
#define Get_DbgPrint(quote...) L##quote
|
|
||||||
|
|
||||||
#define WS_DbgPrint(_t_, _x_) \
|
#define WS_DbgPrint(_t_, _x_) \
|
||||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||||
WCHAR _buffer[256]; \
|
DbgPrint("(%hS:%d)(%hS) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||||
swprintf(_buffer, L"(%S:%d)(%S) ", __FILE__, __LINE__, __FUNCTION__); \
|
DbgPrint _x_; \
|
||||||
OutputDebugStringW(_buffer); \
|
|
||||||
swprintf(_buffer, Get_DbgPrint _x_); \
|
|
||||||
OutputDebugStringW(_buffer); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
@ -63,7 +58,9 @@ extern DWORD DebugTraceLevel;
|
||||||
WS_DbgPrint(MIN_TRACE, ("is unimplemented, please try again later.\n"));
|
WS_DbgPrint(MIN_TRACE, ("is unimplemented, please try again later.\n"));
|
||||||
|
|
||||||
#define CHECKPOINT \
|
#define CHECKPOINT \
|
||||||
do { WS_DbgPrint(MIN_TRACE, ("\n")); } while(0);
|
WS_DbgPrint(MIN_TRACE, ("\n"));
|
||||||
|
|
||||||
|
#define CP CHECKPOINT
|
||||||
|
|
||||||
#endif /* __DEBUG_H */
|
#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 {
|
typedef struct _WINSOCK_THREAD_BLOCK {
|
||||||
INT LastErrorValue; /* Error value from last function that failed */
|
INT LastErrorValue; /* Error value from last function that failed */
|
||||||
BOOL Initialized; /* TRUE if WSAStartup() has been successfully called */
|
BOOL Initialized; /* TRUE if WSAStartup() has been successfully called */
|
||||||
|
CHAR Intoa[16]; /* Buffer for inet_ntoa() */
|
||||||
} WINSOCK_THREAD_BLOCK, *PWINSOCK_THREAD_BLOCK;
|
} WINSOCK_THREAD_BLOCK, *PWINSOCK_THREAD_BLOCK;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
PATH_TO_TOP = ../..
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
CFLAGS = -Iinclude -DUNICODE
|
CFLAGS = -Iinclude -DUNICODE -DDBG
|
||||||
|
|
||||||
TARGETNAME=ws2_32
|
TARGETNAME=ws2_32
|
||||||
|
|
||||||
MISC_OBJECTS = misc/dllmain.o misc/catalog.o misc/event.o misc/ns.o \
|
MISC_OBJECTS = misc/dllmain.o misc/catalog.o misc/event.o misc/handle.o \
|
||||||
misc/stubs.o misc/upcall.o
|
misc/ns.o misc/sndrcv.o misc/stubs.o misc/upcall.o
|
||||||
|
|
||||||
RESOURCE_OBJECT = $(TARGETNAME).coff
|
RESOURCE_OBJECT = $(TARGETNAME).coff
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
||||||
$(CC) \
|
$(CC) \
|
||||||
$(TARGETNAME).o \
|
$(TARGETNAME).o \
|
||||||
$(LIBS) \
|
$(LIBS) \
|
||||||
-specs=$(TARGETNAME)_specs \
|
|
||||||
-mdll \
|
-mdll \
|
||||||
-o junk.tmp \
|
-o junk.tmp \
|
||||||
-Wl,--base-file,base.tmp
|
-Wl,--base-file,base.tmp
|
||||||
|
@ -58,10 +57,9 @@ $(TARGETNAME).dll: $(LIBS) $(OBJECTS) $(TARGETNAME).def
|
||||||
$(CC) \
|
$(CC) \
|
||||||
$(TARGETNAME).o \
|
$(TARGETNAME).o \
|
||||||
$(LIBS) \
|
$(LIBS) \
|
||||||
-specs=$(TARGETNAME)_specs \
|
|
||||||
-mdll \
|
-mdll \
|
||||||
-o $(TARGETNAME).dll \
|
-o $(TARGETNAME).dll \
|
||||||
-Wl,--image-base,0x10000 \
|
-Wl,--image-base,0x77780000 \
|
||||||
-Wl,--file-alignment,0x1000 \
|
-Wl,--file-alignment,0x1000 \
|
||||||
-Wl,--section-alignment,0x1000 \
|
-Wl,--section-alignment,0x1000 \
|
||||||
-Wl,temp.exp
|
-Wl,temp.exp
|
||||||
|
|
|
@ -14,23 +14,74 @@
|
||||||
LIST_ENTRY CatalogListHead;
|
LIST_ENTRY CatalogListHead;
|
||||||
CRITICAL_SECTION CatalogLock;
|
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(
|
PCATALOG_ENTRY CreateCatalogEntry(
|
||||||
LPWSTR LibraryName)
|
LPWSTR LibraryName)
|
||||||
{
|
{
|
||||||
PCATALOG_ENTRY Provider;
|
PCATALOG_ENTRY Provider;
|
||||||
|
|
||||||
Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
|
WS_DbgPrint(MAX_TRACE, ("LibraryName (%S).\n", LibraryName));
|
||||||
if (!Provider)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
InitializeCriticalSection(&Provider->Lock);
|
Provider = HeapAlloc(GlobalHeap, 0, sizeof(CATALOG_ENTRY));
|
||||||
Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
|
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);
|
lstrcpyW(Provider->LibraryName, LibraryName);
|
||||||
|
CP
|
||||||
Provider->Mapping = NULL;
|
Provider->Mapping = NULL;
|
||||||
|
|
||||||
EnterCriticalSection(&CatalogLock);
|
CP
|
||||||
|
//EnterCriticalSection(&CatalogLock);
|
||||||
|
CP
|
||||||
InsertTailList(&CatalogListHead, &Provider->ListEntry);
|
InsertTailList(&CatalogListHead, &Provider->ListEntry);
|
||||||
LeaveCriticalSection(&CatalogLock);
|
CP
|
||||||
|
//LeaveCriticalSection(&CatalogLock);
|
||||||
|
CP
|
||||||
|
|
||||||
return Provider;
|
return Provider;
|
||||||
}
|
}
|
||||||
|
@ -41,22 +92,27 @@ INT DestroyCatalogEntry(
|
||||||
{
|
{
|
||||||
INT Status;
|
INT Status;
|
||||||
|
|
||||||
EnterCriticalSection(&CatalogLock);
|
WS_DbgPrint(MAX_TRACE, ("Provider (0x%X).\n", Provider));
|
||||||
|
|
||||||
|
CP
|
||||||
|
//EnterCriticalSection(&CatalogLock);
|
||||||
RemoveEntryList(&Provider->ListEntry);
|
RemoveEntryList(&Provider->ListEntry);
|
||||||
LeaveCriticalSection(&CatalogLock);
|
//LeaveCriticalSection(&CatalogLock);
|
||||||
|
CP
|
||||||
HeapFree(GlobalHeap, 0, Provider->Mapping);
|
HeapFree(GlobalHeap, 0, Provider->Mapping);
|
||||||
|
CP
|
||||||
if (Provider->hModule != (HMODULE)INVALID_HANDLE_VALUE) {
|
if (Provider->hModule) {
|
||||||
|
CP
|
||||||
Status = UnloadProvider(Provider);
|
Status = UnloadProvider(Provider);
|
||||||
|
CP
|
||||||
} else {
|
} else {
|
||||||
Status = NO_ERROR;
|
Status = NO_ERROR;
|
||||||
}
|
}
|
||||||
|
CP
|
||||||
DeleteCriticalSection(&Provider->Lock);
|
//DeleteCriticalSection(&Provider->Lock);
|
||||||
|
|
||||||
HeapFree(GlobalHeap, 0, Provider);
|
HeapFree(GlobalHeap, 0, Provider);
|
||||||
|
CP
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +124,9 @@ PCATALOG_ENTRY LocateProvider(
|
||||||
PCATALOG_ENTRY Provider;
|
PCATALOG_ENTRY Provider;
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
EnterCriticalSection(&CatalogLock);
|
WS_DbgPrint(MAX_TRACE, ("lpProtocolInfo (0x%X).\n", lpProtocolInfo));
|
||||||
|
|
||||||
|
//EnterCriticalSection(&CatalogLock);
|
||||||
CurrentEntry = CatalogListHead.Flink;
|
CurrentEntry = CatalogListHead.Flink;
|
||||||
while (CurrentEntry != &CatalogListHead) {
|
while (CurrentEntry != &CatalogListHead) {
|
||||||
Provider = CONTAINING_RECORD(CurrentEntry,
|
Provider = CONTAINING_RECORD(CurrentEntry,
|
||||||
|
@ -80,14 +138,50 @@ PCATALOG_ENTRY LocateProvider(
|
||||||
(lpProtocolInfo->iSocketType == Provider->Mapping->Mapping[i].SocketType) &&
|
(lpProtocolInfo->iSocketType == Provider->Mapping->Mapping[i].SocketType) &&
|
||||||
((lpProtocolInfo->iProtocol == Provider->Mapping->Mapping[i].Protocol) ||
|
((lpProtocolInfo->iProtocol == Provider->Mapping->Mapping[i].Protocol) ||
|
||||||
(lpProtocolInfo->iSocketType == SOCK_RAW))) {
|
(lpProtocolInfo->iSocketType == SOCK_RAW))) {
|
||||||
LeaveCriticalSection(&CatalogLock);
|
//LeaveCriticalSection(&CatalogLock);
|
||||||
|
WS_DbgPrint(MID_TRACE, ("Returning provider at (0x%X).\n", Provider));
|
||||||
return Provider;
|
return Provider;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -97,22 +191,30 @@ INT LoadProvider(
|
||||||
PCATALOG_ENTRY Provider,
|
PCATALOG_ENTRY Provider,
|
||||||
LPWSAPROTOCOL_INFOW lpProtocolInfo)
|
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 */
|
/* DLL is not loaded so load it now */
|
||||||
Provider->hModule = LoadLibrary(Provider->LibraryName);
|
Provider->hModule = LoadLibrary(Provider->LibraryName);
|
||||||
if (Provider->hModule != (HMODULE)INVALID_HANDLE_VALUE) {
|
|
||||||
|
CP
|
||||||
|
if (Provider->hModule) {
|
||||||
|
CP
|
||||||
Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
|
Provider->WSPStartup = (LPWSPSTARTUP)GetProcAddress(Provider->hModule,
|
||||||
"WSPStartup");
|
"WSPStartup");
|
||||||
|
CP
|
||||||
if (Provider->WSPStartup) {
|
if (Provider->WSPStartup) {
|
||||||
Status = WSPStartup(MAKEWORD(2, 2),
|
WS_DbgPrint(MAX_TRACE, ("Calling WSPStartup at (0x%X).\n", Provider->WSPStartup));
|
||||||
&Provider->WSPData,
|
Status = Provider->WSPStartup(MAKEWORD(2, 2),
|
||||||
lpProtocolInfo,
|
&Provider->WSPData,
|
||||||
UpcallTable,
|
lpProtocolInfo,
|
||||||
&Provider->ProcTable);
|
UpcallTable,
|
||||||
|
&Provider->ProcTable);
|
||||||
|
CP
|
||||||
} else
|
} else
|
||||||
Status = ERROR_BAD_PROVIDER;
|
Status = ERROR_BAD_PROVIDER;
|
||||||
} else
|
} else
|
||||||
|
@ -120,7 +222,7 @@ INT LoadProvider(
|
||||||
} else
|
} else
|
||||||
Status = NO_ERROR;
|
Status = NO_ERROR;
|
||||||
|
|
||||||
WS_DbgPrint(MIN_TRACE, ("Status %d\n", Status));
|
WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -131,15 +233,23 @@ INT UnloadProvider(
|
||||||
{
|
{
|
||||||
INT Status = NO_ERROR;
|
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);
|
Provider->ProcTable.lpWSPCleanup(&Status);
|
||||||
|
|
||||||
if (!FreeLibrary(Provider->hModule))
|
if (!FreeLibrary(Provider->hModule)) {
|
||||||
|
WS_DbgPrint(MIN_TRACE, ("Could not free library.\n"));
|
||||||
Status = GetLastError();
|
Status = GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
|
Provider->hModule = (HMODULE)INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WS_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,25 +258,46 @@ VOID CreateCatalog(VOID)
|
||||||
{
|
{
|
||||||
PCATALOG_ENTRY Provider;
|
PCATALOG_ENTRY Provider;
|
||||||
|
|
||||||
InitializeCriticalSection(&CatalogLock);
|
CP
|
||||||
|
|
||||||
|
// FIXME: Crash
|
||||||
|
//InitializeCriticalSection(&CatalogLock);
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
InitializeListHead(&CatalogListHead);
|
InitializeListHead(&CatalogListHead);
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
/* FIXME: Read service provider catalog from registry */
|
/* FIXME: Read service provider catalog from registry */
|
||||||
#if 1
|
#if 1
|
||||||
Provider = CreateCatalogEntry(L"msafd.dll");
|
Provider = CreateCatalogEntry(L"msafd.dll");
|
||||||
if (!Provider)
|
if (!Provider) {
|
||||||
|
WS_DbgPrint(MIN_TRACE, ("Could not create catalog entry.\n"));
|
||||||
return;
|
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));
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
Provider->Mapping->Rows = 1;
|
Provider->Mapping->Rows = 1;
|
||||||
Provider->Mapping->Columns = 3;
|
Provider->Mapping->Columns = 3;
|
||||||
Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
|
Provider->Mapping->Mapping[0].AddressFamily = AF_INET;
|
||||||
Provider->Mapping->Mapping[0].SocketType = SOCK_RAW;
|
Provider->Mapping->Mapping[0].SocketType = SOCK_RAW;
|
||||||
Provider->Mapping->Mapping[0].Protocol = 0;
|
Provider->Mapping->Mapping[0].Protocol = 0;
|
||||||
|
|
||||||
|
CP
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,20 +305,19 @@ VOID CreateCatalog(VOID)
|
||||||
VOID DestroyCatalog(VOID)
|
VOID DestroyCatalog(VOID)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
PCATALOG_ENTRY Provider;
|
PCATALOG_ENTRY Provider;
|
||||||
|
|
||||||
CurrentEntry = CatalogListHead.Flink;
|
CurrentEntry = CatalogListHead.Flink;
|
||||||
while (CurrentEntry != &CatalogListHead) {
|
while (CurrentEntry != &CatalogListHead) {
|
||||||
|
NextEntry = CurrentEntry->Flink;
|
||||||
Provider = CONTAINING_RECORD(CurrentEntry,
|
Provider = CONTAINING_RECORD(CurrentEntry,
|
||||||
CATALOG_ENTRY,
|
CATALOG_ENTRY,
|
||||||
ListEntry);
|
ListEntry);
|
||||||
|
|
||||||
DestroyCatalogEntry(Provider);
|
DestroyCatalogEntry(Provider);
|
||||||
|
CurrentEntry = NextEntry;
|
||||||
CurrentEntry = CurrentEntry->Flink;
|
|
||||||
}
|
}
|
||||||
|
//DeleteCriticalSection(&CatalogLock);
|
||||||
DeleteCriticalSection(&CatalogLock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
*/
|
*/
|
||||||
#include <ws2_32.h>
|
#include <ws2_32.h>
|
||||||
#include <catalog.h>
|
#include <catalog.h>
|
||||||
|
#include <handle.h>
|
||||||
#include <upcall.h>
|
#include <upcall.h>
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
|
|
||||||
/* See debug.h for debug/trace constants */
|
/* See debug.h for debug/trace constants */
|
||||||
DWORD DebugTraceLevel = MIN_TRACE;
|
DWORD DebugTraceLevel = MAX_TRACE;
|
||||||
|
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
|
@ -59,18 +60,25 @@ WSAStartup(
|
||||||
IN WORD wVersionRequested,
|
IN WORD wVersionRequested,
|
||||||
OUT LPWSADATA lpWSAData)
|
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->wVersion = wVersionRequested;
|
||||||
lpWSAData->wHighVersion = 2;
|
lpWSAData->wHighVersion = 2;
|
||||||
|
CP
|
||||||
lstrcpyA(lpWSAData->szDescription, "WinSock 2.0");
|
lstrcpyA(lpWSAData->szDescription, "WinSock 2.0");
|
||||||
|
CP
|
||||||
lstrcpyA(lpWSAData->szSystemStatus, "Running");
|
lstrcpyA(lpWSAData->szSystemStatus, "Running");
|
||||||
|
CP
|
||||||
lpWSAData->iMaxSockets = 0;
|
lpWSAData->iMaxSockets = 0;
|
||||||
lpWSAData->iMaxUdpDg = 0;
|
lpWSAData->iMaxUdpDg = 0;
|
||||||
lpWSAData->lpVendorInfo = NULL;
|
lpWSAData->lpVendorInfo = NULL;
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
WSASETINITIALIZED;
|
WSASETINITIALIZED;
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,13 +87,15 @@ INT
|
||||||
EXPORT
|
EXPORT
|
||||||
WSACleanup(VOID)
|
WSACleanup(VOID)
|
||||||
{
|
{
|
||||||
WS_DbgPrint(MIN_TRACE, ("WSACleanup of ws2_32.dll\n"));
|
WS_DbgPrint(MAX_TRACE, ("WSACleanup of ws2_32.dll\n"));
|
||||||
|
|
||||||
if (!WSAINITIALIZED) {
|
if (!WSAINITIALIZED) {
|
||||||
|
CP
|
||||||
WSASetLastError(WSANOTINITIALISED);
|
WSASetLastError(WSANOTINITIALISED);
|
||||||
return WSANOTINITIALISED;
|
return WSANOTINITIALISED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CP
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,18 +118,24 @@ WSASocketA(
|
||||||
UNICODE_STRING StringU;
|
UNICODE_STRING StringU;
|
||||||
ANSI_STRING StringA;
|
ANSI_STRING StringA;
|
||||||
|
|
||||||
|
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
|
||||||
|
af, type, protocol));
|
||||||
|
|
||||||
if (lpProtocolInfo) {
|
if (lpProtocolInfo) {
|
||||||
|
CP
|
||||||
memcpy(&ProtocolInfoW,
|
memcpy(&ProtocolInfoW,
|
||||||
lpProtocolInfo,
|
lpProtocolInfo,
|
||||||
sizeof(WSAPROTOCOL_INFOA) -
|
sizeof(WSAPROTOCOL_INFOA) -
|
||||||
sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
|
sizeof(CHAR) * (WSAPROTOCOL_LEN + 1));
|
||||||
|
CP
|
||||||
RtlInitAnsiString(&StringA, (LPSTR)lpProtocolInfo->szProtocol);
|
RtlInitAnsiString(&StringA, (LPSTR)lpProtocolInfo->szProtocol);
|
||||||
|
CP
|
||||||
RtlInitUnicodeString(&StringU, (LPWSTR)&ProtocolInfoW.szProtocol);
|
RtlInitUnicodeString(&StringU, (LPWSTR)&ProtocolInfoW.szProtocol);
|
||||||
RtlAnsiStringToUnicodeString(&StringU,
|
CP
|
||||||
&StringA,
|
RtlAnsiStringToUnicodeString(&StringU, &StringA, FALSE);
|
||||||
FALSE);
|
CP
|
||||||
p = &ProtocolInfoW;
|
p = &ProtocolInfoW;
|
||||||
|
CP
|
||||||
} else {
|
} else {
|
||||||
p = NULL;
|
p = NULL;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +159,7 @@ WSASocketW(
|
||||||
IN GROUP g,
|
IN GROUP g,
|
||||||
IN DWORD dwFlags)
|
IN DWORD dwFlags)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Creates a new socket
|
* FUNCTION: Creates a new socket descriptor
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
* af = Address family
|
* af = Address family
|
||||||
* type = Socket type
|
* type = Socket type
|
||||||
|
@ -152,7 +168,7 @@ WSASocketW(
|
||||||
* g = Reserved
|
* g = Reserved
|
||||||
* dwFlags = Socket flags
|
* dwFlags = Socket flags
|
||||||
* RETURNS:
|
* 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;
|
INT Status;
|
||||||
|
@ -160,6 +176,9 @@ WSASocketW(
|
||||||
PCATALOG_ENTRY Provider;
|
PCATALOG_ENTRY Provider;
|
||||||
WSAPROTOCOL_INFOW ProtocolInfo;
|
WSAPROTOCOL_INFOW ProtocolInfo;
|
||||||
|
|
||||||
|
WS_DbgPrint(MAX_TRACE, ("af (%d) type (%d) protocol (%d).\n",
|
||||||
|
af, type, protocol));
|
||||||
|
|
||||||
if (!WSAINITIALIZED) {
|
if (!WSAINITIALIZED) {
|
||||||
WSASetLastError(WSANOTINITIALISED);
|
WSASetLastError(WSANOTINITIALISED);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
|
@ -188,12 +207,12 @@ WSASocketW(
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket = Provider->ProcTable.lpWSPSocket(af,
|
Socket = Provider->ProcTable.lpWSPSocket(af,
|
||||||
type,
|
type,
|
||||||
protocol,
|
protocol,
|
||||||
lpProtocolInfo,
|
lpProtocolInfo,
|
||||||
g,
|
g,
|
||||||
dwFlags,
|
dwFlags,
|
||||||
&Status);
|
&Status);
|
||||||
if (Status != NO_ERROR) {
|
if (Status != NO_ERROR) {
|
||||||
WSASetLastError(Status);
|
WSASetLastError(Status);
|
||||||
return INVALID_SOCKET;
|
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
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
DllMain(PVOID hInstDll,
|
DllMain(HANDLE hInstDll,
|
||||||
ULONG dwReason,
|
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) {
|
switch (dwReason) {
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH: {
|
||||||
GlobalHeap = HeapCreate(0, 0, 0);
|
CP
|
||||||
if (!GlobalHeap)
|
GlobalHeap = GetProcessHeap();
|
||||||
return FALSE;
|
//GlobalHeap = HeapCreate(0, 0, 0);
|
||||||
|
if (!GlobalHeap) {
|
||||||
|
WS_DbgPrint(MIN_TRACE, ("Insufficient memory.\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (ReadCatalog() != NO_ERROR)
|
CP
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
|
CreateCatalog();
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
|
InitProviderHandleTable();
|
||||||
|
|
||||||
|
CP
|
||||||
|
/* FIXME: Causes trap
|
||||||
UpcallTable.lpWPUCloseEvent = WPUCloseEvent;
|
UpcallTable.lpWPUCloseEvent = WPUCloseEvent;
|
||||||
UpcallTable.lpWPUCloseSocketHandle = WPUCloseSocketHandle;
|
UpcallTable.lpWPUCloseSocketHandle = WPUCloseSocketHandle;
|
||||||
UpcallTable.lpWPUCreateEvent = WPUCreateEvent;
|
UpcallTable.lpWPUCreateEvent = WPUCreateEvent;
|
||||||
|
@ -235,37 +376,64 @@ DllMain(PVOID hInstDll,
|
||||||
UpcallTable.lpWPUResetEvent = WPUResetEvent;
|
UpcallTable.lpWPUResetEvent = WPUResetEvent;
|
||||||
UpcallTable.lpWPUSetEvent = WPUSetEvent;
|
UpcallTable.lpWPUSetEvent = WPUSetEvent;
|
||||||
UpcallTable.lpWPUOpenCurrentThread = WPUOpenCurrentThread;
|
UpcallTable.lpWPUOpenCurrentThread = WPUOpenCurrentThread;
|
||||||
UpcallTable.lpWPUCloseThread = WPUCloseThread;
|
UpcallTable.lpWPUCloseThread = WPUCloseThread;*/
|
||||||
break;
|
|
||||||
|
/* Fall through to thread attachment handler */
|
||||||
|
}
|
||||||
|
|
||||||
case DLL_THREAD_ATTACH: {
|
case DLL_THREAD_ATTACH: {
|
||||||
PWINSOCK_THREAD_BLOCK p;
|
PWINSOCK_THREAD_BLOCK p;
|
||||||
|
|
||||||
p = HeapAlloc(GlobalHeap, 0, sizeof(WINSOCK_THREAD_BLOCK));
|
CP
|
||||||
if (p) {
|
|
||||||
p->LastErrorValue = NO_ERROR;
|
|
||||||
p->Initialized = FALSE;
|
|
||||||
NtCurrentTeb()->WinSockData = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DLL_THREAD_DETACH: {
|
case DLL_THREAD_DETACH: {
|
||||||
PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
|
PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
|
||||||
|
|
||||||
|
CP
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
HeapFree(GlobalHeap, 0, p);
|
HeapFree(GlobalHeap, 0, p);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
DestroyCatalog();
|
|
||||||
HeapDestroy(GlobalHeap);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
CP
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,19 @@ EXPORT
|
||||||
WSACloseEvent(
|
WSACloseEvent(
|
||||||
IN WSAEVENT hEvent)
|
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
|
EXPORT
|
||||||
WSACreateEvent(VOID)
|
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(
|
WSAResetEvent(
|
||||||
IN WSAEVENT hEvent)
|
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(
|
WSASetEvent(
|
||||||
IN WSAEVENT hEvent)
|
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 DWORD dwTimeout,
|
||||||
IN BOOL fAlertable)
|
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 */
|
/* 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(
|
inet_ntoa(
|
||||||
IN IN_ADDR in)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
INT
|
|
||||||
EXPORT
|
|
||||||
closesocket(
|
|
||||||
IN SOCKET s)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT
|
INT
|
||||||
EXPORT
|
EXPORT
|
||||||
connect(
|
connect(
|
||||||
|
@ -156,76 +146,6 @@ ntohs(
|
||||||
return 0;
|
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
|
INT
|
||||||
EXPORT
|
EXPORT
|
||||||
setsockopt(
|
setsockopt(
|
||||||
|
@ -505,96 +425,6 @@ WSANtohs(
|
||||||
return 0;
|
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
|
FARPROC
|
||||||
EXPORT
|
EXPORT
|
||||||
WSASetBlockingHook(
|
WSASetBlockingHook(
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* CSH 01/09-2000 Created
|
* CSH 01/09-2000 Created
|
||||||
*/
|
*/
|
||||||
#include <ws2_32.h>
|
#include <ws2_32.h>
|
||||||
|
#include <catalog.h>
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
WSPAPI
|
WSPAPI
|
||||||
|
@ -78,7 +79,6 @@ WPUFDIsSet(
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
|
|
||||||
return (SOCKET)0;
|
return (SOCKET)0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,9 +103,25 @@ WPUModifyIFSHandle(
|
||||||
IN SOCKET ProposedHandle,
|
IN SOCKET ProposedHandle,
|
||||||
OUT LPINT lpErrno)
|
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