Модель обмена данными по шине MIL-STD-1553B микропроцессорных устройств
Построение рабочей системы в виде готового программного продукта, с отражением результатов его тестирования. Ознакомление с интерфейсом между приложением и драйвером режима ядра. Рассмотрение процесса выбора и обоснования метода установки драйвера.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 20.12.2017 |
Размер файла | 956,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Модель обмена данными по шине MIL-STD-1553B микропроцессорных устройств
Введение
На сегодняшний день MIL-STD-1553B является фактически общепризнанным и распространенным повсеместно стандартом Министерства обороны США, который поддерживается разработчиками аппаратных средств и электронных компонентов большого числа различных стран. Стандарт магистрального последовательного интерфейса MIL-STD-1553B стал в действительности первым в своем роде стандартом для протокола ЛВС. Характерным примером применения данного интерфейса является соединение датчиков и, так называемого, регистратора событий, известного также как «черный ящик» [1]. Кроме того, шина MIL-STD-1553B широко используются при разработке встраиваемых систем управления космических аппаратов, а также бортового электронного оборудования авиационной и оборонной техники с целью обмена данными среди отдельных модулей системы. В таких системах становится актуальной проблема организации взаимодействия отдельных элементов в единой системе, ради осуществления обмена информацией между ними.
Рассматриваемый в данной работе программный продукт является результатом исследования, предметами которого выступают алгоритмическая и программная реализация модели мультиплексного канала обмена данными последовательного интерфейса MIL-STD-1553B. Не смотря на достаточно продолжительный период существования стандарта, в этой области отсутствуют похожие программные исполнения, целью которых является решение проблемы, описанной в данном исследовании. В виду этого, данная работа является актуальной в том смысле, что предлагает свои варианты и подходы к вопросу организации разработки систем на базе протокола MIL-STD-1553B.
Топология сети, в соответствии со стандартом MIL-STD-1553B, - это, как упоминалось ранее, мультиплексный канал информационного обмена (выполненный в виде экранированной витой пары), устройства к которому подсоединяются при помощи шлейфов. В качестве применимых устройств используются контроллер шины (КШ), удаленные терминалы (УТ) и монитор шины [2]. Весь обмен на шине осуществляется целиком под руководством КШ и инициализируется сугубо им. Тем самым КШ может адресовать свои команды любому подключенному к интерфейсу УТ, используя уникальный адрес длиной 5 бит, назначенный каждому из терминалов. Монитор шины - пассивное устройство, тоже соединенное с шиной данных, но занимающееся исключительно наблюдением и протоколированием информации, которая передается по шине.
Поток информации кодируется с помощью, вероятно, наиболее несложного самосинхронизирующегося кода Манчестер-2, также именуемого как манчестерский код. Скорость обмена по шине составляет порядка 1 Мбит/с, что соответствует установленной частоте повторения импульсов около 1 МГц. Учитывая накладные расходы, связанные с синхронизацией, фактическая пропускная способность, конечно, значительно ниже.
Теоретический интерес к разработке, описанного в данной работе программногопродукта, лежит в основной цели текущего исследования, а именно поиске оптимального способа программной реализации модели обмена данными по шине MIL-STD-1553B с сохранением временных параметров и возможностей стандарта. Практический же интерес представлен тем фактом, что полученное программноеисполнение реализует рассмотренные в данном исследовании алгоритмы и методы без какой-либо опоры на готовые решения в данной области и является самостоятельным результатом изложенной работы.Оценка работоспособности программной модели даст возможность сформулировать основные ограничения, накладываемые на ее использование, и позволит выявить требования необходимые для корректной работы симуляции и всей системы в целом.
Вопреки своему приличному возрасту, упомянутый стандарт актуален в наши дни, он успешно используется в бортовом электронном оборудовании (главным образом в космической и авиационной технике), а также находит применение в системах гражданского и специализированного назначения [1]. Несложность проектирования ЛВС на основе данного стандарта, а также значительная пропускная способность и надежность могут иметь интерес для проектировщиков аппаратуры для производственной автоматики, медицинской аппаратуры, железнодорожного транспорта и многого другого.
При разработке систем с использованием протокола MIL-STD-1553B необходимо учитывать ряд этапов тестирования, включающих верификацию, системную интеграцию / моделирование [3]. Ввиду того, что данный стандарт акцентирует внимание на проверке формата сообщений, необходимо тестировать с введением (инъекцией) ошибок на всех этапах тестирования. Программная модель обмена данными по шине MIL-STD-1553B позволит разрабатывать управляющую (программную) часть встраиваемых систем, использующих данный протокол для взаимодействия между отдельными модулями, независимо от аппаратной части. Это облегчает процесс разработки и поиск оптимальных решений на ее ранних этапах без наличия в сборе реальной системы, а лишь на основании анализа модели, что в свою очередь ускорит процесс разработки всей системы в целом.
Важной задачей данного исследования так же является анализ протокола обмена данными по шине MIL-STD-1553B, необходимый при практическом построении программной модели для симуляции информационного обмена, согласно упомянутому стандарту. Так для целей текущего исследования необходимо сконструировать такую модель, временные параметры, а также скорость работы, которой будут сопоставимы с временными характеристиками, заявленными в указанном стандарте, и скоростью работы, близкой к реальным аппаратным решениям. Целью текущей работы является построение рабочей системы в виде готового программного продукта, с отражением результатов его тестирования. Представленное программное решение, выполненное, например, в форме библиотеки функций, должно с минимальными затратами на адаптацию итегрироваться с проектами, в которых возможноиспользование симуляции протокола обмена по стандарту MIL-STD-1553B на ранних этапах разработки.
1. Теоретическая часть
1.1 Структура стандарта MIL-STD-1553B
Любая транзакция в сети осуществляется с помощью слов длиной в 20 битовых интервалов. Младшие три бита используются в качестве синхропоследовательности (SYNC), представляющей собой импульс протяженностью в три битовых интервала с переходом через нулевой уровень в промежутке второго интервала. Последний бит выступает в качестве бита контроля четности. Тип слова специфицируется направлением перехода через нулевой уровень: отрицательный скачок (от U к -U) идет впереди командного слова (КС) или ответного слова (ОС), положительный скачок находится впереди слов данных (СД). Тип и структура слов стандартаMIL-STD-1553B изображаются на рисунке 1.1.
Рисунок 1.1 - Тип и структура слов стандарта MIL-STD-1553B
Ранее отмечалось, что автором любой транзакции в сети, является исключительно КШ, который посылает на шину команды, сообщающие удаленным терминалам о необходимости выполнения определенных действий, в том числе приема и передачи данных. Следом за синхропоследовательностью КС содержит 5 бит, отведенные под адрес УТ, которому адресована данная команда. В качестве групповых сообщений предназначен адрес 111112. После адреса терминала следует бит передачи/приема, указывающий УТ порядок информационного обмена - передачу или прием данных (в том случае, если бит равен 1, УТ обязан передавать данные). Следующие 5 бит специфицируют подадрес или так называемый признак режима управления. В случае последнего этому полю соответствует одно из значений 111112 либо 000002. Любое другое значение означают подадрес, т.е. обращение к конкретным функциям или подсистемам, подключенным через УТ. Оставшиеся 5 информационных бит КС - это число СД или код режима управления (в том случае, если в предшествующем поле задан признак режима управления). Число СД указывает, какое количество СД необходимо передать/принять после команды (значение 000002 соответствует 32 словам). Код режима управления - это специализированные команды, описанные в стандарте MIL-STD-1553B (принятие управления интерфейсом, синхронизация, блокировка передатчика и т.п.). Передача данных осуществляется с помощью слов размером 16 бит.
Ответные слова или слова статуса - это сообщения, используемые удаленными терминалами для уведомления КШ о возникновении ошибок приема, извещения о своем состоянии, а также исправном статусе подсистем, подключенных к ним, удостоверении приема команды и данных и т.п.
Последовательность слов (командных слов, слов данных и ответных слов) образовывают сообщения. В соответствии с терминологией MIL-STD-1553B сообщениями являются конкретные формы обмена информацией [2]. Предусмотрено только 10 форматов сообщений. К примеру, передача данных от контроллера шины к удаленному терминалу осуществляется с помощью сообщения следующего вида: [КС (адрес УТ)] [СД 1] [СД 2] … [СД N] [ОС (подтверждение приема)].
Формат сообщения передачи данных от одного удаленного терминала к другому имеет следующий вид: [КС (адрес УТ 1)] [КС (адрес УТ 2)] [ОС (подтверждение приема команды от УТ 2)] [СД 1] [СД 2] … [СД N] [ОС (подтверждение приема данных от УТ 1)].
Несмотря на то, что этот стандарт был разработан для особых применений, при которых требуется максимальная надежность работы системы, как правило, в реальных системах наряду с основной шиной используется также и дублирующая (зачастую на схемах они обозначаются как шины А и В) [3]. Вариант применения дублирующей шины в сети стандарта MIL-STD-1553B изображен на рисунке 1.2.
Рисунок 1.2 - Применение двух шин в сети стандарта MIL-STD-1553B
Все возможные устройства, соединяются с каждой из этих шин, позволяя использовать их как в качестве основной и резервной, так и самостоятельно друг от друга. Отсюда большая часть всех существующих трансиверов для интерфейса MIL-STD-1553B имеют дублированный передатчик/приемник.
2. Интерфейс между приложением и драйвером режима ядра
Для организации взаимодействия между драйвером режима ядра и пользовательским приложением, как правило, желательно использовать промежуточныйпрограммный уровень абстракции, который в общем случае носит название драйвера пользовательского режима.
Драйвер пользовательского режима необходим для выполнения следующихосновных задач:
1. Предоставление интерфейсамежду драйвером режима ядра и приложением пользователя.
2. Инкапсуляция обращения к драйверным функциям и сокрытие подробностей и метода их вызова.
3. Уменьшение зависимостей в пользовательском коде.
Тот интерфейс, который предоставляет данный тип драйвера, образовывает готовый набор функций - библиотеку - использующих возможности драйвера режима ядра, и тем самым формирует его API- программный интерфейс приложения.
За счет создания дополнительного уровня абстракции, драйвер пользовательского режима избавляет от необходимости знания деталей реализациивходных и выходных типов данных, а также управляющих кодов необходимых для осуществления запросов к модулю драйвера режима ядра.
Одной из немаловажных задач является также предотвращение модификации пользовательского кода в случае изменения драйверного кода. Любые изменения в коде драйвера, затрагивающие входные и выходные параметры или их типы, а также управляющие коды запросов ввода/вывода, не должны влиять на код пользователя APIдрайвера. Данный программный уровень абстракции и позволяет уменьшить или избежать подобного рода ненужных зависимостей в пользовательском коде.
Схема взаимодействия пользователького приложения с драйвером изображена на рисунке 2.1.
Рисунок 2.1 - Взаимодействие пользовательского приложения с драйвером
Практически схема взаимодействия имеет три уровня. На верхнем уровне расположено приложение пользователя вместе с его программным кодом. Пользовательский код обращается к драйверу режима ядра посредством того API, который предоставляет драйвер пользовательского режима.
Драйвер пользовательского режима, расположенный на уровне ниже, выполнен в виде динамически загружаемой библиотеки. Доступ к функциям драйвера режима ядра реализован как формирование запросов ввода/вывода, заполнение необходимых входных параметров и отправление управляющих кодов ввода/вывода (input/output control code или IOCTL)непосредственно к модулю драйвера режима ядра. Сформированные на этом уровне запросы к драйверу отправляются посредством вызовасистемной функции DeviceIoControl(), входящей в состав WindowsAPI, и обрабатываются Диспетчером ввода/вывода операционной системы.
Диспетчер ввода/вывода формирует пакет запроса на ввод/вывод (input/output request packet или IRP) и отправляет его целевому драйверу, в том случае, если он зарегистрирован в системе. Драйвер режима ядра, расположенный на данной схеме на нижнем уровне, принимает сформированные пользователем запросы в виде IRP пакетов. Пакет запроса на ввод/вывод содержит необходимые драйверу входные параметры, а также код IOCTL запроса, который вместе с входными параметрами анализируется обработчиком запросов ввода/вывода самого драйвера. На основе анализа входных данных драйвер приступает к выполнению запрошенной пользователем операции и по ее окончании формирует ответ на запрос в виде оговоренных интерфейсом выходных параметров.
Подобный уровневый подход позволяет делегировать запросы/ответы уровню расположенному ниже/выше именно в той форме, которую требует интерфейс между двумя конкретными уровнями. Это позволяет избежать знания деталий рализации отдельных уровней, представляя систему как некий «черный ящик» с набром входных и выходных параметров.
2.1 Выбор и обоснование метода установки драйвера
Использование простого, быстрого и удобного способаустановки драйвера режима ядра в систему является важной частью как процесса разработки и отладки драйвера, так и его непосредственного применения конечным пользователем.
В общем случае драйвер может быть установлен в систему статически и динамически. В первом случае установка драйвера осуществляется при старте системы Windows. Данный подход плохо подходит для наших целей, т.к. не обладает достаточной гибкостью. В свою очередь динамическая установка и удаление могут осуществляться в подходящий момент в процессе работы системы без необходимости ее перезагрузки. В текущем случае такой метод является наиболее предпочтительным. Данное решение может быть реализовано за счет разработки дополнительной утилиты (небольшой специальной программы), единственными целями которой будут установка драйвера в систему и его удаление из системы. Включение подобной утилиты в состав программного пакета наряду с самим драйвером режима ядра, а также драйвером пользовательсого режима, избавит пользователя API драйвера от сложных деталей реализации установки, а также выбора ее методов, и обеспечитлегкую настройку окружения и быстрый способ замены текущего драйвера в случае выхода его новой версии. программный драйвер интерфейс
Выбранный метод динамической установки драйвера основан на взаимодействии приложения с диспетчером управления службами (service control manager или SCM) операционной системы Windows, который позволяет обеспечить создание, запуск, остановку, а также удаление служб операционной системы. Запуск службы драйвера может осуществляться как при старте операционной системы, так и по требованию пользователя вручную.
Также необходимо, чтобы установщик был способен сообщить о текущем состоянии драйвера в системе: установлена ли служба драйвера, требует ли она запуска или, к примеру, отсутствует в системе и требует установки.
Для лучшего взаимодействия с пользователем, желательно, чтобы установщик обладал GUI (graphical user interface) - графическим интерфейсом пользователя, а также понятными элементами управления интерфейса, конкретно отражающими функционал приложения.
В процессе разработки и испытания драйвера существенное значение имеетего быстрая инсталляция и деинсталляция. Возможность осуществления этого без необходимости прерывать работу системы значительно ускорит его разработку и упростит отладку, что на практике предоставит больше времени для написания тестовых приложений и примеров использования API драйвера.
В немаловажной степени то, насколько удобно реализован процесс установки и удаления, оказывает влиянее на то, как быстро представленный программный продукт интегрируется с проектными решениями, использующими симуляцию протокола обмена по стандарту MIL-STD-1553B. По своей сути быстрая настройка окружения для возможности применения API драйвера является неотъемлемой частью самих идей и целейразработки и использования данного программного обеспечения.
Библиографический список
Список использованных источников
1. EickhoffJ. OnboardComputers, OnboardSoftwareandSatelliteOperations: AnIntroduction. - SpringerScience&BusinessMedia, 2011.
2. Jose J. An FPGA implementation of 1553 protocol controller // International Journal of Computer Information Systems and Industrial Management Applications. - 2014.
3. Randhawa R. H., Imran M. A low cost design of MIL-STD-1553 devices // 2012 IEEE First AESS European Conference on Satellite Telecommunications (ESTEL). - IEEE, 2012.
Список публикаций соискателя
1-A. Шпак, А. В. Модель обмена данными по шине MIL-STD-1553B / А. В. Шпак // Компьютерные системы и сети: материалы 53-й научной конференции аспирантов, магистрантов и студентов (Минск, 2 - 6 мая 2017 г.). - Минск: БГУИР, 2017. - С. 57 - 58.
Приложения
Приложение А
Листинг кода драйвера
режима ядра
/************************************************************************/
/* Virtual1553B.cpp */
/************************************************************************/
#include"stdafx.h"
#include"IoControlHandler.h"
#include"WorkerThreads.h"
NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject, INPUNICODE_STRINGRegistryPath)
{
Virtual1553B_DbgPrintSeparator();
Virtual1553B_DbgPrintEntry();
UNREFERENCED_PARAMETER(RegistryPath);
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
NTSTATUSStatus = STATUS_SUCCESS;
UNICODE_STRINGDeviceName = { 0 };
RtlInitUnicodeString(&DeviceName, L"\\Device\\Virtual1553B0");
PDEVICE_OBJECTDeviceObject = NULL;
Status = IoCreateDevice(
DriverObject,
sizeof(VIRTUAL1553B_EXTENSION),
&DeviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
Virtual1553B_DbgPrintExit_1("IoCreateDevice() failed. Error: %08X.", Status);
returnStatus;
}
if (!DeviceObject)
{
Virtual1553B_DbgPrintExit_1("IoCreateDevice() failed. Error: %08X.",
STATUS_UNEXPECTED_IO_ERROR);
returnSTATUS_UNEXPECTED_IO_ERROR;
}
UNICODE_STRINGWin32Device = { 0 };
RtlInitUnicodeString(&Win32Device, L"\\DosDevices\\Virtual1553B0");
Status = IoCreateSymbolicLink(&Win32Device, &DeviceName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
Virtual1553B_DbgPrintExit_1("IoCreateSymbolicLink() failed. Error: %08X.", Status);
returnStatus;
}
InitializeExtension((PVIRTUAL1553B_EXTENSION)(DeviceObject->DeviceExtension));
Virtual1553B_DbgPrintExit_0("Success.");
returnSTATUS_SUCCESS;
}
VOIDDriverUnload(INPDRIVER_OBJECTDriverObject)
{
Virtual1553B_DbgPrintSeparator();
Virtual1553B_DbgPrintEntry();
UNICODE_STRINGWin32Device = { 0 };
RtlInitUnicodeString(&Win32Device, L"\\DosDevices\\Virtual1553B0");
IoDeleteSymbolicLink(&Win32Device);
IoDeleteDevice(DriverObject->DeviceObject);
Virtual1553B_DbgPrintExit();
}
NTSTATUSDriverCreate(INPDEVICE_OBJECTDeviceObject, INPIRPIrp)
{
Virtual1553B_DbgPrintSeparator();
Virtual1553B_DbgPrintEntry();
UNREFERENCED_PARAMETER(DeviceObject);
Virtual1553B_DbgPrint_2("Process ID: 0x%p, Reference count: %ld.",
(PVOID)PsGetCurrentProcessId(), DeviceObject->ReferenceCount);
VIRTUAL1553B_COMPLETE_RETURN(Irp, STATUS_SUCCESS, 0);
}
NTSTATUSDriverClose(INPDEVICE_OBJECTDeviceObject, INPIRPIrp)
{
Virtual1553B_DbgPrintSeparator();
Virtual1553B_DbgPrintEntry();
HANDLEProcessId = PsGetCurrentProcessId();
Virtual1553B_DbgPrint_2("Process ID: 0x%p, Reference count: %ld.",
(PVOID)(ProcessId), DeviceObject->ReferenceCount);
PVIRTUAL1553B_EXTENSIONExtension = (PVIRTUAL1553B_EXTENSION)(DeviceObject->DeviceExtension);
for (LONG_PTRTerminalIndex = 0; TerminalIndex<VIRTUAL_TERMINAL_NUMBER; ++TerminalIndex)
{
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
if (VirtualTerminal->ProcessIdOwner == ProcessId)
{
AcquireVirtualTerminal(VirtualTerminal);
if (VirtualTerminal->Mode != UndefinedMode)
{
switch (VirtualTerminal->Mode)
{
caseBusControllerMode:
Virtual1553B_CloseWorkerThreads(VirtualTerminal);
break;
caseRemoteTerminalMode:
Virtual1553B_RevokeRemoteTerminal(&Extension->TerminalMap, VirtualTerminal);
break;
caseBusMonitorMode:
Virtual1553B_RevokeBusMonitor(&Extension->TerminalMap, VirtualTerminal);
break;
}
VirtualTerminal->Mode = UndefinedMode;
PVOIDTerminalPointer = InterlockedExchangePointer(
&VirtualTerminal->TerminalPointer, NULL);
ExFreePoolWithTag(TerminalPointer, 0);
}
PVOIDInterruptEvent = InterlockedExchangePointer(
&VirtualTerminal->InterruptEvent, NULL);
VirtualTerminal->ProcessIdOwner = NULL;
ReleaseVirtualTerminal(VirtualTerminal);
if (InterruptEvent)
{
ObDereferenceObject(InterruptEvent);
}
Virtual1553B_DbgPrint_2("Process ID: 0x%p, Terminal index: %ld.",
(PVOID)(ProcessId), (LONG)(TerminalIndex));
}
}
VIRTUAL1553B_COMPLETE_RETURN(Irp, STATUS_SUCCESS, 0);
}
NTSTATUSDriverDeviceControl(INPDEVICE_OBJECTDeviceObject, INPIRPIrp)
{
Virtual1553B_DbgPrintSeparator();
Virtual1553B_DbgPrintEntry();
NTSTATUSStatus = STATUS_SUCCESS;
PVIRTUAL1553B_EXTENSIONExtension = (PVIRTUAL1553B_EXTENSION)(DeviceObject->DeviceExtension);
PIO_STACK_LOCATIONIrpStackLocation = IoGetCurrentIrpStackLocation(Irp);
ULONGIoControlCode = IrpStackLocation->Parameters.DeviceIoControl.IoControlCode;
switch (IoControlCode)
{
caseIOCTL_VIRTUAL1553B_ALLOC_TERMINAL:
caseIOCTL_VIRTUAL1553B_FREE_TERMINAL:
caseIOCTL_VIRTUAL1553B_INSTALL_EVENT:
caseIOCTL_VIRTUAL1553B_REMOVE_EVENT:
caseIOCTL_VIRTUAL1553B_GET_TERMINAL_MODE:
caseIOCTL_VIRTUAL1553B_START_BUS_CONTROLLER:
caseIOCTL_VIRTUAL1553B_START_REMOTE_TERMINAL:
caseIOCTL_VIRTUAL1553B_START_BUS_MONITOR:
caseIOCTL_VIRTUAL1553B_STOP_TERMINAL:
caseIOCTL_VIRTUAL1553B_BC_EXECUTE_TRANSFER:
caseIOCTL_VIRTUAL1553B_BC_GET_TRANSFER_RESULT:
caseIOCTL_VIRTUAL1553B_RT_SET_ADDRESS:
caseIOCTL_VIRTUAL1553B_RT_GET_ADDRESS:
caseIOCTL_VIRTUAL1553B_RT_WRITE_MEMORY:
caseIOCTL_VIRTUAL1553B_RT_READ_MEMORY:
caseIOCTL_VIRTUAL1553B_RT_GET_TRANSFER_RESULT:
caseIOCTL_VIRTUAL1553B_BM_GET_CURRENT_BASE:
caseIOCTL_VIRTUAL1553B_BM_GET_BASE_COUNT:
caseIOCTL_VIRTUAL1553B_BM_GET_TRANSFER_RECORD:
Status = Extension->IoControlFunction[VIRTUAL1553B_FUNCTION_FROM_IOCTL(IoControlCode)](
Extension,
IrpStackLocation->Parameters.DeviceIoControl.InputBufferLength,
IrpStackLocation->Parameters.DeviceIoControl.OutputBufferLength,
Irp);
Virtual1553B_DbgPrintExit();
returnStatus;
default:
break;
}
VIRTUAL1553B_COMPLETE_RETURN_0(Irp, STATUS_INVALID_DEVICE_REQUEST, 0,
"Invalid device request.");
}
NTSTATUSCompleteIrp(INPIRPIrp, INNTSTATUSStatus, INULONG_PTRInformation)
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
returnStatus;
}
VOIDInitializeExtension(INPVIRTUAL1553B_EXTENSIONExtension)
{
Virtual1553B_DbgPrintEntry();
RtlZeroMemory(Extension, sizeof(VIRTUAL1553B_EXTENSION));
InitializeIoControlFunction(Extension->IoControlFunction);
PVIRTUAL1553B_TRANSFER_LINELine = Extension->Bus.Line;
for (USHORTi = 0; i<TransferLineNumber; ++i)
{
Line[i].TransferLine = i;
}
PVIRTUAL_TERMINALVirtualTerminal = Extension->VirtualTerminal;
for (LONG_PTRTerminalIndex = 0; TerminalIndex<VIRTUAL_TERMINAL_NUMBER; ++TerminalIndex)
{
ExInitializeFastMutex(&VirtualTerminal[TerminalIndex].SynqMutex);
}
ExInitializeFastMutex(&Extension->TerminalMap.SynqMutex);
Virtual1553B_DbgPrintExit();
}
VOIDInitializeIoControlFunction(INPVIRTUAL1553B_IOCTL_HANDLERIoControlFunction[])
{
Virtual1553B_DbgPrintEntry();
IoControlFunction[FUNCTION_ALLOC_TERMINAL] = Virtual1553B_AllocTerminal;
IoControlFunction[FUNCTION_FREE_TERMINAL] = Virtual1553B_FreeTerminal;
IoControlFunction[FUNCTION_INSTALL_EVENT] = Virtual1553B_InstallEvent;
IoControlFunction[FUNCTION_REMOVE_EVENT] = Virtual1553B_RemoveEvent;
IoControlFunction[FUNCTION_GET_TERMINAL_MODE] = Virtual1553B_GetTerminalMode;
IoControlFunction[FUNCTION_START_BUS_CONTROLLER] = Virtual1553B_StartBusController;
IoControlFunction[FUNCTION_START_REMOTE_TERMINAL] = Virtual1553B_StartRemoteTerminal;
IoControlFunction[FUNCTION_START_BUS_MONITOR] = Virtual1553B_StartBusMonitor;
IoControlFunction[FUNCTION_STOP_TERMINAL] = Virtual1553B_StopTerminal;
IoControlFunction[FUNCTION_BC_EXECUTE_TRANSFER] = VirtualBC_ExecuteTransfer;
IoControlFunction[FUNCTION_BC_GET_TRANSFER_RESULT] = VirtualBC_GetTransferResult;
IoControlFunction[FUNCTION_RT_SET_ADDRESS] = VirtualRT_SetAddress;
IoControlFunction[FUNCTION_RT_GET_ADDRESS] = VirtualRT_GetAddress;
IoControlFunction[FUNCTION_RT_WRITE_MEMORY] = VirtualRT_WriteMemory;
IoControlFunction[FUNCTION_RT_READ_MEMORY] = VirtualRT_ReadMemory;
IoControlFunction[FUNCTION_RT_GET_TRANSFER_RESULT] = VirtualRT_GetTransferResult;
IoControlFunction[FUNCTION_BM_GET_CURRENT_BASE] = VirtualBM_GetCurrentBase;
IoControlFunction[FUNCTION_BM_GET_BASE_COUNT] = VirtualBM_GetBaseCount;
IoControlFunction[FUNCTION_BM_GET_TRANSFER_RECORD] = VirtualBM_GetTransferRecord;
Virtual1553B_DbgPrintExit();
}
/************************************************************************/
/* IoControlHandler.cpp */
/************************************************************************/
#include"stdafx.h"
#include"IoControlHandler.h"
#include"WorkerThreads.h"
NTSTATUSVirtual1553B_AllocTerminal(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
UNREFERENCED_PARAMETER(InputBufferLength);
ULONGOutBufferSize = sizeof(OUTPUT_ALLOC_TERMINAL);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_ALLOC_TERMINALOutBuffer = (POUTPUT_ALLOC_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
HANDLEProcessId = PsGetCurrentProcessId();
for (LONG_PTRTerminalIndex = 0; TerminalIndex<VIRTUAL_TERMINAL_NUMBER; ++TerminalIndex)
{
if (InterlockedCompareExchangePointer(
&Extension->VirtualTerminal[TerminalIndex].ProcessIdOwner, ProcessId, NULL))
{
continue;
}
Virtual1553B_DbgPrint_2("Process ID: 0x%p, Terminal index: %ld.",
(PVOID)(ProcessId), (LONG)(TerminalIndex));
OutBuffer->TerminalHandle = (TERMINAL_HANDLE)(TerminalIndex);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
OutBuffer->TerminalHandle = INVALID_TERMINAL_HANDLE;
VIRTUAL1553B_NO_FREE_TERMINALS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_FreeTerminal(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_FREE_TERMINAL);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_FREE_TERMINALInBuffer = (PINPUT_FREE_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_FREE_TERMINAL);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_FREE_TERMINALOutBuffer = (POUTPUT_FREE_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_IS_STOPPED(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
PVOIDInterruptEvent = InterlockedExchangePointer(&VirtualTerminal->InterruptEvent, NULL);
VirtualTerminal->ProcessIdOwner = NULL;
ReleaseVirtualTerminal(VirtualTerminal);
if (InterruptEvent)
{
ObDereferenceObject(InterruptEvent);
}
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_InstallEvent(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_INSTALL_EVENT);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_INSTALL_EVENTInBuffer = (PINPUT_INSTALL_EVENT)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_INSTALL_EVENT);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_INSTALL_EVENTOutBuffer = (POUTPUT_INSTALL_EVENT)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
NTSTATUSStatus = STATUS_SUCCESS;
PVOIDInterruptEvent = NULL;
Status = ObReferenceObjectByHandle(
InBuffer->Event,
EVENT_MODIFY_STATE,
*ExEventObjectType,
Irp->RequestorMode,
&InterruptEvent,
NULL);
if (!NT_SUCCESS(Status))
{
ReleaseVirtualTerminal(VirtualTerminal);
switch (Status)
{
caseSTATUS_ACCESS_DENIED:
VIRTUAL1553B_EVENT_HANDLE_ACCESS_DENIED_RETURN(OutBuffer, OutBufferSize, Irp);
default:
VIRTUAL1553B_INVALID_EVENT_HANDLE_RETURN(OutBuffer, OutBufferSize, Irp);
}
}
InterruptEvent = InterlockedExchangePointer(&VirtualTerminal->InterruptEvent, InterruptEvent);
ReleaseVirtualTerminal(VirtualTerminal);
if (InterruptEvent)
{
ObDereferenceObject(InterruptEvent);
}
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_RemoveEvent(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_REMOVE_EVENT);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_REMOVE_EVENTInBuffer = (PINPUT_REMOVE_EVENT)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_REMOVE_EVENT);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_REMOVE_EVENTOutBuffer = (POUTPUT_REMOVE_EVENT)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
PVOIDInterruptEvent = InterlockedExchangePointer(&VirtualTerminal->InterruptEvent, NULL);
ReleaseVirtualTerminal(VirtualTerminal);
if (InterruptEvent)
{
ObDereferenceObject(InterruptEvent);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
VIRTUAL1553B_EVENT_HANDLE_IS_NOT_INSTALLED_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_GetTerminalMode(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_GET_TERMINAL_MODE);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_GET_TERMINAL_MODEInBuffer = (PINPUT_GET_TERMINAL_MODE)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_GET_TERMINAL_MODE);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_GET_TERMINAL_MODEOutBuffer =
(POUTPUT_GET_TERMINAL_MODE)(Irp->AssociatedIrp.SystemBuffer);
OutBuffer->TerminalMode = UndefinedMode;
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
OutBuffer->TerminalMode = VirtualTerminal->Mode;
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_StartBusController(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_START_BUS_CONTROLLER);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_START_BUS_CONTROLLERInBuffer =
(PINPUT_START_BUS_CONTROLLER)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_START_BUS_CONTROLLER);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_START_BUS_CONTROLLEROutBuffer =
(POUTPUT_START_BUS_CONTROLLER)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_IS_NOT_STARTED(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_BUS_CONTROLLERBusController = (PVIRTUAL_BUS_CONTROLLER)ExAllocatePoolWithTag(
NonPagedPool, sizeof(VIRTUAL_BUS_CONTROLLER), 0);
if (!BusController)
{
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_NOT_ENOUGH_MEMORY_RETURN(OutBuffer, OutBufferSize, Irp);
}
RtlZeroMemory(BusController, sizeof(VIRTUAL_BUS_CONTROLLER));
VirtualTerminal->BusController = BusController;
VirtualTerminal->Mode = BusControllerMode;
if (!Virtual1553B_CreateWorkerThreads(
VirtualTerminal, &Extension->Bus, &Extension->TerminalMap, VirtualBC_WorkerThread))
{
VirtualTerminal->Mode = UndefinedMode;
VirtualTerminal->BusController = NULL;
ReleaseVirtualTerminal(VirtualTerminal);
ExFreePoolWithTag(BusController, 0);
VIRTUAL1553B_CREATE_WORKER_THREADS_FAILED_RETURN(OutBuffer, OutBufferSize, Irp);
}
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_StartRemoteTerminal(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_START_REMOTE_TERMINAL);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_START_REMOTE_TERMINALInBuffer =
(PINPUT_START_REMOTE_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_START_REMOTE_TERMINAL);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_START_REMOTE_TERMINALOutBuffer =
(POUTPUT_START_REMOTE_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_IS_NOT_STARTED(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_REMOTE_TERMINAL_ADDRESS(
InBuffer->Address, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_REMOTE_TERMINALRemoteTerminal = (PVIRTUAL_REMOTE_TERMINAL)ExAllocatePoolWithTag(
NonPagedPool, sizeof(VIRTUAL_REMOTE_TERMINAL), 0);
if (!RemoteTerminal)
{
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_NOT_ENOUGH_MEMORY_RETURN(OutBuffer, OutBufferSize, Irp);
}
RtlZeroMemory(RemoteTerminal, sizeof(VIRTUAL_REMOTE_TERMINAL));
VirtualTerminal->RemoteTerminal = RemoteTerminal;
VirtualTerminal->Mode = RemoteTerminalMode;
if (!Virtual1553B_RegisterRemoteTerminal(
&Extension->TerminalMap, VirtualTerminal, InBuffer->Address, FALSE))
{
VirtualTerminal->Mode = UndefinedMode;
VirtualTerminal->RemoteTerminal = NULL;
ReleaseVirtualTerminal(VirtualTerminal);
ExFreePoolWithTag(RemoteTerminal, 0);
VIRTUAL1553B_REGISTER_REMOTE_TERMINAL_FAILED_RETURN(OutBuffer, OutBufferSize, Irp);
}
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_StartBusMonitor(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_START_BUS_MONITOR);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_START_BUS_MONITORInBuffer = (PINPUT_START_BUS_MONITOR)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_START_BUS_MONITOR);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_START_BUS_MONITOROutBuffer =
(POUTPUT_START_BUS_MONITOR)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_IS_NOT_STARTED(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_BUS_MONITORBusMonitor = (PVIRTUAL_BUS_MONITOR)ExAllocatePoolWithTag(
NonPagedPool, sizeof(VIRTUAL_BUS_MONITOR), 0);
if (!BusMonitor)
{
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_NOT_ENOUGH_MEMORY_RETURN(OutBuffer, OutBufferSize, Irp);
}
RtlZeroMemory(BusMonitor, sizeof(VIRTUAL_BUS_MONITOR));
VirtualTerminal->BusMonitor = BusMonitor;
VirtualTerminal->Mode = BusMonitorMode;
if (!Virtual1553B_RegisterBusMonitor(&Extension->TerminalMap, VirtualTerminal))
{
VirtualTerminal->Mode = UndefinedMode;
VirtualTerminal->BusMonitor = NULL;
ReleaseVirtualTerminal(VirtualTerminal);
ExFreePoolWithTag(BusMonitor, 0);
VIRTUAL1553B_REGISTER_BUS_MONITOR_FAILED_RETURN(OutBuffer, OutBufferSize, Irp);
}
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtual1553B_StopTerminal(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_STOP_TERMINAL);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_STOP_TERMINALInBuffer = (PINPUT_STOP_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_STOP_TERMINAL);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_STOP_TERMINALOutBuffer = (POUTPUT_STOP_TERMINAL)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_IS_STARTED(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
switch (VirtualTerminal->Mode)
{
caseBusControllerMode:
Virtual1553B_CloseWorkerThreads(VirtualTerminal);
break;
caseRemoteTerminalMode:
Virtual1553B_RevokeRemoteTerminal(&Extension->TerminalMap, VirtualTerminal);
break;
caseBusMonitorMode:
Virtual1553B_RevokeBusMonitor(&Extension->TerminalMap, VirtualTerminal);
break;
}
VirtualTerminal->Mode = UndefinedMode;
PVOIDTerminalPointer = InterlockedExchangePointer(&VirtualTerminal->TerminalPointer, NULL);
ReleaseVirtualTerminal(VirtualTerminal);
ExFreePoolWithTag(TerminalPointer, 0);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtualBC_ExecuteTransfer(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_BC_EXECUTE_TRANSFER);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_BC_EXECUTE_TRANSFERInBuffer =
(PINPUT_BC_EXECUTE_TRANSFER)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_BC_EXECUTE_TRANSFER);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_BC_EXECUTE_TRANSFEROutBuffer =
(POUTPUT_BC_EXECUTE_TRANSFER)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_MODE(
BusControllerMode, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TRANSFER_LINE(
InBuffer->TransferLine, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
PVIRTUAL1553B_TRANSFER_LINELine = &Extension->Bus.Line[InBuffer->TransferLine];
switch (InBuffer->ExecuteTransferBuffer.Format)
{
caseTransferBCRT:
caseTransferBCRTBroadcast:
VIRTUAL1553B_TRY_LOCK_TRANSFER_LINE(Line, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
Line->CW1 = InBuffer->ExecuteTransferBuffer.CW1;
RtlCopyMemory(Line->Data, InBuffer->ExecuteTransferBuffer.Data,
GET_DATA_WORD_COUNT(Line->CW1.Raw) * sizeof(USHORT));
break;
caseTransferRTBC:
VIRTUAL1553B_TRY_LOCK_TRANSFER_LINE(Line, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
Line->CW1 = InBuffer->ExecuteTransferBuffer.CW1;
break;
caseTransferRTRT:
caseTransferRTRTBroadcast:
VIRTUAL1553B_TRY_LOCK_TRANSFER_LINE(Line, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
Line->CW1 = InBuffer->ExecuteTransferBuffer.CW1;
Line->CW2 = InBuffer->ExecuteTransferBuffer.CW2;
break;
caseModeCommandWithoutData:
caseModeCommandWithoutDataBroadcast:
VIRTUAL1553B_TRY_LOCK_TRANSFER_LINE(Line, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
Line->CW1 = InBuffer->ExecuteTransferBuffer.CW1;
break;
caseModeCommandWithDataReceive:
caseModeCommandWithDataReceiveBroadcast:
VIRTUAL1553B_TRY_LOCK_TRANSFER_LINE(Line, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
Line->CW1 = InBuffer->ExecuteTransferBuffer.CW1;
Line->Data[0] = InBuffer->ExecuteTransferBuffer.Data[0];
break;
caseModeCommandWithDataTransmit:
VIRTUAL1553B_TRY_LOCK_TRANSFER_LINE(Line, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
Line->CW1 = InBuffer->ExecuteTransferBuffer.CW1;
break;
default:
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_UNKNOWN_MESSAGE_FORMAT_RETURN(OutBuffer, OutBufferSize, Irp);
}
Line->Format = InBuffer->ExecuteTransferBuffer.Format;
Line->Time = KeQueryPerformanceCounter(NULL);
Virtual1553B_InitiateTransfer(VirtualTerminal, InBuffer->TransferLine);
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtualBC_GetTransferResult(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_BC_GET_TRANSFER_RESULT);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_BC_GET_TRANSFER_RESULTInBuffer =
(PINPUT_BC_GET_TRANSFER_RESULT)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_BC_GET_TRANSFER_RESULT);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_BC_GET_TRANSFER_RESULTOutBuffer =
(POUTPUT_BC_GET_TRANSFER_RESULT)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_MODE(
BusControllerMode, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
OutBuffer->TransferResult = VirtualTerminal->BusController->TransferResult;
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtualRT_SetAddress(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_RT_SET_ADDRESS);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_RT_SET_ADDRESSInBuffer = (PINPUT_RT_SET_ADDRESS)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_RT_SET_ADDRESS);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_RT_SET_ADDRESSOutBuffer = (POUTPUT_RT_SET_ADDRESS)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_MODE(
RemoteTerminalMode, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_REMOTE_TERMINAL_ADDRESS(
InBuffer->Address, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
if (!Virtual1553B_RegisterRemoteTerminal(
&Extension->TerminalMap, VirtualTerminal, InBuffer->Address, TRUE))
{
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_REMAP_REMOTE_TERMINAL_FAILED_RETURN(OutBuffer, OutBufferSize, Irp);
}
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtualRT_GetAddress(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_RT_GET_ADDRESS);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_RT_GET_ADDRESSInBuffer = (PINPUT_RT_GET_ADDRESS)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_RT_GET_ADDRESS);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_RT_GET_ADDRESSOutBuffer = (POUTPUT_RT_GET_ADDRESS)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_MODE(
RemoteTerminalMode, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
OutBuffer->Address = VirtualTerminal->RemoteTerminal->Address;
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtualRT_WriteMemory(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_RT_WRITE_MEMORY);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
POUTPUT_RT_WRITE_MEMORYOutBuffer = (POUTPUT_RT_WRITE_MEMORY)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_RT_WRITE_MEMORY);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
PINPUT_RT_WRITE_MEMORYInBuffer = (PINPUT_RT_WRITE_MEMORY)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_VALIDATE_TERMINAL_OWNER(VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TERMINAL_MODE(
RemoteTerminalMode, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_TRANSFER_DIRECTION(
InBuffer->Direction, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_SUBADDRESS(
InBuffer->Subaddress, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
VIRTUAL1553B_VALIDATE_DATA_WORD_COUNT(
InBuffer->WordCountToWrite, VirtualTerminal, OutBuffer, OutBufferSize, Irp);
switch (InBuffer->Direction)
{
caseDirectionReceive:
RtlCopyMemory(GetReceiveBuffer(VirtualTerminal->RemoteTerminal, InBuffer->Subaddress),
InBuffer->Buffer, InBuffer->WordCountToWrite * sizeof(USHORT));
break;
caseDirectionTransmit:
RtlCopyMemory(GetTransmitBuffer(VirtualTerminal->RemoteTerminal, InBuffer->Subaddress),
InBuffer->Buffer, InBuffer->WordCountToWrite * sizeof(USHORT));
break;
}
OutBuffer->WordCountWritten = InBuffer->WordCountToWrite;
ReleaseVirtualTerminal(VirtualTerminal);
VIRTUAL1553B_SUCCESS_RETURN(OutBuffer, OutBufferSize, Irp);
}
NTSTATUSVirtualRT_ReadMemory(
INPVIRTUAL1553B_EXTENSIONExtension,
INULONGInputBufferLength,
INULONGOutputBufferLength,
INPIRPIrp)
{
Virtual1553B_DbgPrintEntry();
ULONGInBufferSize = sizeof(INPUT_RT_READ_MEMORY);
VIRTUAL1553B_VALIDATE_INPUT_BUFFER_LENGTH(InputBufferLength, InBufferSize, Irp);
PINPUT_RT_READ_MEMORYInBuffer = (PINPUT_RT_READ_MEMORY)(Irp->AssociatedIrp.SystemBuffer);
ULONGOutBufferSize = sizeof(OUTPUT_RT_READ_MEMORY);
VIRTUAL1553B_VALIDATE_OUTPUT_BUFFER_LENGTH(OutputBufferLength, OutBufferSize, Irp);
POUTPUT_RT_READ_MEMORYOutBuffer = (POUTPUT_RT_READ_MEMORY)(Irp->AssociatedIrp.SystemBuffer);
LONG_PTRTerminalIndex = (LONG_PTR)(InBuffer->TerminalHandle);
VIRTUAL1553B_VALIDATE_TERMINAL_INDEX(TerminalIndex, OutBuffer, OutBufferSize, Irp);
PVIRTUAL_TERMINALVirtualTerminal = &Extension->VirtualTerminal[TerminalIndex];
AcquireVirtualTerminal(VirtualTerminal);
Подобные документы
Описание исходных текстов программного продукта. Системные требования и установка программного продукта. Тестирование пользователя по двадцати вопросам указанной темы и сохранение результатов тестирования. Форма отображения результатов тестирования.
курсовая работа [2,8 M], добавлен 09.07.2013Характеристика основных методов и средств моделирования мультиагентных систем. Ознакомление с результатами экспериментального тестирования и отладки программного комплекса. Рассмотрение методов оценки качества разработанного программного продукта.
дипломная работа [3,1 M], добавлен 27.10.2017Операция обмена данными между прикладной программой и шиной USB путем передачи буферов памяти. Основные характеристики каналов. Аппаратная часть USB. Физическая топология шины. Конструкция кабелей и коннекторов. Способы питания устройств от сети.
контрольная работа [218,4 K], добавлен 27.01.2014Разработка драйверов ядра Windows. Драйвер виртуальных устройств Windows - компьютерная программа, с помощью которой другая программа получает доступ к аппаратному обеспечению стандартным образом. Доступ к драйверам из приложений пользовательского режима.
курсовая работа [436,1 K], добавлен 25.10.2012Использование драйвера режима ядра и управляющего приложения для создания системных потоков. Имитация обработки данных и организация задержек. Разработка драйвера на языке C++. Конфигурация тестового стенда. Точность изменения задержек и работы таймера.
курсовая работа [182,4 K], добавлен 24.06.2009Проектирование информационной системы для удобного ведения учета товара. Функциональная модель предметной области. Обоснование выбора языка программирования. Описание программы, руководство пользователя. Протокол тестирования программного продукта.
курсовая работа [537,6 K], добавлен 18.09.2014Разработка программного обеспечения для микропроцессорных систем МК51, интерфейсы в системах связи, основы асинхронной связи. Этапы решения задачи на ЭВМ, принципы тестирования программ и их отладка. Расчет затрат на разработку программного продукта.
дипломная работа [270,6 K], добавлен 19.06.2010Требования к создаваемому программному модулю. Разработка необходимых алгоритмов и интерфейсов. Описание протокола SPA-BUS. Выбор языка программирования. Тестирование и документирование программного продукта. Оценка экономической эффективности программы.
дипломная работа [722,4 K], добавлен 06.07.2012Механизмы взаимодействия драйвера режима ядра и пользовательского приложения: многослойная драйверная архитектура, алгоритм сокрытия данных, взаимодействие драйвера и приложения, пользовательский интерфейс программы фильтрации доступа к файлам.
курсовая работа [1023,3 K], добавлен 23.06.2009Автоматизация учета и управления, использование тиражных программных продуктов системы "1С: Предприятие". OLE - технология управления и обмена информацией между программным интерфейсом другими приложениями. Установка среды разработки, совместимой с 1С.
курсовая работа [558,9 K], добавлен 20.03.2013