Пример #1
0
NTSTATUS
	TdiRecvfrom(
		PFILE_OBJECT	AddressObject, 
		PVOID			Data, 
		ULONG			Length, 
		ULONG			Addr,
		USHORT			Port,
		PULONG			pRead,
		PKEVENT			ReadEvent
		)
{
	KEVENT	Event; 
	PIRP	Irp;
	PMDL	Mdl;
	NTSTATUS	ntStatus;
	IO_STATUS_BLOCK IoStatus;
    PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(AddressObject);
	TA_IP_ADDRESS	SrcAddr = {1, {TDI_ADDRESS_LENGTH_IP, TDI_ADDRESS_TYPE_IP, {Port, Addr}}};
    TDI_CONNECTION_INFORMATION Src = {0, 0, 0, 0, sizeof SrcAddr, &SrcAddr};
	PKEVENT pEvent = ReadEvent;

	if (!ReadEvent)
	{
		KeInitializeEvent(&Event, NotificationEvent, FALSE);
		pEvent = &Event;
	}

    if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, DeviceObject, AddressObject, pEvent, &IoStatus)))
		return STATUS_INSUFFICIENT_RESOURCES;

    if (!(Mdl = IoAllocateMdl(Data, Length, FALSE, FALSE, Irp)))
		return STATUS_INSUFFICIENT_RESOURCES;

    MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
	TdiBuildReceiveDatagram(Irp, DeviceObject, AddressObject, 0, 0, Mdl, Length, &Src, &Src, TDI_RECEIVE_NORMAL);

   	ntStatus = IoCallDriver(DeviceObject, Irp);

    if ((ntStatus == STATUS_PENDING) && (!ReadEvent))
        ntStatus = KeWaitForSingleObject(pEvent, UserRequest, KernelMode, FALSE, 0);

	if (ntStatus == STATUS_SUCCESS)
	{
		*pRead = IoStatus.Status;
	}

    return(ntStatus);

}
Пример #2
0
NTSTATUS tdi_recv_dgram(PFILE_OBJECT addressFileObject, PULONG addr, PUSHORT port, char *buf, int len, ULONG flags)
{
    PDEVICE_OBJECT              devObj;
    KEVENT                      event;
    PTDI_CONNECTION_INFORMATION remoteInfo;
    PTDI_CONNECTION_INFORMATION returnInfo;
    PTA_IP_ADDRESS              returnAddr;
    PIRP                        irp;
    PMDL                        mdl;
    IO_STATUS_BLOCK             iosb;
    NTSTATUS                    status;

    devObj = IoGetRelatedDeviceObject(addressFileObject);

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    remoteInfo = HttpDiskMalloc(
        2 * sizeof (TDI_CONNECTION_INFORMATION) +
        sizeof (TA_IP_ADDRESS)
      );

    if (remoteInfo == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(remoteInfo, 2 * sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));

    remoteInfo->RemoteAddressLength = 0;
    remoteInfo->RemoteAddress = NULL;

    returnInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)remoteInfo + sizeof(TDI_CONNECTION_INFORMATION));

    returnInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
    returnInfo->RemoteAddress = (PUCHAR)returnInfo + sizeof(TDI_CONNECTION_INFORMATION);

    returnAddr = (PTA_IP_ADDRESS) returnInfo->RemoteAddress;

    returnAddr->TAAddressCount = 1;
    returnAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
    returnAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;

    irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, devObj, addressFileObject, &event, &iosb);

    if (irp == NULL)
    {
        ExFreePool(remoteInfo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    if (len)
    {
        mdl = IoAllocateMdl((void*) buf, len, FALSE, FALSE, NULL);

        if (mdl == NULL)
        {
            IoFreeIrp(irp);
            ExFreePool(remoteInfo);
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        __try
        {
            MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
            status = STATUS_SUCCESS;
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            IoFreeMdl(mdl);
            IoFreeIrp(irp);
            ExFreePool(remoteInfo);
            status = STATUS_INVALID_USER_BUFFER;
        }

        if (!NT_SUCCESS(status))
        {
            return status;
        }
    }

    TdiBuildReceiveDatagram(irp, devObj, addressFileObject, NULL, NULL, len ? mdl : 0, len, remoteInfo, returnInfo, flags);

    status = IoCallDriver(devObj, irp);

    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = iosb.Status;
    }

    if (addr)
    {
        *addr = returnAddr->Address[0].Address[0].in_addr;
    }

    if (port)
    {
        *port = returnAddr->Address[0].Address[0].sin_port;
    }

    ExFreePool(remoteInfo);

    return NT_SUCCESS(status) ? iosb.Information : status;
}
Пример #3
0
NTSTATUS TdiReceiveDatagram(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    USHORT Flags,
    PCHAR Buffer,
    UINT BufferLength,
    PTDI_CONNECTION_INFORMATION Addr,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
/*
 * 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
 */
{
    PDEVICE_OBJECT DeviceObject;
    PMDL Mdl;

    ASSERT(*Irp == NULL);

    if (!TransportObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad tranport object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    DeviceObject = IoGetRelatedDeviceObject(TransportObject);
    if (!DeviceObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    *Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM,    /* Sub function */
                                            DeviceObject,            /* Device object */
                                            TransportObject,         /* File object */
                                            NULL,                    /* Event */
                                            NULL);                   /* Status */

    if (!*Irp) {
        AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength));

    Mdl = IoAllocateMdl(Buffer,         /* Virtual address */
                        BufferLength,   /* 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"));
        IoCompleteRequest(*Irp, IO_NO_INCREMENT);
        *Irp = NULL;
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _SEH2_TRY {
        MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess);
    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeMdl(Mdl);
        IoCompleteRequest(*Irp, IO_NO_INCREMENT);
        *Irp = NULL;
        _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
    }
    _SEH2_END;

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl));

    TdiBuildReceiveDatagram(*Irp,                   /* I/O Request Packet */
                            DeviceObject,           /* Device object */
                            TransportObject,        /* File object */
                            CompletionRoutine,      /* Completion routine */
                            CompletionContext,      /* Completion context */
                            Mdl,                    /* Data buffer */
                            BufferLength,
                            Addr,
                            Addr,
                            Flags);                 /* Length of data */

    TdiCall(*Irp, DeviceObject, NULL, NULL);
    /* Does not block...  The MDL is deleted in the receive completion
       routine. */

    return STATUS_PENDING;
}