Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.06.2012, 14:46   #1
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию BSOD при IOCTL запросе

Доброго времени суток. Имеется драйвер, при выполнении ioctl запроса он должен вернуть пользовательскому приложению данные. Объявление ioctl
Код:
#define IOCTL_PROCGUARD_GET_START_PROTECT_LIST		CTL_CODE(PG_DEVICE_TYPE, \
PG_GET_START_PROTECT_LIST, METHOD_OUT_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA)
Обработчик:
Код:
NTSTATUS DriverIoCtl(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
	PIO_STACK_LOCATION pIOStack;
	BOOLEAN Err;

	DBGMSG("DriverIoCtl called");

	pIOStack =  IoGetCurrentIrpStackLocation(pIrp);

	switch (pIOStack->Parameters.DeviceIoControl.IoControlCode)
	{
case IOCTL_PROCGUARD_GET_START_PROTECT_LIST:
	{
	
		PTO_USER_DATA Data = pIrp->AssociatedIrp.SystemBuffer;
		if(Data != NULL)
                {
			DBGMSG("Buffer ok");


		RtlCopyBytes(&(Data->Process), &OpenProtectList[0], MAX_PROCESS_IN_LIST*sizeof(PROCESS));
		RtlCopyBytes(&(Data->IsUsed), &OpenMass[0], MAX_PROCESS_IN_LIST*sizeof(BOOLEAN));

		pIrp->IoStatus.Status = STATUS_SUCCESS;
		pIrp->IoStatus.Information = sizeof(TO_USER_DATA);
		
		DBGMSG("Start process buffer copied to user");
	}
   }
break;
}//switch
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
В приложении:
Код:
TO_USER_DATA Data;
DWORD dwRet;
DeviceIoControl(hDriver, IOCTL_PROCGUARD_GET_START_PROTECT_LIST, NULL, 0, &Data, sizeof(TO_USER_DATA), &dwRet, NULL)
После этого вылетает BSOD с ошибкой SYSTEM_SERVICE_EXCEPTION.
Any ideas?
Единственный способ стать умнее - играть с более умным противником.

Последний раз редактировалось rpy3uH; 18.06.2012 в 10:22. Причина: Опечатка
Sam Gold вне форума Ответить с цитированием
Старый 17.06.2012, 18:31   #2
raxp
Старожил
 
Регистрация: 29.09.2009
Сообщений: 9,742
По умолчанию

...это все или код ошибки тоже имеется? Драйвер зарегистрирован в системе? Ось семерка?
Разработки и научно-технические публикации :: Видеоблог :: Твиттер
Radar systems engineer & Software developer of industrial automation
raxp вне форума Ответить с цитированием
Старый 17.06.2012, 20:21   #3
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

в курсе, что если в стеке драйвера имеется драйвер, который не дружит с METHOD_OUT_DIRECT, bug check гарантирован?
f.hump вне форума Ответить с цитированием
Старый 18.06.2012, 20:40   #4
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Цитата:
Сообщение от raxp Посмотреть сообщение
...это все или код ошибки тоже имеется?
Так а я что привел? SYSTEM_SERVICE_EXCEPTION это 0x3B. Или какой код имеется ввиду?
Цитата:
Сообщение от raxp Посмотреть сообщение
Драйвер зарегистрирован в системе? Ось семерка?
Да, зарегистрирован, подписан с помощью тестового сертификата. ОСь Win7 x64 Ultimate.
Цитата:
в курсе, что если в стеке драйвера имеется драйвер, который не дружит с METHOD_OUT_DIRECT, bug check гарантирован?
Теперь в курсе Пробовал другие методы - та же история.
Взял, как в примере из WDK
Код:
case IOCTL_PROCGUARD_GET_START_PROTECT_LIST:
	{
TO_USER_DATA Buff;
		Data = MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority);

        if (!Data) {
            pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

                RtlCopyBytes(&(Buff), &OpenProtectList[0], MAX_PROCESS_IN_LIST*sizeof(PROCESS));
		RtlCopyBytes(&(Buff) + MAX_PROCESS_IN_LIST*sizeof(PROCESS), &OpenMass[0], MAX_PROCESS_IN_LIST*sizeof(BOOLEAN));

		RtlCopyBytes(Data, &Buff, sizeof(TO_USER_DATA));

		pIrp->IoStatus.Status = STATUS_SUCCESS;
		pIrp->IoStatus.Information = sizeof(TO_USER_DATA);
		
		DBGMSG("Start process buffer copied to user");
	}
   }
break;
}//switch
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
Однако буффер в приложение приходит пустой. А при выгрузке драйвера происходит BSOD с ошибкой DRIVER_UNLOADED_WITHOUT_CANCELLING_ PENDING_OPERATIONS (0xCE), непонятно почему. Подскажите, в чем проблема?
Единственный способ стать умнее - играть с более умным противником.

Последний раз редактировалось Sam Gold; 18.06.2012 в 20:49.
Sam Gold вне форума Ответить с цитированием
Старый 18.06.2012, 22:29   #5
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Цитата:
че это такое?
Ой, пардон, забыл исправить, там
Код:
RtlCopyBytes(&(Buff.IsUsed), &OpenMass[0], MAX_PROCESS_IN_LIST*sizeof(BOOLEAN));
должно быть, иначе PAGE_FAULT_IN_NONPAGED_AREA.
Копирование в поле структуры TO_USER_DATA.
Единственный способ стать умнее - играть с более умным противником.
Sam Gold вне форума Ответить с цитированием
Старый 18.06.2012, 23:06   #6
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

всегда полезно в switch иметь дефолт, который будет ставить неподдерживаемому запросу STATUS_UNSUCCESSFUL

да, че-то сразу не увидел, драйверы должны использовать RtlCopyMemory, а не RtlCopyBytes

Последний раз редактировалось f.hump; 18.06.2012 в 23:22.
f.hump вне форума Ответить с цитированием
Старый 18.06.2012, 23:58   #7
Sam Gold
Форумчанин
 
Аватар для Sam Gold
 
Регистрация: 26.03.2010
Сообщений: 538
По умолчанию

Цитата:
драйверы должны использовать RtlCopyMemory, а не RtlCopyBytes
Да, спасибо.Заменил на RtlCopyMemory, но пользовательскому приложению все равно ничего не приходит.
Цитата:
всегда полезно в switch иметь дефолт, который будет ставить неподдерживаемому запросу STATUS_UNSUCCESSFUL
К сожалению, при этом BSOD с DRIVER_UNLOADED_WITHOUT_CANCELLING_ PENDING_OPERATIONS остается.

P.S. Интересно, а почему в примере драйвера ioctl в WDK RtlCopyBytes используется?
Единственный способ стать умнее - играть с более умным противником.

Последний раз редактировалось Sam Gold; 19.06.2012 в 00:37.
Sam Gold вне форума Ответить с цитированием
Старый 19.06.2012, 01:52   #8
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

Код:
RtlCopyBytes(&(Buff) + MAX_PROCESS_IN_LIST*sizeof(PROCESS), &OpenMass[0], MAX_PROCESS_IN_LIST*sizeof(BOOLEAN));
че это такое?
куда копирование происходит?
f.hump вне форума Ответить с цитированием
Старый 19.06.2012, 23:43   #9
f.hump
C/C++, Asm
Участник клуба
 
Аватар для f.hump
 
Регистрация: 02.03.2010
Сообщений: 1,323
По умолчанию

ну тогда WinDbg в помощь. во первых можно попробовать вытащить че-то полезное из мини-дампов. а во вторых если драйвер пишется на одной машине и тестируется на другой, то можно трейсить до креша.
f.hump вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
IOCTL roman1991 Общие вопросы C/C++ 1 10.08.2011 14:31
Откуда дубли при запросе? hronos1975 Microsoft Office Access 7 11.02.2011 19:14
Можно ли при пост-запросе InDy получить только куки (при логине на сайт например)? TwiX Работа с сетью в Delphi 2 07.02.2010 08:21
Ошибка при запросе SQL в IB Алекс1 БД в Delphi 2 24.06.2007 22:37