コード例 #1
0
ファイル: device.c プロジェクト: killbug2004/lcxl-net-loader
_Use_decl_annotations_
NTSTATUS
FilterDeviceIoControl(
    PDEVICE_OBJECT        DeviceObject,
    PIRP                  Irp
    )
{
    PIO_STACK_LOCATION          irp_sp;
    NTSTATUS                    status = STATUS_SUCCESS;
    PFILTER_DEVICE_EXTENSION    filter_device_extension;
    PUCHAR                      input_buffer;
    PUCHAR                      output_buffer;
    ULONG                       input_buffer_length, output_buffer_length;
    PLIST_ENTRY                 link;
    PUCHAR                      info;
    ULONG                       InfoLength = 0;
    PLCXL_FILTER                filter = NULL;
    BOOLEAN                     bFalse = FALSE;


    UNREFERENCED_PARAMETER(DeviceObject);


    irp_sp = IoGetCurrentIrpStackLocation(Irp);

    if (irp_sp->FileObject == NULL) {
        return(STATUS_UNSUCCESSFUL);
    }


    filter_device_extension = (PFILTER_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(DeviceObject);

    ASSERT(filter_device_extension->Signature == 'FTDR');

    Irp->IoStatus.Information = 0;

	input_buffer = output_buffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
	input_buffer_length = output_buffer_length = irp_sp->Parameters.DeviceIoControl.InputBufferLength;

    switch (irp_sp->Parameters.DeviceIoControl.IoControlCode) {

        case IOCTL_FILTER_RESTART_ALL:
            break;

        case IOCTL_FILTER_RESTART_ONE_INSTANCE:
            filter = filterFindFilterModule (input_buffer, input_buffer_length);

            if (filter == NULL) {

                break;
            }
            NdisFRestartFilter(filter->filter_handle);
            break;

        case IOCTL_FILTER_ENUERATE_ALL_INSTANCES:

            info = output_buffer;
			LockLCXLLockList(&g_filter_list);
            
            link = GetListofLCXLLockList(&g_filter_list)->Flink;
			//遍历列表
			while (link != GetListofLCXLLockList(&g_filter_list)) {
                filter = CONTAINING_RECORD(link, LCXL_FILTER, filter_module_link);

                InfoLength += (filter->module_setting->filter_module_name->Length + sizeof(USHORT));

                if (InfoLength <= output_buffer_length) {
					*(PUSHORT)info = filter->module_setting->filter_module_name->Length;
                    NdisMoveMemory(info + sizeof(USHORT),
						(PUCHAR)(filter->module_setting->filter_module_name->Buffer),
						filter->module_setting->filter_module_name->Length);

					info += (filter->module_setting->filter_module_name->Length + sizeof(USHORT));
                }
                link = link->Flink;
            }
			UnlockLCXLLockList(&g_filter_list);
            if (InfoLength <= output_buffer_length) {
                status = NDIS_STATUS_SUCCESS;
            }
            //
            // Buffer is small
            //
            else {
                status = STATUS_BUFFER_TOO_SMALL;
            }
            break;
		//添加代码
		case IOCTL_LOADER_ALL_APP_MODULE:
		{
			PAPP_MODULE_INFO cur_buf;
			PLCXL_MODULE_SETTING_LIST_ENTRY module;

			cur_buf = (PAPP_MODULE_INFO)output_buffer;
			LockLCXLLockList(&g_setting.module_list);
			module = CONTAINING_RECORD(GetListofLCXLLockList(&g_setting.module_list)->Flink, LCXL_MODULE_SETTING_LIST_ENTRY, list_entry);
			while (&module->list_entry != GetListofLCXLLockList(&g_setting.module_list)) {
				//先判断缓冲区是否足够
				if (output_buffer_length - (ULONG)((LONG_PTR)cur_buf - (LONG_PTR)output_buffer) < sizeof(APP_MODULE_INFO)) {
					status = STATUS_BUFFER_TOO_SMALL;
					break;
				}
				cur_buf->app_module_status = module->ref_count == 0 ? AMS_NO_FILTER : AMS_NORMAL;
				FILTER_ACQUIRE_LOCK(&module->lock, bFalse);
				cur_buf->real_addr = module->real_addr;
				cur_buf->virtual_ipv4 = module->virtual_ipv4;
				cur_buf->virtual_ipv6 = module->virtual_ipv6;
				LockLCXLLockList(&module->server_list);
				cur_buf->server_count = GetListCountofLCXLLockList(&module->server_list);
				UnlockLCXLLockList(&module->server_list);
				FILTER_RELEASE_LOCK(&module->lock, bFalse);
				cur_buf->miniport_net_luid = module->miniport_net_luid;

				cur_buf->filter_module_name_len = (sizeof(cur_buf->filter_module_name) < module->filter_module_name->Length) ? sizeof(cur_buf->filter_module_name) : module->filter_module_name->Length;
				RtlCopyMemory(cur_buf->filter_module_name, module->filter_module_name->Buffer, cur_buf->filter_module_name_len);

				cur_buf->miniport_friendly_name_len = (sizeof(cur_buf->miniport_friendly_name) < module->miniport_friendly_name->Length) ? sizeof(cur_buf->miniport_friendly_name) : module->miniport_friendly_name->Length;
				RtlCopyMemory(cur_buf->miniport_friendly_name, module->miniport_friendly_name->Buffer, cur_buf->miniport_friendly_name_len);

				cur_buf->miniport_name_len = (sizeof(cur_buf->miniport_name) < module->miniport_name->Length) ? sizeof(cur_buf->miniport_name) : module->miniport_name->Length;
				RtlCopyMemory(cur_buf->miniport_name, module->miniport_name->Buffer, cur_buf->miniport_name_len);

				cur_buf++;
				module = CONTAINING_RECORD(module->list_entry.Flink, LCXL_MODULE_SETTING_LIST_ENTRY, list_entry);
			}
			UnlockLCXLLockList(&g_setting.module_list);
			InfoLength = (ULONG)((ULONG_PTR)cur_buf - (ULONG_PTR)output_buffer);
		}
			break;
		case IOCTL_LOADER_SET_VIRTUAL_IP:
			if (input_buffer_length == sizeof(APP_IP)) {
				PAPP_IP ip;
				PLCXL_FILTER pFilter;

				ip = (PAPP_IP)input_buffer;
				LockLCXLLockList(&g_filter_list);
				pFilter = FindFilter(ip->miniport_net_luid);
				if (pFilter != NULL) {
					NdisAcquireSpinLock(&pFilter->module_setting->lock);
					switch (ip->ip.ip_mode) {
						//IPv4模式
					case IM_IPV4:
						pFilter->module_setting->virtual_ipv4 = ip->ip.addr.ip_4;
						break;
						//IPv6模式
					case IM_IPV6:
						pFilter->module_setting->virtual_ipv6 = ip->ip.addr.ip_6;
						break;
					default:
						status = STATUS_INVALID_PARAMETER;
						break;
					}
					NdisReleaseSpinLock(&pFilter->module_setting->lock);
				}
				
				UnlockLCXLLockList(&g_filter_list);
			} else {
				status = STATUS_INFO_LENGTH_MISMATCH;
			}
			break;
		case IOCTL_LOADER_GET_SERVER_LIST:
			if (input_buffer_length == sizeof(NET_LUID)) {
				PLCXL_FILTER pFilter;

				LockLCXLLockList(&g_filter_list); 
				pFilter = FindFilter(*(PNET_LUID)input_buffer);
				if (pFilter != NULL) {
					if (pFilter->module_setting != NULL && (pFilter->module_setting->flag & MSF_DELETE_AFTER_RESTART) == 0) {
						
					} else {
						status = STATUS_NOT_FOUND;
					}
				} else {
					status = STATUS_NOT_FOUND;
				}
				UnlockLCXLLockList(&g_filter_list);
			} else {
				status = STATUS_INFO_LENGTH_MISMATCH;
			}
			break;
		case IOCTL_LOADER_ADD_SERVER:
			if (sizeof(APP_ADD_SERVER) == input_buffer_length) {
				PAPP_ADD_SERVER app_add_server;
				PLCXL_FILTER pFilter;
				
				app_add_server = (PAPP_ADD_SERVER)input_buffer;
				LockLCXLLockList(&g_filter_list);
				pFilter = FindFilter(app_add_server->miniport_net_luid);
				if (pFilter != NULL) {
					
					LockLCXLLockList(&pFilter->module_setting->server_list);
					
					
					UnlockLCXLLockList(&pFilter->module_setting->server_list);
				}
				UnlockLCXLLockList(&g_filter_list);
			} else {
				status = STATUS_INFO_LENGTH_MISMATCH;
			}
			break;
		case IOCTL_LOADER_DEL_SERVER:
			if (sizeof(APP_DEL_SERVER) == input_buffer_length) {
				PAPP_DEL_SERVER app_del_server = (PAPP_DEL_SERVER)input_buffer;
				PLCXL_FILTER pFilter;

				LockLCXLLockList(&g_filter_list);
				pFilter = FindFilter(app_del_server->miniport_net_luid);
				UnlockLCXLLockList(&g_filter_list);
				
			} else {
				status = STATUS_INFO_LENGTH_MISMATCH;
			}
			break;
		//!添加代码!
        default:
			status = STATUS_INVALID_PARAMETER;
            break;
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = InfoLength;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}
コード例 #2
0
ファイル: device.c プロジェクト: AlexeyAB/netmap
_Use_decl_annotations_
NTSTATUS
FilterDeviceIoControl(
    PDEVICE_OBJECT        DeviceObject,
    PIRP                  Irp
    )
{
    PIO_STACK_LOCATION          IrpSp;
    NTSTATUS                    Status = STATUS_SUCCESS;
    PFILTER_DEVICE_EXTENSION    FilterDeviceExtension;
    PUCHAR                      InputBuffer;
    PUCHAR                      OutputBuffer;
    ULONG                       InputBufferLength, OutputBufferLength;
    PLIST_ENTRY                 Link;
    PUCHAR                      pInfo;
    ULONG                       InfoLength = 0;
    PMS_FILTER                  pFilter = NULL;
    BOOLEAN                     bFalse = FALSE;


    UNREFERENCED_PARAMETER(DeviceObject);

    DbgPrint("------------------FilterDeviceIoControl!\n");

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    if (IrpSp->FileObject == NULL)
    {
        return(STATUS_UNSUCCESSFUL);
    }


    FilterDeviceExtension = (PFILTER_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(DeviceObject);

    ASSERT(FilterDeviceExtension->Signature == 'FTDR');

    Irp->IoStatus.Information = 0;

    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
    {

        case IOCTL_FILTER_RESTART_ALL:
            break;

        case IOCTL_FILTER_RESTART_ONE_INSTANCE:
            InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;

            pFilter = filterFindFilterModule (InputBuffer, InputBufferLength);

            if (pFilter == NULL)
            {

                break;
            }

            NdisFRestartFilter(pFilter->FilterHandle);

            break;

        case IOCTL_FILTER_ENUERATE_ALL_INSTANCES:

            InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
            OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;


            pInfo = OutputBuffer;

            FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);

            Link = FilterModuleList.Flink;

            while (Link != &FilterModuleList)
            {
                pFilter = CONTAINING_RECORD(Link, MS_FILTER, FilterModuleLink);


                InfoLength += (pFilter->FilterModuleName.Length + sizeof(USHORT));

                if (InfoLength <= OutputBufferLength)
                {
                    *(PUSHORT)pInfo = pFilter->FilterModuleName.Length;
                    NdisMoveMemory(pInfo + sizeof(USHORT),
                                   (PUCHAR)(pFilter->FilterModuleName.Buffer),
                                   pFilter->FilterModuleName.Length);

                    pInfo += (pFilter->FilterModuleName.Length + sizeof(USHORT));
                }

                Link = Link->Flink;
            }

            FILTER_RELEASE_LOCK(&FilterListLock, bFalse);
            if (InfoLength <= OutputBufferLength)
            {

                Status = NDIS_STATUS_SUCCESS;
            }
            //
            // Buffer is small
            //
            else
            {
                Status = STATUS_BUFFER_TOO_SMALL;
            }
            break;


        default:
	    DbgPrint("WRONG request received!\n");
            break;
    }

    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = InfoLength;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;


}
コード例 #3
0
ファイル: device.c プロジェクト: Hartigan/Firewall
_Use_decl_annotations_                
NTSTATUS
NDISFilterDriverDeviceIoControl(
    PDEVICE_OBJECT        DeviceObject,
    PIRP                  Irp
    )
{
	DbgPrint("NDISFilterDriverDeviceIoControl\n");
    PIO_STACK_LOCATION          IrpSp;
    NTSTATUS                    Status = STATUS_SUCCESS;
    PFILTER_DEVICE_EXTENSION    FilterDeviceExtension;
    PUCHAR                      InputBuffer;
    PUCHAR                      OutputBuffer;
    ULONG                       InputBufferLength, OutputBufferLength;
    PLIST_ENTRY                 Link;
    PUCHAR                      pInfo;
    ULONG                       InfoLength = 0;
    PMS_FILTER                  pFilter = NULL;
    BOOLEAN                     bFalse = FALSE;


    UNREFERENCED_PARAMETER(DeviceObject);

	KIRQL OldIrql;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    if (IrpSp->FileObject == NULL)
    {
        return(STATUS_UNSUCCESSFUL);
    }


    FilterDeviceExtension = (PFILTER_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(DeviceObject);

    ASSERT(FilterDeviceExtension->Signature == 'FTDR');
    
    Irp->IoStatus.Information = 0;

	KeAcquireSpinLock(&FilterDeviceExtension->QLock, &OldIrql);
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
    {
		case IOCTL_ADD_IPV4_RULE:
			DbgPrint("IOCTL_ADD_IPV4_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(RULE_IPV4))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			PRULE_IPV4 pRuleIPv4 = ExAllocatePool(NonPagedPool, sizeof(RULE_IPV4));
			RtlCopyMemory(pRuleIPv4, InputBuffer, InputBufferLength);
			AddIPv4Rule(FilterDeviceExtension, pRuleIPv4);
			DbgPrint("IOCTL_ADD_IPV4_RULE END\n");
			break;
		case IOCTL_DEL_IPV4_RULE:
			DbgPrint("IOCTL_DEL_IPV4_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(ULONG))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			ULONG IdIPv4 = *((PULONG)(InputBuffer));
			DelIPv4Rule(FilterDeviceExtension, IdIPv4);
			DbgPrint("IOCTL_DEL_IPV4_RULE END\n");
			break;
		case IOCTL_ADD_IPV6_RULE:
			DbgPrint("IOCTL_ADD_IPV6_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(RULE_IPV6))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			PRULE_IPV6 pRuleIPv6 = ExAllocatePool(NonPagedPool, sizeof(RULE_IPV6));
			RtlCopyMemory(pRuleIPv6, InputBuffer, InputBufferLength);
			AddIPv6Rule(FilterDeviceExtension, pRuleIPv6);
			DbgPrint("IOCTL_ADD_IPV6_RULE END\n");
			break;
		case IOCTL_DEL_IPV6_RULE:
			DbgPrint("IOCTL_DEL_IPV6_RULE BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != sizeof(ULONG))
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			ULONG IdIPv6 = *((PULONG)(InputBuffer));
			DelIPv6Rule(FilterDeviceExtension, IdIPv6);
			DbgPrint("IOCTL_END_IPV6_RULE END\n");
			break;
		case IOCTL_ACTIVATE_FILTER:
			DbgPrint("IOCTL_ACTIVATE_FILTER BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != 0)
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			ActivateRules(FilterDeviceExtension);
			DbgPrint("IOCTL_ACTIVATE_FILTER END\n");
			break;
		case IOCTL_DEACTIVATE_FILTER:
			DbgPrint("IOCTL_DEACTIVATE_FILTER BEGIN\n");
			InputBuffer = Irp->UserBuffer;
			InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
			if (InputBufferLength != 0)
			{
				Status = NDIS_STATUS_FAILURE;
				break;
			}
			DeactivateRules(FilterDeviceExtension);
			DbgPrint("IOCTL_DEACTIVATE_FILTER END\n");
			break;
        case IOCTL_FILTER_RESTART_ALL:
            break;

        case IOCTL_FILTER_RESTART_ONE_INSTANCE:
            InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;

            pFilter = filterFindFilterModule (InputBuffer, InputBufferLength);

            if (pFilter == NULL)
            {
                
                break;
            }

            NdisFRestartFilter(pFilter->FilterHandle);

            break;

        case IOCTL_FILTER_ENUERATE_ALL_INSTANCES:
            
            InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
            InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
            OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
            
            
            pInfo = OutputBuffer;
            
            FILTER_ACQUIRE_LOCK(&FilterListLock, bFalse);
            
            Link = FilterModuleList.Flink;
            
            while (Link != &FilterModuleList)
            {
                pFilter = CONTAINING_RECORD(Link, MS_FILTER, FilterModuleLink);

                
                InfoLength += (pFilter->FilterModuleName.Length + sizeof(USHORT));
                        
                if (InfoLength <= OutputBufferLength)
                {
                    *(PUSHORT)pInfo = pFilter->FilterModuleName.Length;
                    NdisMoveMemory(pInfo + sizeof(USHORT), 
                                   (PUCHAR)(pFilter->FilterModuleName.Buffer),
                                   pFilter->FilterModuleName.Length);
                            
                    pInfo += (pFilter->FilterModuleName.Length + sizeof(USHORT));
                }
                
                Link = Link->Flink;
            }
               
            FILTER_RELEASE_LOCK(&FilterListLock, bFalse);
            if (InfoLength <= OutputBufferLength)
            {
       
                Status = NDIS_STATUS_SUCCESS;
            }
            //
            // Buffer is small
            //
            else
            {
                Status = STATUS_BUFFER_TOO_SMALL;
            }
            break;

             
        default:
            break;
    }
	KeReleaseSpinLock(&FilterDeviceExtension->QLock, OldIrql);
    Irp->IoStatus.Status = Status;
    Irp->IoStatus.Information = InfoLength;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return Status;
            

}