예제 #1
0
파일: tdi.c 프로젝트: 0x00dec0de/Rovnix
NTSTATUS
	TdiSendto(
		PFILE_OBJECT AddressObject, 
		PVOID		Data, 
		ULONG		Length,
		ULONG		Addr,
		USHORT		Port,
		PKEVENT		WriteEvent
		)
{
    KEVENT	Event; 
	PIRP	Irp;
	PMDL	Mdl;
	NTSTATUS		ntStatus;
    PDEVICE_OBJECT	DeviceObject = IoGetRelatedDeviceObject(AddressObject);
    IO_STATUS_BLOCK IoStatus;
	TA_IP_ADDRESS	DstAddr = {1, {TDI_ADDRESS_LENGTH_IP, TDI_ADDRESS_TYPE_IP, {Port, Addr}}};
    TDI_CONNECTION_INFORMATION Dst = {0, 0, 0, 0, sizeof DstAddr, &DstAddr};
	PKEVENT	pEvent = WriteEvent;

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

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

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

    MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);

    TdiBuildSendDatagram(Irp, DeviceObject, AddressObject, 0, 0, Mdl, Length, &Dst);

	ntStatus = IoCallDriver(DeviceObject, Irp);

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

    return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus);

}
예제 #2
0
NTSTATUS
LpxTdiSendDataGram(
	IN	PFILE_OBJECT	AddressFileObject,
	PLPX_ADDRESS		LpxRemoteAddress,
	IN	PUCHAR			SendBuffer,
	IN 	ULONG			SendLength,
	IN	ULONG			Flags,
	OUT	PLONG			Result
	)
{
	KEVENT				event;
    PDEVICE_OBJECT		deviceObject;
	PIRP				irp;
	IO_STATUS_BLOCK		ioStatusBlock;
	NTSTATUS			ntStatus;
	PMDL				mdl;
    TDI_CONNECTION_INFORMATION  SendDatagramInfo;
	UCHAR				AddrBuffer[256];
	PTRANSPORT_ADDRESS	RemoteAddress = (PTRANSPORT_ADDRESS)AddrBuffer;
	
	UNREFERENCED_PARAMETER(Flags);

    LtDebugPrint (3, ("LpxTdiSendDataGram:  Entered\n"));
	//
	// Make Event.
	//
	KeInitializeEvent(&event, NotificationEvent, FALSE);

    deviceObject = IoGetRelatedDeviceObject(AddressFileObject);

	//
	// Make IRP.
	//
	irp = TdiBuildInternalDeviceControlIrp(
			TDI_SEND_DATAGRAM,
			deviceObject,
			AddressFileObject,
			&event,
			&ioStatusBlock
			);
	if(irp == NULL) {
		LtDebugPrint(1, ("[LpxTdi]LpxTdiSendDataGram: Can't Build IRP.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	
	//
	// Make MDL.
	//
	mdl = IoAllocateMdl(
			SendBuffer,
			SendLength,
			FALSE,
			FALSE,
			irp
			);
	if(mdl == NULL) {
		LtDebugPrint(1, ("[LpxTdi]LpxTdiSendDataGram: Can't Allocate MDL.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	
	MmBuildMdlForNonPagedPool(mdl);
	mdl->Next = NULL;
//	MmProbeAndLockPages(
//		mdl,
//		KernelMode,
//		IoReadAccess
//		);

	RemoteAddress->TAAddressCount = 1;
    RemoteAddress->Address[0].AddressType	= TDI_ADDRESS_TYPE_LPX;
    RemoteAddress->Address[0].AddressLength	= TDI_ADDRESS_LENGTH_LPX;
	RtlCopyMemory(RemoteAddress->Address[0].Address, LpxRemoteAddress, sizeof(LPX_ADDRESS));


	SendDatagramInfo.UserDataLength = 0;
	SendDatagramInfo.UserData = NULL;
	SendDatagramInfo.OptionsLength = 0;
	SendDatagramInfo.Options = NULL;
	SendDatagramInfo.RemoteAddressLength =	TPADDR_LPX_LENGTH;
	SendDatagramInfo.RemoteAddress = RemoteAddress;
	

	TdiBuildSendDatagram(
		irp,
		deviceObject,
		AddressFileObject,
		LpxTdiSendCompletionRoutine,
		NULL,
		mdl,
		SendLength,
		&SendDatagramInfo
    );

	ntStatus = LpxTdiIoCallDriver(
				deviceObject,
				irp,
				&ioStatusBlock,
				&event,
				NULL
				);

	if(!NT_SUCCESS(ntStatus)) {
		LtDebugPrint(1, ("[LpxTdi]LpxTdiSendDataGram: Failed.\n"));
		*Result = -1;
		return ntStatus;
	}
	*Result = ioStatusBlock.Information;

	return ntStatus;
}
예제 #3
0
파일: ktdi.c 프로젝트: baselsayeh/winvblock
NTSTATUS tdi_send_dgram(PFILE_OBJECT addressFileObject, ULONG addr, USHORT port, const char *buf, int len)
{
    PDEVICE_OBJECT              devObj;
    KEVENT                      event;
    PTDI_CONNECTION_INFORMATION remoteInfo;
    PTA_IP_ADDRESS              remoteAddr;
    PIRP                        irp;
    PMDL                        mdl;
    IO_STATUS_BLOCK             iosb;
    NTSTATUS                    status;

    devObj = IoGetRelatedDeviceObject(addressFileObject);

    KeInitializeEvent(&event, NotificationEvent, FALSE);

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

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

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

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

    remoteAddr = (PTA_IP_ADDRESS) remoteInfo->RemoteAddress;

    remoteAddr->TAAddressCount = 1;
    remoteAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
    remoteAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
    remoteAddr->Address[0].Address[0].sin_port = port;
    remoteAddr->Address[0].Address[0].in_addr = addr;

    irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_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, IoReadAccess);
            status = STATUS_SUCCESS;
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            IoFreeMdl(mdl);
            IoFreeIrp(irp);
            ExFreePool(remoteInfo);
            status = STATUS_INVALID_USER_BUFFER;
        }

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

    TdiBuildSendDatagram(irp, devObj, addressFileObject, NULL, NULL, len ? mdl : 0, len, remoteInfo);

    status = IoCallDriver(devObj, irp);

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

    ExFreePool(remoteInfo);

    return NT_SUCCESS(status) ? iosb.Information : status;
}
예제 #4
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiSendDatagram(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    PCHAR Buffer,
    UINT BufferLength,
    PTDI_CONNECTION_INFORMATION Addr,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
/*
 * FUNCTION: Sends a datagram
 * ARGUMENTS:
 *     TransportObject = Pointer to transport object
 *     From            = Send filter (NULL if none)
 *     Address         = Address of buffer to place remote address
 *     Buffer          = Address of buffer to place send 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 transport object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    AFD_DbgPrint(MID_TRACE,("Called(TransportObject %p)\n", TransportObject));

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

    *Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_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));

    TdiBuildSendDatagram(*Irp,                   /* I/O Request Packet */
                         DeviceObject,           /* Device object */
                         TransportObject,        /* File object */
                         CompletionRoutine,      /* Completion routine */
                         CompletionContext,      /* Completion context */
                         Mdl,                    /* Data buffer */
                         BufferLength,           /* Bytes to send */
                         Addr);                  /* Address */

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

    return STATUS_PENDING;
}