[skip]
TC>Сбросте флаг устройства DO_DEVICE_INITIALIZING после завершения инициализации ( выхода из DriverEntry )
TC>DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
Этого делать не надо, так как на все обьекты устройства созданные в DriverEntry это зделает I/O manager. А вот на все остальные которые создаем это делать обязательно.
Пусто
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Задача такая: программно манипулировать напряжением на определенных ногах LPT порта (устанавливать лог. 1 или 0).
Для этого дела написал вот такой вот драйвер:
#ifndef _X86_
#define _X86_ // target arch#endif
#ifdef _DEBUG
#define DBG 1 // ddk debug routines such as ASSERT#endif
#pragma warning(disable: 4005)
#ifdef __cplusplus
extern"C"{
#endif
#include <wdm.h>
NTSTATUS DriverEntry (PDRIVER_OBJECT, PUNICODE_STRING);
NTSTATUS AddDevice (PDRIVER_OBJECT, PDEVICE_OBJECT);
void DriverUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS DispatchPnp(PDEVICE_OBJECT, PIRP);
NTSTATUS DispatchPower(PDEVICE_OBJECT, PIRP);
NTSTATUS DispatchRead(PDEVICE_OBJECT, PIRP);
NTSTATUS DispatchWrite(PDEVICE_OBJECT, PIRP);
/*
DriverEntry is the first routine called after a driver is loaded,
and is responsible for initializing the driver.
*/
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, // Caller-supplied pointer to driver object.
IN PUNICODE_STRING RegistryPath) // Pointer to a Unicode string - driver's registry key
{
UNICODE_STRING DeviceNameUnicodeString;
UNICODE_STRING DeviceLinkUnicodeString;
PDEVICE_OBJECT DeviceObject=NULL;
NTSTATUS ntStatus;
RtlInitUnicodeString(&DeviceNameUnicodeString,L"\\Device\\LPTCable");
ntStatus=IoCreateDevice(DriverObject, 0, &DeviceNameUnicodeString, 0x8012,0,FALSE,&DeviceObject);
if(NT_SUCCESS(ntStatus))
{
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
// Create a symbolic link, e.g. a name that a Win32 app can specify
// to open the device.
RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\\DosDevices\\LPTCable");
ntStatus=IoCreateSymbolicLink(&DeviceLinkUnicodeString, &DeviceNameUnicodeString);
if(!NT_SUCCESS(ntStatus))
{
IoDeleteDevice(DeviceObject);
return ntStatus;
}
}
return ntStatus;
}
NTSTATUS AddDevice( IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
return STATUS_SUCCESS;
}
void DriverUnload(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DeviceLinkUnicodeString;
RtlInitUnicodeString (&DeviceLinkUnicodeString, L"\\DosDevices\\LPTCable");
IoDeleteSymbolicLink(&DeviceLinkUnicodeString);
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS DispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
return STATUS_SUCCESS;
}
NTSTATUS DispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
return STATUS_SUCCESS;
}
NTSTATUS DispatchRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
return STATUS_SUCCESS;
}
NTSTATUS DispatchWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
UCHAR data;
if(Irp->Size<1)
return STATUS_SUCCESS;
data = ((char*)Irp->UserBuffer)[0];
WRITE_PORT_UCHAR((PUCHAR)0x378, data);
return STATUS_SUCCESS;
}
#ifdef __cplusplus
} // extern C#endif
Всё нормально компилируется после шаманских плясок при настройке опций компилера и линкера. Драйвер устанавливается и не глючит (пока ещё).
Теперь как я понимаю, надо сделать приложение или User-Mode dll для того, чтобы этому драйверу посылать данные. Для этих целей создал тестовое прилодение, из которого делаю вот что:
Здравствуйте, serg_fork, Вы писали:
M>>При этом девайс не открывается, а GetLastError выдает S_FALSE
_>Драйвер устанавливали? Он виден в системе как работающий?
Да. Он висит у меня в системных устройствах, говорит, что работает.
_>P.S. А как GetLastError может выдавать S_FALSE ? S_FALSE — ошибка с кодом 1.
Перед тем, как улучшиться, ситуация ухудшается. (из законов Мерфи)
Здравствуйте, Macr0s, Вы писали:
M>Здравствуйте, serg_fork, Вы писали:
M>>>При этом девайс не открывается, а GetLastError выдает S_FALSE
_>>Драйвер устанавливали? Он виден в системе как работающий?
M>Да. Он висит у меня в системных устройствах, говорит, что работает.
_>>P.S. А как GetLastError может выдавать S_FALSE ? M> S_FALSE — ошибка с кодом 1.
Я почему спросил — коды GetLastError расцениваются несколько по другим критериям
В вашем случае 1 = ERROR_INVALID_FUNCTION = Incorrect function.
Здравствуйте, serg_fork, Вы писали:
_>Я почему спросил — коды GetLastError расцениваются несколько по другим критериям _>В вашем случае 1 = ERROR_INVALID_FUNCTION = Incorrect function.
Хмм, где эти этикритерии? Мне сама студия сказала что у мя ошибка такая скриншот
А если INVALID_FUNCTION, то это куда надо копать? Кто инвалид?
Перед тем, как улучшиться, ситуация ухудшается. (из законов Мерфи)
У Вас драйвер написан в стиле Pnp — присутствует AddDevice! хотя на самом деле он должен быть Legacy!
Драйвер не загружен по той причине что системе не удается найти устройство для которого по спецификации PnP должен загружатся Ваш драйвер! Уберите инициализацию AddDevice в DriverEntry
Здравствуйте, Macr0s, Вы писали:
M>При этом девайс не открывается, а GetLastError выдает S_FALSE M>Что тут не так?
Нужно обязательно задать диспетчеры IRP_MJ_CREATE и IRP_MJ_CLOSE — без них открыть устройсвтво как файл невозможно
M>З.Ы. Почему-то DriverUnload не выполняется при удалении устройства.
Сбросте флаг устройства DO_DEVICE_INITIALIZING после завершения инициализации ( выхода из DriverEntry )
Здравствуйте, Злость, Вы писали:
З>Этого делать не надо, так как на все обьекты устройства созданные в DriverEntry это зделает I/O manager. А вот на все остальные которые создаем это делать обязательно.
Согласен, DDK пишет:
Note It is not necessary to clear the DO_DEVICE_INITIALIZING flag on device objects that are created in DriverEntry, because this is done automatically by the I/O Manager. However, your driver should clear this flag on all other device objects that it creates.
Почему-то DriverUnload не выполняется при удалении устройства.
А как Вы удаляете устройство? Попробуйте выполнить команду net stop имя_вашего_сервиса без каких-либо иных действий. Если на устройстве не будет открыт файл — драйвер должен выгрузиться.