NTSTATUS createcomplete(PDEVICE_OBJECT dev, PIRP irp, PVOID context) { UNREFERENCED_PARAMETER(dev); UNREFERENCED_PARAMETER(irp); UNREFERENCED_PARAMETER(context); DbgPrint("enter createcomplete\n"); PIO_STACK_LOCATION sa = IoGetCurrentIrpStackLocation(irp); PCONTEXTI info = context; DbgPrint("1\n"); TDI_ADDRESS_INFO *tai = ExAllocatePool(NonPagedPool, sizeof(TDI_ADDRESS_INFO)); DbgPrint("2\n"); PMDL mdl = IoAllocateMdl(tai, sizeof(TDI_ADDRESS_INFO), FALSE, FALSE, info->query_irp); MmBuildMdlForNonPagedPool(mdl); info->mdl = mdl; DbgPrint("3\n"); IoCopyCurrentIrpStackLocationToNext(irp); TdiBuildQueryInformation(info->query_irp, info->realdev, sa->FileObject, querycom, info, TDI_QUERY_ADDRESS_INFO, mdl); DbgPrint("4\n"); if (irp->PendingReturned) { IoMarkIrpPending(irp); DbgPrint("pending\n"); } IoCallDriver(info->realdev, info->query_irp); DbgPrint("6\n"); IoFreeMdl(info->mdl); ExFreePool(context); return STATUS_SUCCESS; }
NTSTATUS TdiQueryAddress( PFILE_OBJECT AddressObject, PTDI_ADDRESS_INFO AddressInfo, PULONG pInfoLength ) { NTSTATUS ntStatus; PIRP Irp; PMDL Mdl; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(AddressObject); IO_STATUS_BLOCK IoStatus; if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, DeviceObject, FileObject, NULL, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; if (!(Mdl = IoAllocateMdl(AddressInfo, *pInfoLength, FALSE, FALSE, Irp))) { IoFreeIrp(Irp); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); TdiBuildQueryInformation(Irp, DeviceObject, AddressObject, NULL, NULL, TDI_QUERY_ADDRESS_INFO, Mdl); ntStatus = IoCallDriver(DeviceObject, Irp); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS TdiQueryInformation( PFILE_OBJECT FileObject, LONG QueryType, PMDL MdlBuffer) /* * FUNCTION: Query for information * ARGUMENTS: * FileObject = Pointer to file object * QueryType = Query type * MdlBuffer = Pointer to MDL buffer specific for query type * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK Iosb; KEVENT Event; PIRP Irp; if (!FileObject) { AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(FileObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, /* Sub function */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ &Event, /* Event */ &Iosb); /* Status */ if (!Irp) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildQueryInformation(Irp, DeviceObject, FileObject, NULL, NULL, QueryType, MdlBuffer); return TdiCall(Irp, DeviceObject, &Event, &Iosb); }
/* this completion routine queries address and port from address object */ NTSTATUS tdi_create_addrobj_complete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { NTSTATUS status; PIO_STACK_LOCATION irps = IoGetCurrentIrpStackLocation(Irp); PIRP query_irp = (PIRP)Context; PDEVICE_OBJECT devobj; TDI_CREATE_ADDROBJ2_CTX *ctx = NULL; PMDL mdl = NULL; KdPrint(("[tdi_fw] tdi_create_addrobj_complete: devobj 0x%x; addrobj 0x%x\n", DeviceObject, irps->FileObject)); if (Irp->IoStatus.Status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_create_addrobj_complete: status 0x%x\n", Irp->IoStatus.Status)); status = Irp->IoStatus.Status; goto done; } // query addrobj address:port ctx = (TDI_CREATE_ADDROBJ2_CTX *)malloc_np(sizeof(TDI_CREATE_ADDROBJ2_CTX)); if (ctx == NULL) { KdPrint(("[tdi_fw] tdi_create_addrobj_complete: malloc_np\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto done; } ctx->fileobj = irps->FileObject; ctx->tai = (TDI_ADDRESS_INFO *)malloc_np(TDI_ADDRESS_INFO_MAX); if (ctx->tai == NULL) { KdPrint(("[tdi_fw] tdi_create_addrobj_complete: malloc_np!\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto done; } mdl = IoAllocateMdl(ctx->tai, TDI_ADDRESS_INFO_MAX, FALSE, FALSE, NULL); if (mdl == NULL) { KdPrint(("[tdi_fw] tdi_create_addrobj_complete: IoAllocateMdl!\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto done; } MmBuildMdlForNonPagedPool(mdl); devobj = get_original_devobj(DeviceObject, NULL); // use original devobj! if (devobj == NULL) { KdPrint(("[tdi_fw] tdi_create_addrobj_complete: get_original_devobj!\n")); status = STATUS_INVALID_PARAMETER; goto done; } TdiBuildQueryInformation(query_irp, devobj, irps->FileObject, tdi_create_addrobj_complete2, ctx, TDI_QUERY_ADDRESS_INFO, mdl); status = IoCallDriver(devobj, query_irp); query_irp = NULL; mdl = NULL; ctx = NULL; if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_create_addrobj_complete: IoCallDriver: 0x%x\n", status)); goto done; } status = STATUS_SUCCESS; done: // cleanup if (mdl != NULL) IoFreeMdl(mdl); if (ctx != NULL) { if (ctx->tai != NULL) free(ctx->tai); free(ctx); } if (query_irp != NULL) IoCompleteRequest(query_irp, IO_NO_INCREMENT); Irp->IoStatus.Status = status; if (status != STATUS_SUCCESS) { // tdi_create failed - remove fileobj from hash ot_del_fileobj(irps->FileObject, NULL); } return tdi_generic_complete(DeviceObject, Irp, Context); }
/* query local address and port for connection */ void update_conn_info(PDEVICE_OBJECT devobj, PFILE_OBJECT connobj) { PIRP query_irp; PMDL mdl = NULL; struct uci_param *uci_param = NULL; // MUST be executed at PASSIVE_LEVEL if (KeGetCurrentIrql() != PASSIVE_LEVEL) { // do it a bit later :-) struct delayed_ucn_param *ucn_param = (struct delayed_ucn_param *)malloc_np(sizeof(*ucn_param)); if (ucn_param != NULL) { memset(ucn_param, 0, sizeof(*ucn_param)); ucn_param->devobj = devobj; ucn_param->fileobj = connobj; ExInitializeWorkItem(&ucn_param->item, delayed_ucn, ucn_param); ExQueueWorkItem(&ucn_param->item, DelayedWorkQueue); // DelayedWorkQueue a good value? } else { KdPrint(("[ndis_hk] tdi_connect_complete: malloc_np!\n")); // so we'll live without known local address :-( } return; } // we're at PASSIVE_LEVEL query_irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, devobj, connobj, NULL, NULL); if (query_irp == NULL) { KdPrint(("[tdi_fw] update_conn_info: TdiBuildInternalDeviceControlIrp!\n")); goto done; } uci_param = (struct uci_param *)malloc_np(sizeof(*uci_param) + TDI_ADDRESS_INFO_MAX); if (uci_param == NULL) { KdPrint(("[tdi_fw] update_conn_info: malloc_np!\n")); goto done; } memset(uci_param, 0, sizeof(*uci_param) + TDI_ADDRESS_INFO_MAX); uci_param->connobj = connobj; mdl = IoAllocateMdl(uci_param->address, TDI_ADDRESS_INFO_MAX, FALSE, FALSE, NULL); if (mdl == NULL) { KdPrint(("[tdi_fw] update_conn_info: IoAllocateMdl!\n")); goto done; } MmBuildMdlForNonPagedPool(mdl); TdiBuildQueryInformation(query_irp, devobj, connobj, update_conn_info_complete, uci_param, TDI_QUERY_ADDRESS_INFO, mdl); IoCallDriver(devobj, query_irp); query_irp = NULL; mdl = NULL; uci_param = NULL; done: // cleanup if (mdl != NULL) IoFreeMdl(mdl); if (uci_param != NULL) ExFreePool(uci_param); if (query_irp != NULL) IoCompleteRequest(query_irp, IO_NO_INCREMENT); }
NTSTATUS tdi_query_address(PFILE_OBJECT addressFileObject, PULONG addr, PUSHORT port) { PDEVICE_OBJECT devObj; KEVENT event; PTRANSPORT_ADDRESS localInfo; PTA_IP_ADDRESS localAddr; PIRP irp; PMDL mdl; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(addressFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); localInfo = HttpDiskMalloc(sizeof (TDI_ADDRESS_INFO) * 10); if (localInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(localInfo, sizeof(TDI_ADDRESS_INFO)*10); irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, devObj, addressFileObject, &event, &iosb); if (irp == NULL) { ExFreePool(localInfo); return STATUS_INSUFFICIENT_RESOURCES; } { mdl = IoAllocateMdl((void*) localInfo, sizeof(TDI_ADDRESS_INFO)*10, FALSE, FALSE, NULL); if (mdl == NULL) { IoFreeIrp(irp); ExFreePool(localInfo); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); ExFreePool(localInfo); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildQueryInformation(irp, devObj, addressFileObject, NULL, NULL, TDI_QUERY_ADDRESS_INFO, mdl); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } localAddr = (PTA_IP_ADDRESS)&localInfo->Address[0]; if (addr) { *addr = localAddr->Address[0].Address[0].in_addr; } if (port) { *port = localAddr->Address[0].Address[0].sin_port; } ExFreePool(localInfo); return status; }
NTSTATUS LpxTdiQueryInformation( IN PFILE_OBJECT ConnectionFileObject, IN ULONG QType, IN PVOID Buffer, IN ULONG BufferLen ) { NTSTATUS status; KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; PMDL mdl; if (QType != TDI_QUERY_CONNECTION_INFO) return STATUS_NOT_IMPLEMENTED; if (BufferLen != sizeof(TDI_CONNECTION_INFO)) return STATUS_INVALID_PARAMETER; LtDebugPrint (3, ("[LpxTdi] LpxTdiQueryInformation: Entered\n")); KeInitializeEvent( &event, NotificationEvent, FALSE ); deviceObject = IoGetRelatedDeviceObject( ConnectionFileObject ); irp = TdiBuildInternalDeviceControlIrp( TDI_QUERY_INFORMATION, deviceObject, connectionFileObject, &event, &ioStatusBlock ); if (irp == NULL) { LtDebugPrint( 1, ("[LpxTdi] LpxTdiQueryInformation: Can't Build IRP.\n") ); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( Buffer, BufferLen, FALSE, FALSE, irp ); if (mdl == NULL) { LtDebugPrint( 1, ("[LpxTdi] LpxTdiQueryInformation: Can't Allocate MDL.\n") ); IoFreeIrp( irp ); return STATUS_INSUFFICIENT_RESOURCES; } MmBuildMdlForNonPagedPool( mdl ); TdiBuildQueryInformation( irp, deviceObject, ConnectionFileObject, LpxTdiQueryInformationCompletionRoutine, NULL, QType, mdl ); status = LpxTdiIoCallDriver( deviceObject, irp, NULL, NULL, TRUE ); #if DBG if (status != STATUS_SUCCESS) { LtDebugPrint(1, ("[LpxTdi]LpxTdiQueryInformation: Failed. STATUS=%08lx\n", status)); } #endif return status; }