Форум программистов, компьютерный форум, киберфорум
Программирование драйверов
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,037

Создание нескольких экземпляров объекта драйвера

10.11.2014, 11:16. Показов 1829. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Прочёл книгу Солдатова (дважды), однако не нашёл там объяснения того, как можно создать несколько объектов (экземпляров) одного драйвера. У Солдатова в главе 3 "Простой драйвер "в-стиле-NT": Example.sys" приводится пример простого драйвера. В процедуре Unload производится "зачистка" объектов драйвера с учётом того, что их может быть несколько. Однако в процедурах DriverEntry и CreateDevice, как я понял, таких возможностей не предусмотрено. Честно пытался создать несколько экземпляров с помощью SCM, один создаётся и всё.

Подскажите, что нужно переделать. Пытался перенести IoCreateDevice в процедуру драйвера CreateDevice - безрезультатно. Может я что не так сделал.

Ниже куски примера из Солдатова.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
// (Файл init.cpp)
// UnloadRoutine: Выгружает драйвер, освобождая оставшиеся объекты
// Вызывается системой, когда необходимо выгрузить драйвер.
// Как и процедура AddDevice, регистрируется иначе чем
// все остальные рабочие процедуры и не получает никаких IRP.
// Arguments:  указатель на объект драйвера
//
 
#pragma code_seg("PAGE")
// Допускает размещение в странично организованной памяти
//
VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject)
{
    PDEVICE_OBJECT  pNextDevObj;
    int i;
 
    // Задаем печать отладочных сообщений √ если сборка отладочная
    #if DBG
    DbgPrint("-Example- In Unload Routine.");
    #endif
    //==========================================================
    // Нижеприведенные  операции в полномасштабном WDM драйвере
    // следовало бы поместить в обработчике IRP_MJ_PNP запросов
    // с субкодом IRP_MN_REMOVE_DEVICE, но в силу простоты
    // драйвера, сделаем это здесь.
    // Проходим по всем объектам устройств, контролируемым
    // драйвером
    pNextDevObj = pDriverObject->DeviceObject;
 
    for(i=0; pNextDevObj!=NULL; i++)
    {
        PEXAMPLE_DEVICE_EXTENSION dx =
                (PEXAMPLE_DEVICE_EXTENSION)pNextDevObj->DeviceExtension;
        // Удаляем символьную ссылку и уничтожаем FDO:
        UNICODE_STRING *pLinkName = & (dx->ustrSymLinkName);
        // !!! сохраняем указатель:
        pNextDevObj = pNextDevObj->NextDevice;
 
        #if DBG
        DbgPrint("-Example- Deleted device (%d) : pointer to FDO = %X.",
                            i,dx->fdo);
        DbgPrint("-Example- Deleted symlink = %ws.", pLinkName->Buffer);
        #endif
 
        IoDeleteSymbolicLink(pLinkName);
        IoDeleteDevice( dx->fdo);
    }
}
#pragma code_seg() // end PAGE section


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/////////////////////////////////////////////////////////////////////
// init.cpp: Инициализация драйвера
// Замечание. Рабочая версия данного драйвера должна быть
// скомпилирована как не-WDM версия. В противном случае - драйвер
// не сможет корректно загружаться и выгружаться с использованием
// программы monitor (пакет Numega Driver Studio) и сервисов SCM
// Менеджера.
 
/////////////////////////////////////////////////////////////////////
// DriverEntry            Главная точка входа в драйвер
// UnloadRoutine          Процедура выгрузки драйвера
// DeviceControlRoutine   Обработчик DeviceIoControl IRP пакетов
/////////////////////////////////////////////////////////////////////
#include "Driver.h"
 
// Предварительные объявления функций:
NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp );
VOID     UnloadRoutine(IN PDRIVER_OBJECT DriverObject);
NTSTATUS ReadWrite_IRPhandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp );
NTSTATUS Create_File_IRPprocessing(IN PDEVICE_OBJECT fdo, IN PIRP Irp);
NTSTATUS Close_HandleIRPprocessing(IN PDEVICE_OBJECT fdo, IN PIRP Irp);
 
// Хотя и нехорошо делать глобальные переменные в драйвере...
KSPIN_LOCK MySpinLock;
#pragma code_seg("INIT") // начало секции INIT
/////////////////////////////////////////////////////////////////////
// (Файл init.cpp)
// DriverEntry - инициализация драйвера и необходимых объектов
// Аргументы:  указатель на объект драйвера
//             раздел реестра (driver service key) в UNICODE
// Возвращает: STATUS_Xxx
 
extern "C"
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
                      IN PUNICODE_STRING RegistryPath  )
{
    NTSTATUS status = STATUS_SUCCESS;
    PDEVICE_OBJECT  fdo;
    UNICODE_STRING  devName;
 
    #if DBG
    DbgPrint("=Example= In DriverEntry.");
    DbgPrint("=Example= RegistryPath = %ws.", RegistryPath->Buffer);
    #endif
 
    // Экспорт точек входа в драйвер (AddDevice объявлять не будем)
    // DriverObject->DriverExtension->AddDevice= OurAddDeviceRoutine;
    DriverObject->DriverUnload = UnloadRoutine;
    DriverObject->MajorFunction[IRP_MJ_CREATE]= Create_File_IRPprocessing;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = Close_HandleIRPprocessing;
    DriverObject->MajorFunction[IRP_MJ_READ]  = ReadWrite_IRPhandler;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = ReadWrite_IRPhandler;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DeviceControlRoutine;
    //========================================================
    // Действия по созданию символьной ссылки
    // (их нужно было бы делать в OurAddDeviceRoutine, но у нас
    // очень простой драйвер и эта процедура отсутствует):
    RtlInitUnicodeString( &devName, L"\\Device\\EXAMPLE" );
 
    // Создаем наш Functional Device Object (FDO) и получаем
    // указатель на созданный FDO в нашей переменной fdo.   
    // (В WDM драйвере эту работу также следовало бы выполнять
    // в процедуре OurAddDeviceRoutine.) При создании FDO
    // будет выделено место и под структуру расширения устройства
    // EXAMPLE_DEVICE_EXTENSION (для этого мы передаем в вызов
    // ее размер, вычисляемый оператором sizeof):
    status = IoCreateDevice(DriverObject,
                            sizeof(EXAMPLE_DEVICE_EXTENSION),
                            &devName, // может быть и NULL
                            FILE_DEVICE_UNKNOWN,
                            0,
                            FALSE, // без эксклюзивного доступа
                            &fdo);
    if(!NT_SUCCESS(status)) return status;
 
    // Получаем указатель на область, предназначенную под
    // структуру расширение устройства
    PEXAMPLE_DEVICE_EXTENSION dx = (PEXAMPLE_DEVICE_EXTENSION)fdo->DeviceExtension;
    dx->fdo = fdo;  // Сохраняем обратный указатель
 
    // Применяя прием условной компиляции, вводим функцию DbgPrint,
    // сообщения которой мы сможем увидеть в окне DebugView, если
    // выполним сборку нашего драйвера как checked (отладочную)
    // версию:
    #if DBG
    DbgPrint("=Example= FDO %X, DevExt=%X.",fdo,dx);
    #endif
 
    //=======================================
    // Действия по созданию символьной ссылки
    // (их нужно было бы делать в OurAddDeviceRoutine, но у нас
    // очень простой драйвер):
    UNICODE_STRING symLinkName;   // Сформировать символьное имя:
    // #define   SYM_LINK_NAME   L"\\??\\Example"
    // Такого типа символьные ссылки ^^ проходят только в NT.
    // (То есть, если перенести бинарный файл драйвера в
    // Windows 98, то пользовательские приложения заведомо
    // не смогут открыть файл по такой символьной ссылке.)
    // Для того, чтобы ссылка работала в и Windows 98 и в NT,
    // необходимо поступать следующим образом:
    #define SYM_LINK_NAME   L"\\DosDevices\\Example"
    RtlInitUnicodeString( &symLinkName, SYM_LINK_NAME );
    dx->ustrSymLinkName = symLinkName;
    
    // Создаем символьную ссылку
    status = IoCreateSymbolicLink( &symLinkName, &devName );
    if (!NT_SUCCESS(status))
    { // при неудаче √ удалить Device Object и вернуть управление
        IoDeleteDevice( fdo );
        return status;
        } // Теперь можно вызывать CreateFile("\\\\.\\Example",...);
          // в пользовательских приложениях
 
        // Объект спин-блокировки, который будем использовать для
        // разнесения во времени выполнения кода обработчика
        // IOCTL запросов. Инициализируем его:
        KeInitializeSpinLock(&MySpinLock);
 
        // Снова используем условную компиляцию, чтобы выделить код,
        // компилируемый в отладочной версии и не компилируемый в
        // версии free (релизной):
        #if DBG
        DbgPrint("=Example= DriverEntry successfully completed.");
        #endif
        return status;
}
#pragma code_seg() // end INIT section

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//
// (Файл init.cpp)
// Create_File_IRPprocessing: Берет на себя обработку запросов с
// кодом IRP_MJ_CREATE.
// Аргументы:
// Указатель на объект нашего FDO
// Указатель на структуру IRP, поступившего от Диспетчера ВВ
//
NTSTATUS Create_File_IRPprocessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    // Задаем печать отладочных сообщений - если сборка отладочная
    #if DBG
    DbgPrint("-Example- Create File is %ws",
        &(IrpStack->FileObject->FileName.Buffer));
    #endif
return CompleteIrp(Irp,STATUS_SUCCESS,0); // Успешное завершение
}
Добавлено через 9 минут
P.S. Я правильно понимаю, что для Legacy драйверов функция AddDevice не вызывается?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.11.2014, 11:16
Ответы с готовыми решениями:

Заполнение нескольких экземпляров объекта
Я работаю с ООП в c# и понимаю его основу ( Инкапсуляция, наследование, полиморфизм ) Мне не понятен синтаксис в самом Lazarus-се . ...

Как произвести действия с одинаковыми свойствами нескольких экземпляров одного объекта?
У меня 8 панелей. Мне нужко чтобы при нажатии на одной из панелей ее свойство BevelOuter менялось на bvLowered, а все остальные панели на...

Работа с классами: создание нескольких экземпляров класса
В общем в ActionScript 3 неочень. Ситуацыя такова: Мне нужно игру на флеше написать(суть игры в том чтоб мышкой заганять мух в...

10
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.11.2014, 14:05
Цитата Сообщение от Khludenkov Посмотреть сообщение
как можно создать несколько объектов (экземпляров) одного драйвера.
Никак.
Может быть несколько устройств (DEVICE_OBJECT), у каждого устройства
может быть несколько клиентов (различать можно по FsContext1, например), но
DRIVER_OBJECT и образ драйвера всегда в одном экземпляре.

Цитата Сообщение от Khludenkov Посмотреть сообщение
В процедуре Unload производится "зачистка" объектов драйвера с учётом того, что их может быть несколько.
Нет, там не объекты драйвера удаляются, а объекты устройств (т.е. не
DRIVER_OBJECT, а DEVICE_OBJECT). В драйвере можно понасоздавать сколько
угодно DEVICE_OBJECT-ов, и они будут в связном списке pDriverObject->DeviceObject.
Код выше (Unload) демонстрирует именно это.

Цитата Сообщение от Khludenkov Посмотреть сообщение
Я правильно понимаю, что для Legacy драйверов функция AddDevice не вызывается?
Да, именно так.
0
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,037
10.11.2014, 14:13  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Может быть несколько устройств (DEVICE_OBJECT), у каждого устройства
Да, я просто оговорился. Я и хотел сказать "объекты устройств" (DEVICE_OBJECT).

Если можно подскажите, как это сделать. У Солдатова не совсем ясно описано. Да и у Они я что-то не нашёл.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.11.2014, 14:14
IoCreateDevice(Secure). Или я не понял вопрос.
0
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,037
10.11.2014, 14:32  [ТС]
У Они написано, что имена устройств задаются динамически, как-то через расширение устройства вроде.
То есть, если можно, скажите как создать несколько объектов устройств, как их различать (обращаться). У Они даже глава есть, что не надо назначать драйверам имена устройств.
И совсем ламерский вопрос, в чём отличие создания объекта драйвера (если я правильно сказал) вызовом CreateFile по имени драйвера и по символьной ссылке.

Добавлено через 41 секунду
Допустим я хочу создать три объекта драйвера.

Добавлено через 44 секунды
Пардон, три объекта устройств, управляемых этим драйвером. Как это сделать?

Добавлено через 25 секунд
DriverEntry же вызывается один раз?

Добавлено через 1 минуту
То есть IoCreateDevice надо не в DriverEntry вызывать? А где? В своём обработчике CreateDevice?

Добавлено через 1 минуту
У меня просто когда я пытаюсь вызвать функцию CrуateFile у SCM менеджера, возвращается 0xFFFFFFFF, т.е. ошибка.

Добавлено через 3 минуты
Допустим, у меня два LPT порта, есть свой драйвер для LPT. И я их хочу открыть. Я регистрирую свой драйвер extLPT.sys с помощью SCM менеджера. При этом вызывается DriverEntry (вроде так ведь?). Т.е. IoCreateDevice по-хорошему там делать нельзя?

Добавлено через 1 минуту
Затем по полученному хэндлу я должен создать объект устройства (возможно я путаюсь в терминах), т.е. сделать CreateFile(имя)?

Добавлено через 38 секунд
P.S. Наверное всё в кашу смешал... Почитаю дальше Они.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.11.2014, 14:33
Отвечу сегодня вечером, когда время будет.
1
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,037
10.11.2014, 14:34  [ТС]
И опять хочу объект устройства создать. Но второй раз CreateFile по этим имени и хэндлу уже возвращает ошибку. Так ведь?

Добавлено через 33 секунды
Спасибо большое. Наверное мне тоже надо знания систематизировать.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.11.2014, 21:09
Лучший ответ Сообщение было отмечено Khludenkov как решение

Решение

В драйверах мы имеем дело с тремя ключевыми структурами: DRIVER_OBJECT,
DEVICE_OBJECT и IRP.

DRIVER_OBJECT - это объект, связанный с драйвером, он хранит указатели на
функции обработки I/O, функции AddDevice/Unload, на список устройств и т.д.,
то есть, управляет общими для всего драйвера данными. Этот объект всегда
существует в единственном экземпляре.

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

IRP - это пакет ввода-вывода. В системе ввода-вывода это основной
носитель информации. IRP всегда адресован конкретному драйверу и "знает"
целевой DEVICE_OBJECT, который должен заняться его обработкой.

Работает это все примерно следующим образом.

Сначала драйвер создает один или более DEVICE_OBJECT-ов и символьные ссылки
на них, а также регистрирует обработчики ввода-вывода: IRP_MJ_CREATE,
IRP_MJ_WRITE и т.д. Когда приложение вызывает CreateFile, используя
символьную ссылку, в драйвер приходит IRP-пакет с кодом IRP_MJ_CREATE,
причем в запросе передается указатель на соответствующий DEVICE_OBJECT,
которому этот запрос адресован. Если кто-то другой вызовет CreateFile, в
драйвер придет еще один IRP_MJ_CREATE на это же устройство. Если драйвер
успешно завершает запрос, в приложение возвращается HANDLE, через который
можно работать с драйвером такими функциями, как DeviceIoControl, например.

На каждую операцию ReadFile, WriteFile, DeviceIoControl, CloseHandle
будет вызываться соответствующий обработчик драйвера с соответствующим
DEVICE_OBJECT.

Драйвер может различать разных клиентов одного и того же DEVICE_OBJECT,
используя поле FileObject стека IRP (см. IoGetCurrentIrpStackLocation):
каждому клиенту соответствует объект FILE_OBJECT ядра.

Нередко, особенно при написании фильтрующих драйверов, возникает
необходимость иметь два и более DEVICE_OBJECT, обслуживающих разные
по сути устройства: например, одно устройство воткнуто в стек клавиатуры и
перехватывает нажатия клавиш, а второе устройство принимает команды от
управляющего приложения. При этом на фильтрующем устройстве нужно
обрабатывать все IRP-коды, пропуская их вниз, а на устройстве управления
требуется поддержать, к примеру, только read-write-open-close.
Возникает загвоздка: когда приходит IRP, вы не знаете, какому именно
устройству оно адресовано - фильтрующему или управляющему.

Здесь поступают так: в объявлении DEVICE_EXTENSION обоих устройств делается
одно общее поле, например DeviceTag. При создании фильтрующего устройства
туда пишется что-нибудь типа DEVTAG_FILTER, а при создании управляющего -
DEVTAG_CONTROL. Когда приходит IRP-запрос, мы заглядываем в DeviceExtension
устройства и находим там его тип:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
typedef struct _FILTER_DATA
{
    DEVICE_OBJECT     * pLowerDevice;
    IO_REMOVE_LOCK      RemoveLock;
    // ...
} FILTER_DATA, * PFILTER_DATA;
 
typedef struct _CONTROL_DATA
{
    int SomeValue;
} CONTROL_DATA, * PCONTROL_DATA;
 
typedef struct _DEVICE_EXTENSION
{
    ULONG DeviceTag;
    
    union
    {
        FILTER_DATA     Filter;
        CONTROL_DATA    Control;
    } Data;
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;
 
// ...
 
NTSTATUS
DriverEntry(DRIVER_OBJECT * pDriverObj, UNICODE_STRING * pRegPath)
{
    // ...
    
    pFilterDev = CreateFilterDevice(/* ... */);
    pDeviceExt = pFilterDev->DeviceExtension;
    pDeviceExt->DeviceTag = FILTER_DEVICE;
    
    pControlDev = CreateControlDevice(/* ... */);
    pDeviceExt  = pControlDev->DeviceExtension;
    pDeviceExt->DeviceTag = CONTROL_DEVICE;
 
    // ...
    
    return STATUS_SUCCESS;
}
 
// ...
 
NTSTATUS
IrpHandler(DEVICE_OBJECT * pDeviceObj, IRP * pIrp)
{
    DEVICE_EXTENSION * pDeviceExt = pDeviceObj->DeviceExtension;
    
    switch (pDeviceExt->DeviceTag)
    {
        case FILTER_DEVICE:
        {
            // This is a filter device.
        }
        break;
        
        case CONTROL_DEVICE:
        {
            // This is a control device.
        }
        break;
    }
    
    // ...
    
    return STATUS_SUCCESS;
}
Есть и другая вариация этого способа, более эффективная и, на мой взгляд,
более правильная в концептуальном плане: вместо DeviceTag хранить в
DEVICE_EXTENSION указатель на таблицу обработчиков IRP для данного устройства.
Получится, что у каждого устройства будет свой массив MajorFunction.
Код не привожу, так как он элементарен. Ну и как полагается, все это лучше
скрыть за удобными и безопасными обертками, чтобы не "зашумлять" код.
Кстати, в WDF так давно все уже и сделано.

Цитата Сообщение от Khludenkov Посмотреть сообщение
У Они написано, что имена устройств задаются динамически, как-то через расширение устройства вроде.
Имя устройства нужно задавать самому только в том случае, если
это legacy (т.е. не PnP) устройство, которое будет открываться из
режима пользователя или из другого драйвера по символьной ссылке.
Для PnP-устройств другая схема: там имя генерируется автоматически,
вида "Device\00000087", а символьную ссылку создает PnP-менеджер.

Цитата Сообщение от Khludenkov Посмотреть сообщение
в чём отличие создания объекта драйвера (если я правильно сказал) вызовом CreateFile по имени драйвера и по символьной ссылке.
По имени драйвера открыть устройство не получится. В этом и смысл символьных ссылок.

Цитата Сообщение от Khludenkov Посмотреть сообщение
Допустим я хочу создать три объекта драйвера.
Пардон, три объекта устройств, управляемых этим драйвером. Как это сделать?
IoCreateDevice(Secure), IoCreateDevice(Secure), IoCreateDevice(Secure).

Цитата Сообщение от Khludenkov Посмотреть сообщение
DriverEntry же вызывается один раз?
Да.

Цитата Сообщение от Khludenkov Посмотреть сообщение
То есть IoCreateDevice надо не в DriverEntry вызывать? А где? В своём обработчике CreateDevice?
Устройство создается либо в DriverEntry, либо в AddDevice.
В обработчике CreateDevice не получится: ведь устройства еще нет, значит,
символьной ссылки на него тоже нет, а следовательно и имени, которое
пользователь может передать в CreateFile, тоже нет. Нечего открывать.

Цитата Сообщение от Khludenkov Посмотреть сообщение
У меня просто когда я пытаюсь вызвать функцию CrуateFile у SCM менеджера, возвращается 0xFFFFFFFF, т.е. ошибка.
А GetLastError где ?

Цитата Сообщение от Khludenkov Посмотреть сообщение
Допустим, у меня два LPT порта, есть свой драйвер для LPT. И я их хочу открыть. Я регистрирую свой драйвер extLPT.sys с помощью SCM менеджера. При этом вызывается DriverEntry (вроде так ведь?). Т.е. IoCreateDevice по-хорошему там делать нельзя?
IoCreateDevice зовется либо в DriverEntry, либо в AddDevice, в зависимости от
типа драйвера. Можно и там, и там, кстати. По поводу LPT - не знаю, мне этот
стек плохо знаком, даже не в курсе, поддерживается ли модель WDM или нет.

Цитата Сообщение от Khludenkov Посмотреть сообщение
Затем по полученному хэндлу я должен создать объект устройства (возможно я путаюсь в терминах), т.е. сделать CreateFile(имя)?
Нет, не так. CreateFile вызывается с именем символьной ссылки, которую
драйвер где-нибудь в DriverEntry связал с одним из своих устройств.

Цитата Сообщение от Khludenkov Посмотреть сообщение
И опять хочу объект устройства создать. Но второй раз CreateFile по этим имени и хэндлу уже возвращает ошибку. Так ведь?
В IoCreateDevice есть флаг Exclusive. Если его ставить TRUE, устройство сможет
открывать только один клиент.
1
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,037
11.11.2014, 08:18  [ТС]
Спасибо большое десять раз.

Цитата Сообщение от Убежденный Посмотреть сообщение
Сначала драйвер создает один или более DEVICE_OBJECT-ов
Т.е. если это Legacy драйвер, то создаёт в DriverEntry и определённое число раз, затем уже нельзя добавить?

А если это WDM драйвер, то можно в AddDevice. А AddDevice вызывается при каждом подключении (нового) устройства? И для каждого подключенного устройства можно "на лету" создать свой объект устройства?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
11.11.2014, 09:26
Цитата Сообщение от Khludenkov Посмотреть сообщение
если это Legacy драйвер, то создаёт в DriverEntry и определённое число раз, затем уже нельзя добавить?
IoCreateDevice можно звать сколько угодно и где угодно, был бы
только указатель на DRIVER_OBJECT и IRQL ниже DISPATCH_LEVEL.

Цитата Сообщение от Khludenkov Посмотреть сообщение
А AddDevice вызывается при каждом подключении (нового) устройства? И для каждого подключенного устройства можно "на лету" создать свой объект устройства?
Да. И AddDevice - единственное место, где "бесплатно" дается
указатель на Physical Device Object.
1
37 / 31 / 5
Регистрация: 30.04.2014
Сообщений: 1,037
11.11.2014, 10:08  [ТС]
Спасибо. Тему можно считать закрытой.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.11.2014, 10:08
Помогаю со студенческими работами здесь

Обращение к каждому из экземпляров объекта
Здравствуйте! Интересует такой вопрос: Как обратиться к каждому экземпляру, созданному из одного объекта? Например: ... Form1...

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

Запуск нескольких экземпляров IntelliJ IDEA
Здравствуйте! Подскажите пожалуйста как сделать, чтобы запускалось несколько экземпляров IntelliJ IDEA (если допустим надо отдельный...

Открытие нескольких экземпляров одной формы
Необходимо на основании счета-заказа открыть несколько форм наряда одного типа. Возможно ли это в 7-ке?

Установка нескольких экземпляров MSSQL на одном компьютере
Привет ! Есть Windows server 2003 На нем уже есть установленный Microsoft SQL Server 2005 Service Pack 2 Теперь я хочу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru