Модель обмена данными по шине 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

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.