_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; }
_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; }
_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; }