Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: загрузка драйвера  (Прочитано 15310 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Mayor
Специалист

ru
Offline Offline

« : 23-12-2003 21:25 » 

мне интересно как в nt5 запустить драйвер с коммандной строки
(что-нибудь типа net start ntice)

я пока только сумел скомпилировать готовый драйвер
 и применяя как inf file так и EZDriverInstall от NuMega
добивался лишь того что он запускался еще до перехода в
графический режим где-то после KBDCLASS MOUCLASS
если я начну добавлять в него что-нибудь свое рано или поздно это обвалит систему и мне не хотелось чтобы это произошло на старте

и еще может кто-нибудь даст ссылку где поподробнее написано о загрузке драйверов через Enumерацию -так для общего развития Улыбаюсь
Записан

1n c0de we trust
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #1 : 24-12-2003 06:43 » 

По загрузке- используй ф-ции для установки и запуска сервисов.
Вот пример

Код:
//Ф-ции для динамической загрузки и выгрузки драйверов в WinNT/2k/XP/2003
//(Почти полностью взяты у С. Шрайбера)

typedef SC_HANDLE *PSC_HANDLE;
typedef DWORDLONG QWORD, *PQWORD, **PPQWORD;

SC_HANDLE WINAPI w2kServiceConnect (void)
{
return OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
}

//----------------------------------------------------------

SC_HANDLE WINAPI w2kServiceDisconnect (SC_HANDLE hManager)
{
if (hManager != NULL) CloseServiceHandle (hManager);
return NULL;
}

//----------------------------------------------------------

SC_HANDLE WINAPI w2kServiceManager (SC_HANDLE hManager,
PSC_HANDLE phManager,
BOOL fOpen)
{
SC_HANDLE hManager1 = NULL;

if (phManager != NULL)
{
if (fOpen)
{
if (hManager == NULL)
{
*phManager = w2kServiceConnect ();
}
else
{
*phManager = hManager;
}
}
else
{
if (hManager == NULL)
{
*phManager = w2kServiceDisconnect (*phManager);
}
}
hManager1 = *phManager;
}
return hManager1;
}

//----------------------------------------------------------

SC_HANDLE WINAPI w2kServiceOpen (SC_HANDLE hManager,
PWORD pwName)
{
SC_HANDLE hManager1;
SC_HANDLE hService = NULL;

w2kServiceManager (hManager, &hManager1, TRUE);

if ((hManager1 != NULL) && (pwName != NULL))
{
hService = OpenService (hManager1, pwName,
SERVICE_ALL_ACCESS);
}
w2kServiceManager (hManager, &hManager1, FALSE);
return hService;
}

//----------------------------------------------------------

BOOL WINAPI w2kServiceClose (SC_HANDLE hService)
{
return (hService != NULL) && CloseServiceHandle (hService);
}

//----------------------------------------------------------

BOOL WINAPI w2kServiceAdd (SC_HANDLE hManager,
PWORD pwName,
PWORD pwInfo,
PWORD pwPath)
{
SC_HANDLE hManager1, hService;
PWORD pwFile;
WORD awPath [MAX_PATH];
DWORD n;
BOOL fOk = FALSE;

w2kServiceManager (hManager, &hManager1, TRUE);

if ((hManager1 != NULL) && (pwName != NULL) &&
(pwInfo != NULL)&&(pwPath != NULL) &&
(n = GetFullPathName (pwPath, MAX_PATH, awPath, &pwFile)) &&
(n < MAX_PATH))
{
if ((hService = CreateService (hManager1, pwName, pwInfo,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
awPath, NULL, NULL,
NULL, NULL, NULL))
!= NULL)
{
w2kServiceClose (hService);
fOk = TRUE;
}
else
{
fOk = (GetLastError () ==
ERROR_SERVICE_EXISTS);
}
}
w2kServiceManager (hManager, &hManager1, FALSE);
return fOk;
}

//----------------------------------------------------------

BOOL WINAPI w2kServiceRemove (SC_HANDLE hManager,
PWORD pwName)
{
SC_HANDLE hService;
BOOL fOk = FALSE;

if ((hService = w2kServiceOpen (hManager, pwName)) != NULL)
{
if (DeleteService (hService))
{
fOk = TRUE;
}
else
{
fOk = (GetLastError () ==
ERROR_SERVICE_MARKED_FOR_DELETE);
}
w2kServiceClose (hService);
}
return fOk;
}

//----------------------------------------------------------

BOOL WINAPI w2kServiceStart (SC_HANDLE hManager,
PWORD pwName)
{
SC_HANDLE hService;
BOOL fOk = FALSE;

if ((hService = w2kServiceOpen (hManager, pwName)) != NULL)
{
if (StartService (hService, 1, (LPCTSTR*)&pwName))
{
fOk = TRUE;
}
else
{
fOk = (GetLastError () ==
ERROR_SERVICE_ALREADY_RUNNING);
}
w2kServiceClose (hService);
}
return fOk;
}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceControl (SC_HANDLE hManager,
PWORD pwName,
DWORD dControl)
{
SC_HANDLE hService;
SERVICE_STATUS ServiceStatus;
BOOL fOk = FALSE;

if ((hService = w2kServiceOpen (hManager, pwName)) != NULL)
{
if (QueryServiceStatus (hService, &ServiceStatus))
{
switch (ServiceStatus.dwCurrentState)
{
case SERVICE_STOP_PENDING:
case SERVICE_STOPPED:
{
fOk = (dControl == SERVICE_CONTROL_STOP);
break;
}
case SERVICE_PAUSE_PENDING:
case SERVICE_PAUSED:
{
fOk = (dControl == SERVICE_CONTROL_PAUSE);
break;
}
case SERVICE_START_PENDING:
case SERVICE_CONTINUE_PENDING:
case SERVICE_RUNNING:
{
fOk = (dControl == SERVICE_CONTROL_CONTINUE);
break;
}
}
}
fOk = fOk ||
ControlService (hService, dControl, &ServiceStatus);

w2kServiceClose (hService);
}
return fOk;
}
// -----------------------------------------------------------------

BOOL WINAPI w2kServiceStop (SC_HANDLE hManager,
PWORD pwName)
{
return w2kServiceControl (hManager, pwName,
SERVICE_CONTROL_STOP);
}

// -----------------------------------------------------------------

BOOL WINAPI w2kServicePause (SC_HANDLE hManager,
PWORD pwName)
{
return w2kServiceControl (hManager, pwName,
SERVICE_CONTROL_PAUSE);
}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceContinue (SC_HANDLE hManager,
PWORD pwName)
{
return w2kServiceControl (hManager, pwName,
SERVICE_CONTROL_CONTINUE);
}

// -----------------------------------------------------------------

SC_HANDLE WINAPI w2kServiceLoad (PWORD pwName,
PWORD pwInfo,
PWORD pwPath,
BOOL fStart)
{
BOOL fOk;
SC_HANDLE hManager = NULL;

if ((hManager = w2kServiceConnect ()) != NULL)
{
fOk = w2kServiceAdd (hManager, pwName, pwInfo, pwPath);

if (fOk && fStart)
{
if (!(fOk = w2kServiceStart (hManager, pwName)))
{
w2kServiceRemove (hManager, pwName);
}
}
if (!fOk)
{
hManager = w2kServiceDisconnect (hManager);
}
}
return hManager;
}

// -----------------------------------------------------------------

BOOL WINAPI w2kServiceUnload (PWORD pwName)
{
SC_HANDLE hManager1 = NULL;
BOOL fOk = FALSE;

if (pwName != NULL)
{
hManager1 = w2kServiceConnect ();

if (hManager1 != NULL)
{
w2kServiceStop (hManager1, pwName);
fOk = w2kServiceRemove (hManager1, pwName);
}
}
w2kServiceDisconnect (hManager1);
return fOk;
}


Вот пример загрузки драйвера с помощью этих ф-ций
bResult = LoadUnloadDeviceDriver(L"XXX_Driver",L"MyXXX_Driver",L"C:\\work\\Drivers\\XXX_Driver.sys", TRUE);
if(!bResult)
Error(L"Error in load driver\n");

Вот пример выгрузки:
hDev = OpenDeviceDriver(L"NotifyDriver");
CloseDeviceDriver(L"NotifyDriver",&hDev );


Цитата
и еще может кто-нибудь даст ссылку где поподробнее написано о загрузке драйверов через Enumерацию -так для общего развития

В DDK. Раздел Kernel Mode Driver Architecture/Design Guide/Plug and Play/Adding a PnP Device to a Runing System.

А это я уже тут писал(два раза):
Последовательность загрузки всех драйверов(начиная с Win2k) такая:
1) Загружают драйвер системной шины. Например PCI.
2) Вызывают DriverEntry а затем AddDevice для драйвера системной шины. В AddDevice создается FDO для драйвера системной шины. Потом посылают IRP_MN_START_DEVICE на созданный FDO.
3) Драйвер шины нумерует устройства на шине. Создает для них PDO.
4) Драйверу системной шины посылают IRP_MN_QUERY_DEVICE_RELATIONS, в ответ на который он возвращает массив созданных им PDO для устройств на шине.
5) На эти PDO посылают запрос IRP_MN_QUERY_ID, в ответ на которые драйвер системной шины сообщает ID этих устройств.
6) Получив эти ID система пытается найти и загрузить драйвера устройств.
7) Найдя драйвер для устройства, система отображает его в память вызывает его DriverEntry, потом AddDevice, в этом AddDevice создается FDO для устройства. Если устройств управляемых этим драйвером несколько то AddDevice будет вызвана для каждого устройства. Также смотрят реестр на предмет наличия фильтров для девайса. Device Manager посылает на FDO запрос IRP_MN_START_DEVICE.
8 ) Потом посылают на FDO запрос IRP_MN_QUERY_DEVICE_RELATIONS. Если устройство само является шиной или держит на себе другие устройства, которыми само не управляет, то для устройств на нем повторяется вся последовательность действий, начиная с пункта 5.
« Последнее редактирование: 23-11-2007 16:22 от Алексей1153++ » Записан
maaaaaad
Гость
« Ответ #2 : 24-12-2003 10:41 » 

Стоит заметить что вышеприведенный код не работает с драйверами от NuMega.
Все стопорится на запуске StartService, который не желает запускать драйвера с ненулевым AddDevice.
А запуск драйвера можно сделать net start (StartService). Но только если в ини - сделать его MANUAL_START.
Хех. Признаюсь честно - так не делал =))
Записан
maaaaaad
Гость
« Ответ #3 : 24-12-2003 10:58 » 

Я думаю что net_start просто прогонит через драйвер IRP_MJ_PNP IRP_MN_START_DEVICE. У девайса все равно будет вызван AddDevice. Вероятно это используется для экономии памяти. Девайс изначально будет находится с состоянии "NEVER_STATED" (STOPPED) и не будет содержать инициализованных очередей, дма, прерываний....в надежде что устройство и не будет забущено вообще
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #4 : 24-12-2003 11:00 » 

Цитата

Стоит заметить что вышеприведенный код не работает с драйверами от NuMega.
Все стопорится на запуске StartService, который не желает запускать драйвера с ненулевым AddDevice.


На NuMega мне параллельно. Скорее всего это следствие того что там собирается WDM драйвер- "$(DRIVERTYPE)" == "WDM", что отражается в заголовке собранного PE файла, а WDM без AddDevice не бывает.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #5 : 24-12-2003 11:03 » 

Цитата

Я думаю что net_start просто прогонит через драйвер IRP_MJ_PNP IRP_MN_START_DEVICE. У девайса все равно будет вызван AddDevice.


Внимательно читай то что я написал про последовательность загрузки драйверов. AddDevice вызывается на созданный PDO, если его нет, то незачем и вызывать. А вот как создать этот PDO? Кто им управлять будет. Так что поосторожней с IRP_MJ_PNP+ IRP_MN_START_DEVICE.
Записан
maaaaaad
Гость
« Ответ #6 : 24-12-2003 11:57 » 

Slaval: Вы не знаете Питрек еще жив? =)))

SubSustem NAVIVE & SubSustemVersion 1.1 для всех драйверов одинакова.
Скажем так. =)
Записан
maaaaaad
Гость
« Ответ #7 : 24-12-2003 12:16 » 

Цитата

Так что поосторожней с IRP_MJ_PNP+ IRP_MN_START_DEVICE.


Я имею ввиду что при установке драйвера с MANUAL_START AddDevice вызывается при загрузке нижнего драйвера, если наш драйвер - фильтр, или после загрузки шинного и перечисления всех устройств на нем. А irp IRP_MJ_PNP c IRP_MN_START_DEVICE посылается когда это потребуется.

Хотя это мое личное скромное мнение =)


А относительно написанного вами выше...есть претензия....
В PnP я много раз видел когда пересылается irp c IRP_MN_START_DEVICE шинному драйверу для запуска шинного драйвера. А вы говорите что моменту прихода START_DEVICE шинный драйвер уже должен быть запущен....
Не параноики стадающие синдромом "остановом шинного драйвера" (syndromeius dormant bus driver)  о писали же.
Я бы сказал что это немного упрощенная модель....
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #8 : 24-12-2003 12:35 » 

Цитата

Slaval: Вы не знаете Питрек еще жив? =)))


Жив вроде, он еще молодой, если только на своем кроссовом мотоцикле не разбился, но я такого не слышал. Питрек сейчас занимается .NET и он не занимался отладчиком ядра и драйверами, он делал только для User Mode отладчики. Во всяком случае так он сам говорил (может это отмазка, чтоб не били).

Цитата

В PnP я много раз видел когда пересылается irp c IRP_MN_START_DEVICE шинному драйверу для запуска шинного драйвера. А вы говорите что моменту прихода START_DEVICE шинный драйвер уже должен быть запущен....
Не параноики стадающие синдромом "остановом шинного драйвера" (syndromeius dormant bus driver) о писали же.
Я бы сказал что это немного упрощенная модель....


Согласен. Я без понятия когда менеджер решит стартануть шину. Тока ткните пальчиком в моем рассказе где сказано, что к моменту старта девайсов на шине шина уже обработала IRP_MN_START_DEVICE или ей послан IRP_MN_START_DEVICE? Там сказано "Потом посылают IRP_MN_START_DEVICE на созданный FDO". Шине ничто не мешает запендить запрос, а менеджеру вобще его не посылать- я этого не отрицаю.
Я сам НЕ уверен когда стартует шина, они же разные бывают, вполне воможна сначала инициализация устройств на шине, потом уже запуск шины.

Только маленькое дополнение- я говорю, что запрос посылают не драйверу а DEVICE_OBJECT, так как стартуют его, обрабатывает запрос конечно драйвер, но с учетом конкретного DEVICE_OBJECT.

Цитата

Я бы сказал что это немного упрощенная модель....


Модель упрощена на столько, чтобы дать понять как все работает не вдаваясь в мелочи- там еще 10 IRP_MN.. запросов придет, менеджер инфу об устройстве в реестр скинет, я их не описываю- важно чтобы поняли как строятся стеки драйверов. А за подробностями- смотрите исходники и DDK , я даже написал название одной страницы- там уже в несколько раз больше чем у меня написано.
Записан
maaaaaad
Гость
« Ответ #9 : 24-12-2003 13:16 » 

Цитата

запендить запрос


В принципе да. Или закомплить =) Мне терминология понравилась.

Выкрутились =)
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #10 : 24-12-2003 13:27 » 

Цитата

SubSustem NAVIVE & SubSustemVersion 1.1 для всех драйверов одинакова.


В заголовке еще есть SubSystem Version. Так если компилить wdm(DRIVERTYPE=WDM) там вылазит номер 5. А вобще я себя этим не напрягал, если NT драйвер- компилю без WDM c /version:4.0 /osversion:4.00  для линкера.
 Вот выясни как отличаются PE заголовки для WDM и не WDM драйверов.
Записан
Mayor
Специалист

ru
Offline Offline

« Ответ #11 : 25-12-2003 21:49 » 

прошу прощения за возможные неточности...


SlavaI: где в электронном виде есть Шрайдер???
из исходника мало понял но по SC_HANDLE вышел на описание SCM
3 строк кода хватило на создание сервиса и это очень помогло

CrashMaker: по поводу загрузки драйвера шины::
   все запросы I/O в тч и IRP_MJ_PnP/StartDevice отправляются через готовый DevObj иначе их некуда посылать
   
тк шина не может физически уведомить о своем присутствии
большинство драйверов шин грузится загрузчиком вместе с диспетчерами I/O PnP и др +
hal ntoskrnl еще до загрузки ntice и других мониторов
так что возможно ты этого и не видел

далее диспетчер PnP с их помощью создает дерево устройств и запускает соответствующие драйверы из
сервисов (даже если там указан Старт по требованию; -
можешь считать что обнаружение устройства и является требованием)  и это уже видно ntice ;
единственное что это остановит - это параметр Старт disable но нет смысла писать отключенный wdm драйвер

таким образом если отключить "устройсво" то не сработает net start или вышеприведенный исходник
а если устройство присутствует то драйвер запустится при следующей перезагрузке через перечисление

так что похоже мне придется вместо DriverWork разбираться с утилитами DDK и отказаться от WDM драйвера в пользу унаследованого драйвера

Но в любом случае благодаря вам я на практике убедился
в возможности запуска кода режима ядра через net start
без последующей загрузки драйвера после reboot
Записан

1n c0de we trust
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #12 : 26-12-2003 06:24 » 

Цитата

 где в электронном виде есть Шрайдер???


По-моему нигде. Он еще продается в бумажном виде C. Шрайбер "Недокументированные возможности Windows 2000", стоит 220 рублей.
Записан
maaaaaad
Гость
« Ответ #13 : 26-12-2003 16:22 » 

SubSystem - Идентификатор подсистемы под которую пашет даный имадж а версия - требуемая версия подсистемы (а не вдм или еще чего-то) в драйверах я лично не исправляю версию подсистемы (по умолчанию ставится 1.0) для приложений выставлю 5.0 - кода генирится меньше - 98 все равно не пользуюсь.
PE драйверов и приложений кроме сабсустемом ничем не отличается, и то это ма мой взгляд сделанно для идентификации.
"Приложение нельзя запустить под Win32"
"Присоединенное к системе усройство не работает"
...
Что бы не ловить эксепшенны от кода запущенного не в той подсистеме.

Цитата

wdm(DRIVERTYPE=WDM) там вылазит номер 5

Наверно компьваренские вдм драйвера делались только в расчете на => 2000
Впрочем и не удивительно. Кто же тогда стал покупать лайбы VxdTools (или как их там) которые пашут только под девяностыми.



Какой Щрайдер? Который из черепашек-ниндзя?
Записан
maaaaaad
Гость
« Ответ #14 : 26-12-2003 16:27 » 

Цитата

Вот выясни как отличаются PE заголовки для WDM и не WDM драйверов


Они могут и не отличаться.
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #15 : 29-12-2003 07:37 » 

Цитата

Какой Щрайдер? Который из черепашек-ниндзя?


Словарик Шрайберов-

Шрайдер- Из черепашек.
Шрайбер - Свен, программист из швейцарии. Автор книги "Undocumented Windows 2000"
Шнайер- Брюс, криптограф из США. Автор книги "Прикладная криптография".
Шнайдер- Рони, актриса, Франция.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines