Сбой при запуске службы драйвер параллельного порта из за ошибки

Обновлено: 07.07.2024

Кузин Ю.Р.
дата публикации 05-01-2005 13:40

Прочитал я недавно где-то в интернете, что драйвер параллельного порта в Windows 2000 и Windows XP непосредственно поддерживает работу с устройствами в режимах EPP и ECP, и решил проверить, в чем это выражается и как это использовать. Меня больше интересовал режим EPP, который более практичен, так как представляет собой "вынос" шины ISA за пределы компьютера. Попытки найти что-то путное в интернете привели к статье Тарасенко, где неплохо изложены общие принципы работы с драйвером параллельного порта. Но этого было недостаточно, поэтому пришлось лезть на MSDN и посмотреть, что по этому поводу говорит Майкрософт. Далекий от совершенства online-справочник сориентирован в основном на разработчиков драйверов, поскольку предполагает специальные знания на каждом шагу. Поэтому одновременно с библиотечным разделом Operating a Parallel Device Attached to a Parallel Port мне пришлось держать открытыми некоторые файлы из DDK. Возможно потому, что я сам скорее железячник, чем программист, я избегаю написания собственных драйверов. Ведь для того, чтобы мое устройство заработало на чужом компьютере, туда придется поставить собственный драйвер кустарного производства, а это, во-первых, неудобно, во-вторых, может привести к "непредсказуемому поведению системы": начиная от дырок для вирусов (что всегда очень трудно просчитать) и заканчивая тривиальным крахом системы. Как мне кажется, большая часть пользователей склоняется к применению того, что нам досталось от Microsoft в том убогом виде как это есть. Именно для этих людей я и решил написать статью, чтобы помочь им избежать трудностей, с которыми я столкнулся.

Начну с того, что объясню общие правила работы клиента с каким-либо драйвером Windows. Вообще говоря, под клиентом понимается или другой драйвер, работающий в режиме ядра, или приложение, работающее в пользовательском режиме. В MSDN, к сожалению, не часто проводят эту грань различия в том или ином документе, а разница есть: не все, что может использовать клиент-драйвер, может применить клиент-приложение. Проходит время пока следуя тексту, наконец поймешь, что вот именно ЭТО пригодно только для драйвера. Windows следует идеологии многоуровневых драйверов. В качестве примера можно привести драйвер от производителя принтера, использующий для своей работы драйвер параллельного порта Microsoft, тот же самый которым мы хотели бы воспользоваться непосредственно из приложения. Забегая вперед скажу, что поскольку мое тестовое устройство все-таки не захотело сразу работать из под Windows, несмотря на нормальную работу в EPP режиме из под DOS, мне пришлось, вооружившись цифровым осциллографом с памятью и логическим анализатором, более внимательно изучить, что же все-таки предлагает Майкрософт за рамками собственной документации. Результаты и побудили меня к написанию этой статьи.

  1. открыть устройство;
  2. настроить нужный режим;
  3. читать из и писать в устройство;
  4. закрыть устройство.

Все эти операции проделываются с помощью механизма запросов ввода-вывода драйвера (IRPs). Пользователю доступны функции, формирующие такие запросы. В Delphi для их использования нужно подключить модуль Windows.pas:

1 ШАГ Функция CreateFile формирует запрос, открывающий устройство. Например, такой вызов открывает порт LPT1 для операций асинхронного чтения и записи:

Если все запросы должны выполняться синхронно, то вызов будет выглядеть так: Здесь hLPT - дескриптор устройства, который затем используется при обращении к его драйверу:

2 ШАГ Управление работой устройства, определение его состояния, поддержка режимов и т.д. осуществляется с помощью запросов IRP_MJ_DEVICE_CONTROL и IRP_MJ_INTERNAL_DEVICE_CONTROL. В режиме пользователя поддерживается только запрос первого типа - он формируется с помощью функции DeviceIoControl. В качестве одного из параметров этой функции фигурирует код операци и ( IOCTL ), который определяет действие, выполняемое драйвером. Для некоторых устройств (например, COM-порта) в API Win32 определены функции управления, которые служат оболочкой для DeviceIoControl при определенном значении IOCTL . Это делает программу более наглядной и читаемой. Для параллельного порта я такой возможности не обнаружил, хотя это не вызывает трудностей, поскольку никто не мешает описать такие функции самому.

Тело такой функции будет сводится к вызову DeviceIoControl с определенным набором параметров. Гораздо более неприятный момент заключается в том, что для LPTx невозможно определить коммуникационное событие, чтобы затем обработать его в отдельном потоке как это можно сделать, например, для последовательного порта с помощью вызова SetCommEvents . Поэтому о готовности Вашего устройства к каким-либо операциям, оно может сообщить, только выставив флаг в некотором своем регистре, который Вы будете регулярно опрашивать (например, по таймеру), что конечно не очень удобно и эффективно. Вообще говоря, в режиме EPP параллельного порта определено внешнее прерывание по положительному переходу на линии 10 (nACK), и драйвер содержит его обработчик. Доступ к обработчику можно получить с помощью IRP_MJ_INTERNAL_DEVICE_CONTROL, но только в режиме ядра. Еще раз хочу подчеркнуть, что все изложенное - результат моих собственных поисков, поэтому не исключено, что какое-то решение от Microsoft для обработки событий параллельного порта в режиме пользователя существует. Если кто-нибудь знает, поделитесь. В конце статьи я укажу E-mail для связи.

Рассмотрим по порядку все коды операций доступные в качестве аргумента в вызове DeviceIoControl при работе с LPTx. Код представляет собой 32-разрядное слово и строится по определенному правилу, которое учитывает тип устройства, вид и метод доступа. Не вдаваясь в подробности, перечислим значения кодов для управления параллельным портом и их идентификаторы, принятые в Microsoft.

Обращаю внимание читателя, что статья приготовлена для сайта Delphi, поэтому все примеры кода и т.п. приводятся на Паскале. Коды в таблице указаны в шестнадцатеричном формате (т.е. 0х160014 и т.д.).

Код IOCTL_IEEE1284_GET_MODE предназначен для формирования запроса текущего режима порта:

Если запрос синхронный, то он выглядит так:

@Mode - указатель на буфер, в котором драйвер возвращает текущий режим. Следующий параметр сообщает драйверу размер буфера, а параметр ret возвращает размер структуры, через которую передаются данные. Структура PARCLASS_NEGOTIATION_MASK имеет два поля: usReadMask - определяет режим работы порта при чтении, а usWriteMask - при записи. Вот возможные значения этих переменных:

Сразу после того, как порт открыт, он устанавливается в режим CENTRONICS по записи и NIBBLE по чтению.

Код операции IOCTL_IEEE1284_NEGOTIATE предназначен для согласования режима работы порта и устройства:

@ReqMode указывает на структуру PARCLASS_NEGOTIATION_MASK, которая содержит маску тестирования режимов для работы с устройством. Маска представляет собой произвольную сумму, указанных выше констант.

Драйвер выполняет последовательность согласования с устройством для каждого указанного в маске режима в соответствии со спецификацией IEEE 1284. Если соответствующий бит в маске выставлен в 1, то данный режим проверяется на возможность его применения при работе с подключенным устройством, а затем выбирается режим с максимальной пропускной способностью. Этот режим устанавливается в качестве текущего, а соответствующие ему значения драйвер возвращает в структуре LptMode. Кроме указанных выше констант, однозначно обозначающих режимы, Windows определяет еще две маски для запроса:

Чтобы запросить проверку всех режимов, нужно указать $7FF.

После согласования режима драйвер не переводит выходные линии порта в состояние, соответствующее выбранному режиму! Он оставляет их в состоянии инициализации:

В таком состоянии выводы находятся сразу после открытия порта, или после сброса драйвера (см. далее). При первом обращении к порту на предмет ввода-вывода драйвер сначала сообщит устройству о начале работы повторением последовательности согласования (на этот раз только для выбранного режима), а затем осуществит обмен данными. После этого состояние линий будет соответствовать выбранному режиму, и уже каждый последующий цикл ввода-вывода будет происходить по обычной схеме.

Код IOCTL_PAR_GET_DEFAULT_MODES применяется для запроса режима драйвера по умолчанию: CENTRONICS для записи и NONE для чтения. Может быть возможны и другие варианты, поэтому приведу команду целиком.

В структуре Mode возвращается режим по умолчанию в той же манере, что и для запроса текущего режима IOCTL_IEEE1284_GET_MODE.

  • совместимости (Centronics);
  • полубайтный (Nibble);
  • байтный (Byte_Bidir);
  • EPP;
  • ECP.
  • адресуемый полубайтный (CHANNEL_NIBBLE);
  • программный EPP (EPP_SW);
  • программный ECP (ECP_SW);
  • упрощенный ECP (BOUNDED_ECP).

Запрос с кодом IOCTL_PAR_GET_DEVICE_CAPS похож на IOCTL_IEEE1284_NEGOTIATE с той разницей, что он не меняет режим драйвера, а только проводит циклы согласования с устройством для всех(. ) режимов, чтобы выяснить какие из них поддерживаются. Затем результат проверки возвращается в уже известной структуре PARCLASS_NEGOTIATION_MASK.

Если выдать этот запрос на пустой порт (без устройства), то будет отмечена поддержка только CENTRONICS и IEEE_COMPATIBILITY. Соответственно и включить никакие другие режимы будет невозможно. Исключение составляет только NIBBLE, который согласно спецификации должен поддерживаться всеми IEEE1284-устройствами. Чтобы использовать другой режим, например EPP, необходимо подключить устройство, поддерживающее последовательность согласования для этого режима. В ходе цикла согласования хост выставляет на шину данных байт совместимости, который уникален для каждого режима:

Затем по отрицательному переходу сигнала Paper End (конт. 12) хост проверяет уровень на линии Select (конт. 13). Если устройство подтверждает режим, то на эту линию оно должно выставить 1, в противном случае - 0. Байт совместимости имеет очень удобную структуру для его аппаратной обработки: за каждым режимом закреплен определенный бит, который выставляется в единицу только для этого режима. Поэтому, скажем для EPP, достаточно защелкнуть 6 бит (считая от 0) по сигналу nStrobe (1 конт.) и вернуть его по линии Select. Если сигнал Select просто навсегда установить в 1 (подтянуть к +5В), то устройство будет подтверждать все режимы.

Что касается других сигналов, то для согласования работы с драйвером параллельного порта достаточно на линях nError (конт. 15) и Paper End выставить лог. 1, а для формирования сигнала завершения цикла согласования можно по линии nACK (конт. 10) вернуть в хост уровень nAutoFeed (конт. 14). Так как оборванный вход LPT-порта воспринимается как 1, то для реализации этой последовательности достаточно просто воткнуть в разъем перемычку на контакты 10 и 14. Такое "устройство" драйвер распознает как поддерживающее следующие режимы: CENTRONICS, IEEE_COMPATIBILITY, NIBBLE, CHANNEL_NIBBLE, BYTE_BIDIR, EPP_SW, - т.е. все режимы, кроме аппаратного EPP и всех разновидностей ECP. Дело в том, что согласование ECP (который, кстати, придуман Microsoft в сотрудничестве с HP) требует более сложной последовательности согласования, и простой аппаратурой здесь не обойтись. В интернете свободно распространяется файл ecp_reg.pdf от Microsoft с подробным описанием режима.

Ситуация с аппаратным EPP еще более оригинальная: при запросе этого режима на разъеме порта……..ничего не происходит. А драйвер сообщает, что режим не поддерживается. Отсутствие даже намека на попытку согласования EPP_HW позволяет сделать вывод о том, что именно сам драйвер не поддерживает этот режим,- возможно из-за каких-то трений между Microsoft и Intel - автором EPP, может из-за технических нестыковок. Ниже сопоставляются сигналы в режимах аппаратного и программного EPP, а также применение соответствующих линий в цикле согласования.

Здесь надо обратить внимание на две вещи. Во-первых, в программной реализации EPP Майкрософт случайно или намеренно перепутал сигналы местами: строб адреса теперь на контакте 16 разъема, т.е. он соответствует сигналу nInitialize. На контакте 17 остается признак интерфейса 1284, как и во всех остальных режимах, включая последовательность согласования. Этот сигнал можно использовать как ChipSelect (активный высокий). Сигнала сброса nReset как такового нет, но есть последовательность сброса, которую выполняет драйвер по соответствующему запросу (см. далее). Во-вторых, из-за ограниченности набора сигналов одни и те же линии используются как в циклах квитирования режимов, так и в цикле согласования (например, Data Strobe - AutoFeed, Write - Strobe). Поэтому если не принять определенных мер, то во время последовательности согласования будет сымитирован цикл записи, и в регистр устройства будет записан байт совместимости, что не всегда допустимо. Мало того, непосредственно перед этим имитируется чтение данных из устройства, несмотря на наличие байта на выходе LPT. Работа двух устройств на выход одновременно не сулит ничего хорошего. В моем случае внешнее устройство "перетягивало" порт, изменяя байт совместимости. В худшем случае что-нибудь может выгореть.

Последовательность согласования предусматривает возможность запроса идентификатора устройства, который представляет собой нуль-терминальную строку. Эту строку Windows выдает на экран при обнаружении нового устройства. Чтобы сделать запрос ID, придется воспользоваться кодами IOCTL_PAR_QUERY_DEVICE_ID, IOCTL_PAR_QUERY_DEVICE_ID_SIZE, IOCTL_PAR_QUERY_RAW_DEVICE_ID.

С помощью кода IOCTL_PAR_QUERY_INFORMATION у драйвера можно запросить информацию об его состоянии.

В поле ParInfo.Status драйвер возвращает байт, который может представлять собой комбинацию следующих чисел

Прямого соответствия между битами ParInfo.Status и физическими регистрами параллельного порта нет, но какая-то нетривиальная взаимосвязь существует: определенные комбинации входных сигналов на разъеме порождают различное состояние поля статуса драйвера.

Код IOCTL_PAR_SET_INFORMATION применяется для сброса драйвера.

  • nStrobe (конт. 1) - высокий;
  • nInitialize (конт. 16) - низкий;
  • nSelectIn (конт. 17) - низкий;

Запрос IOCTL_SERIAL_SET_TIMEOUTS устанавливает значение таймаута, которое драйвер использует в операциях записи в режимах SPP и ECP_SW. Прочитать установленное значение можно с помощью IOCTL_SERIAL_GET_TIMEOUTS.

3 ШАГ Чтобы сформировать цикл записи адреса EPP, нужно воспользоваться кодом IOCTL_PAR_SET_WRITE_ADDRESS.

Новый цикл будет сформирован лишь при условии, что в очередном запросе драйверу будет передан новый адрес. Драйвер пытается устранять избыточные операции - благая цель, которая усложняет систему и как следствие влечет ошибки. Я полагаю, что программист Майкрософт не правильно понял смысл чтения адреса EPP, поэтому такая операция отсутствует, зато есть команда IOCTL_PAR_SET_READ_ADDRESS, которая не формирует физических циклов, но настраивает драйвер таким образом, что он создает цикл записи адреса непосредственно перед циклом чтения данных. При этом драйвер, оптимизируя циклы адреса, не всегда работает разумно. Поэтому, не вдаваясь в подробности, я не рекомендую вообще использовать IOCTL_PAR_SET_READ_ADDRESS, тем более что он не дает ничего дополнительно по сравнению с IOCTL_PAR_SET_WRITE_ADDRESS.

Для записи данных в устройство используется функция WriteFile, а для чтения ReadFile. Обе функции обрабатывают поток данных, а не отдельный байт. Это означает, что для режима EPP будет последовательно сформировано столько циклов записи (чтения) данных, сколько необходимо, чтобы передать весь массив байт за байтом. Естественно, что все данные при этом уйдут по одному адресу. Ниже приводится пример кода, в котором производится запись $55 по адресу $AA, а затем чтение по адресам $AA и $BB.

4 ШАГ Закрывается устройство обычным образом: с помощью функции CloseHandle .


Смотрите также материалы по темам: [LPT] [Драйверы]

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

В логах критическая ошибка

- Provider

[ Name] Microsoft-Windows-Kernel-Power
[ Guid]
[ ProcessID] 4
[ ThreadID] 8

BugcheckCode 30
BugcheckParameter1 0xffffffffc0000005
BugcheckParameter2 0x0
BugcheckParameter3 0x8
BugcheckParameter4 0x0
SleepInProgress 0
PowerButtonTimestamp 0
BootAppStatus 0
Checkpoint 0
ConnectedStandbyInProgress false
SystemSleepTransitionsToOn 3
CsEntryScenarioInstanceId 0
BugcheckInfoFromEFI false
CheckpointStatus 0

Ответы

dism /online /cleanup-image /scanhealth
-dism /Online /Cleanup-image /Restorehealth
-chkdsk /f - reboots

Все ответы

This posting is provided "AS IS" with no warranties, and confers no rights.

  • Предложено в качестве ответа Vector BCO Moderator 12 июня 2018 г. 16:32

This posting is provided "AS IS" with no warranties, and confers no rights.

dism /online /cleanup-image /restorehealth

chkdsk /f %SystemDrive%

Последняя проведет проверку после перезагрузки.

This posting is provided "AS IS" with no warranties, and confers no rights.

Первая проверка выдала ошибки. После 2 и 3 "пункта" повторная проверка ошибок не выявила, нарушения целостности не выявлено.

В bugCheck нашел "дубли" ошибки kernel power

Service Control Manager

Сбой при запуске службы "luafv" из-за ошибки
Загрузка драйвера была заблокирована

Так же есть ошибки в Distrubuted COM

Здравствуйте.
Ноутбук начал крайне медленно загружаться. В списке ошибок особенно часты 1 и 11.

набор ошибок в письменном виде ****************************
1. Службе планировщика заданий не удается запустить задачи, активируемые при загрузке компьютера. Дополнительные сведения: значение ошибки: 2147942402. Действие пользователя: перезапустите службу планировщика заданий.

2. Event filter with query "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA "Win32_Processor" AND TargetInstance.LoadPercentage > 99" could not be reactivated in namespace "//./root/CIMV2" because of error 0x80041003. Events cannot be delivered through this filter until the problem is corrected.

3. Служба "Рабочая станция" является зависимой от службы "SMB 1.x MiniRedirector", которую не удалось запустить из-за ошибки
Указанная служба не может быть запущена, поскольку она отключена или все связанные с ней устройства отключены.

4. Сбой при запуске службы "Parallel port driver" из-за ошибки
Указанная служба не может быть запущена, поскольку она отключена или все связанные с ней устройства отключены.

5. Сбой при запуске службы "adfs" из-за ошибки
Не удается найти указанный файл.

6. Служба "Intel(R) Host Controller Interface (non-volatile memory)" завершена из-за ошибки
Не найден указанный модуль.

7. Служба "Служба загрузки изображений Windows (WIA)" является зависимой от службы "Определение оборудования оболочки", которую не удалось запустить из-за ошибки
Указанная служба не может быть запущена, поскольку она отключена или все связанные с ней устройства отключены.

8. Служба "Windows Audio 5.1 Surround" завершена из-за ошибки
Не найден указанный модуль.

9. Сбой при загрузке драйвера(ов) перезагрузки или запуска системы:
amdkmafd
ASPI32

10. Начало загрузки Windows:
Длительность загрузки: : 66052мс
IsDegradation : false
Время события (UTC) : 27.07.2019 15:51:17

11. Драйвер обнаружил ошибку контроллера \Device\Ide\IdePort0.
*****************

Виндовс Виста Home Basic сп2 х32, от вирусов всё проверено - ничего. Но с удовольствием проверю ещё раз.
Виста мне именно что нравится, поэтому переустановка или апгрейд не предпочтительны.

Также в диспетчере устройств многовато всего повторяется. Почему? Это норма или неполадка? баг или фича?


иллюстрация

Плюс к тому при загрузке винды в безопасном режиме очень долго застревает на \Windows\system32\drivers\crcdisk.sys


ещё одна

Тоже интересно почему и что происходит? В целом как всё это лечить?

В предыдущей статье мы собирали "антикризисный" ПК. Там мы добавили в итоговую конфигурацию Ryzen 5 3400G, со встроенным графическим ядром Vega 11. Сегодня я расскажу на собственном опыте, с какой конкретно проблемой столкнулся спустя несколько месяцев эксплуатации данного железа. Хотелось бы сразу отметить, что нижеописанная проблема характерна для многих процессоров Ryzen со встроенным GPU.

И так собственно проблема, о которой я хотел поговорить в данной статье это внезапная перезагрузка ПК во время игр. Наверняка возможны также внезапные ребуты и при других нагрузках на GPU, по крайней мере, я видел жалобы от людей на различных форумах в интернете. В логах, лично у меня, при этом появлялись следующие ошибки:

Событие 41, Kernel-Power:

"Система перезагрузилась, завершив работу с ошибками. Возможные причины ошибки: система перестала отвечать на запросы, произошел критический сбой или неожиданно отключилось питание".

Событие 6008, EventLog:

Предыдущее завершение работы системы в xx:xx:xx на ‎xx.‎xx.‎xxxx было неожиданным.

Событие 7000, Service Control Manager:

Сбой при запуске службы "ElevationService" из-за ошибки

Не удается найти указанный файл.

Событие 7000, Service Control Manager:

Сбой при запуске службы "WsDrvInst" из-за ошибки

Не удается найти указанный файл.

Событие 7000, Service Control Manager:

Сбой при запуске службы "SSGDIO" из-за ошибки

Отказано в доступе.

Поиск в гугле решений не дал, были найдены лишь рекомендации, некоторые из которых я действительно применил.

Первое что я сделал, это естественно проверил температуру CPU в нагрузке, обновил драйвер графического ядра и сбросил настройки графики в Default, а так же отключил автоматическую перезагрузку в свойствах системы:

Результата это не принесло. Далее выполнил проверку и восстановление системных файлов Windows, командой sfc /scannow.

К слову, на некоторых форумах людям помогали "мифические" обновления ОС. Но у меня и так были установлены все последние обновления. Переустанавливать ОС я не решился, не наши это методы, к тому же система у меня довольно свежая. Нельзя сказать, что я днями и ночами искал, как решить данную проблему, но время от времени возвращался к поиску решения.

И вот в один из таких вечеров, нагуглив очередной совет по обновлению Bios, я решил его обновить. Вообще я не сторонник обновления Bios только лишь ради обновления. В принципе об этом пишут на своих сайтах и производители. Но тут сам бог велел. Скачал последнюю прошивку с официального сайта производителя, отформатировал флешку в FAT32, закинул на эту флешку скачанный файл. После перезагрузки ПК зашел в Bios и обновил его. Стоит отметить, что Bios обновлялся минут 10-15, и после обновления и перезагрузки ПК он не сразу стартанул. Пришлось даже выключать компьютер принудительно, по питанию. Однако после дальнейшего, успешного старта, я убедился, что Bios таки обновился. С тех пор проблем с внезапными перезагрузками в играх у меня нет.

Перейдем к выводам: если купили и используете процессоры Ryzen со встроенным GPU, в первую очередь обновляйте Bios. Сэкономите нервы, время и даже возможно деньги :)

На этом, пожалуй, всё, если понравилась статья, подписывайтесь на мой канал Дзен и на канал в телеграм .

Читайте также: