Всем привет.
Сразу оговорюсь — в области драйверов я новичок

Пишу верхний фильтр (WDM) для устройства с использованием DriverWorks3.1.
Первым делом решил попробовать поуправлять внутренними переменными класса-устройства
RWHookDevice : public KWdmFilterDevice{... private: DWORD m_dwTest; ...};
через DeviceIoControl(...). Определил два кода — один для записи этой переменной, другой для чтения:
#define RWHOOKDRIVER_IOCTL_801 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define RWHOOKDRIVER_IOCTL_802 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
Хэндлер для DeviceControl(KIrp I) выглядит так:
#define RWHOOKDRIVER_IOCTL_801 0x801
#define RWHOOKDRIVER_IOCTL_802 0x802
NTSTATUS RWHookDevice::DeviceControl(KIrp I)
{
NTSTATUS status;
char bPassToLowerDev = 0;
t <<"Entering RWHookDevice::DeviceControl\n";
switch (I.IoctlCode())
{
// Свои управляющие коды обслуживаем на месте и сразу завершаем IRP
case RWHOOKDRIVER_IOCTL_801:
status = RWHOOKDRIVER_IOCTL_801_Handler(I);
break;
case RWHOOKDRIVER_IOCTL_802:
status = RWHOOKDRIVER_IOCTL_802_Handler(I);
break;
// Остальные упр.коды отправляем ниже
default:
bNotPassToLowerDev = 1;
status = PassThrough(I);
break;
}
if( !bPassToLowerDev )
return I.PnpComplete(status);
else
return status;
}
Хэндлеры для кодов RWHOOKDRIVER_IOCTL_801,RWHOOKDRIVER_IOCTL_802:
///////////////////////////////////////////////////////////////////////
// Чтение m_dwTest
///////////////////////////////////////////////////////////////////////
NTSTATUS RWHookDevice::RWHOOKDRIVER_IOCTL_801_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;
t << "Entering TestDriverDevice::RWHOOKDRIVER_IOCTL_801_Handler, " << I << "\n";
if( I.IoctlOutputBufferSize() < sizeof(DWORD) )
return STATUS_INVALID_PARAMETER;
DWORD* pOutBuf = (DWORD*)I.IoctlBuffer();
if( pOutBuf != NULL )
{
*pOutBuf = m_dwTest;
I.Information() = sizeof(DWORD);
}
else
{
t << "NULL out buffer pointer!!!\n";
I.Information() = 0;
status = STATUS_INVALID_PARAMETER;
}
return status;
}
///////////////////////////////////////////////////////////////////////
// Запись m_dwTest
///////////////////////////////////////////////////////////////////////
NTSTATUS RWHookDevice::RWHOOKDRIVER_IOCTL_802_Handler(KIrp I)
{
t << "Entering TestDriverDevice::RWHOOKDRIVER_IOCTL_802_Handler, " << I << "\n";
if( I.IoctlInputBufferSize() < sizeof(DWORD) )
return STATUS_INVALID_PARAMETER;
DWORD* pOutBuf = (DWORD*)I.IoctlBuffer();
if( pOutBuf == NULL )
{
t << "NULL in buffer pointer!!!\n";
I.Information() = 0;
return STATUS_INVALID_PARAMETER;
}
m_dwTest = *pOutBuf;
I.Information() = 0;
return STATUS_SUCCESS;
}
Для user-mode приложения определил пару функций:
FILTERDLL_API BOOL RwhWriteTestValue(HANDLE hDevice,DWORD dwValue)
{
if( hDevice == INVALID_HANDLE_VALUE )
return FALSE;
OVERLAPPED ovl = {0};
BOOL bRes = FALSE;
DWORD dwBytesReturned;
__try
{
ovl.hEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL);
bRes = ::DeviceIoControl(
hDevice,
RWHOOKDRIVER_IOCTL_802,
&dwValue,
sizeof(DWORD),
NULL,
0,
&dwBytesReturned,&ovl);
}
__finally
{
::CloseHandle(ovl.hEvent);
}
return bRes;
}
FILTERDLL_API BOOL RwhReadTestValue(HANDLE hDevice,LPDWORD pdwValue)
{
if( hDevice == INVALID_HANDLE_VALUE )
return FALSE;
OVERLAPPED ovl = {0};
BOOL bRes = FALSE;
DWORD dwValue,dwBytesReturned;
__try
{
ovl.hEvent = ::CreateEvent(NULL,TRUE,FALSE,NULL);
bRes = ::DeviceIoControl(
hDevice,
RWHOOKDRIVER_IOCTL_801,
NULL,
0,
&dwValue,
sizeof(DWORD),
&dwBytesReturned,
&ovl);
if( bRes )
*pdwValue = dwValue;
}
__finally
{
::CloseHandle(ovl.hEvent);
}
return bRes;
}
А проблема собстно в том, что запись проходит успешно, а при чтении выводится отладочное сообщение из драйвера
"NULL out buffer pointer!!!\n" ..., то бишь почему-то в драйвер не передаётся адрес выходного буфера, куда нужно вернуть значение
m_dwTest.
Работаю под WinXP SP2. Пробовал компилить под DDK_2K и DDK_XP с одинаковым результатом. С установкой и удалением фильтра проблем нет.
Ставлю на communications Port (COM-порты).
Где ж тут собака закопана?
С уважением, Роман.
Вопрос снимается

В DeviceControl передавал неправильные значения управляющих кодов.
Здравствуйте, PR0m, Вы писали:
PR>Сразу оговорюсь — в области драйверов я новичок
PR>Пишу верхний фильтр (WDM) для устройства с использованием DriverWorks3.1.
PR>Первым делом решил попробовать поуправлять внутренними переменными класса-устройства
PR>RWHookDevice : public KWdmFilterDevice{... private: DWORD m_dwTest; ...};
PR>через DeviceIoControl(...). Определил два кода — один для записи этой переменной, другой для чтения:
PR>PR>#define RWHOOKDRIVER_IOCTL_801 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
PR>#define RWHOOKDRIVER_IOCTL_802 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
PR>
PR>Хэндлер для DeviceControl(KIrp I) выглядит так:
PR>PR>#define RWHOOKDRIVER_IOCTL_801 0x801
PR>#define RWHOOKDRIVER_IOCTL_802 0x802
PR>NTSTATUS RWHookDevice::DeviceControl(KIrp I)
PR>{
PR> NTSTATUS status;
PR> char bPassToLowerDev = 0;
PR> t <<"Entering RWHookDevice::DeviceControl\n";
PR> switch (I.IoctlCode())
PR> {
PR> // Свои управляющие коды обслуживаем на месте и сразу завершаем IRP
PR> case RWHOOKDRIVER_IOCTL_801:
PR> status = RWHOOKDRIVER_IOCTL_801_Handler(I);
PR> break;
PR> case RWHOOKDRIVER_IOCTL_802:
PR> status = RWHOOKDRIVER_IOCTL_802_Handler(I);
PR> break;
PR> // Остальные упр.коды отправляем ниже
PR> default:
PR> bNotPassToLowerDev = 1;
PR> status = PassThrough(I);
PR> break;
PR> }
PR> if( !bPassToLowerDev )
PR> return I.PnpComplete(status);
PR> else
PR> return status;
PR>}
PR>
--
Здесь немного странно. Метод Kirp.IoctlCode(), судя по исходному коду, должен вернуть "полные" IOCTL коды (как в define'e в первом примере кода) и они никак не дожны быть равны тем определениям, которые используются в функции DeviceControl (второй пример кода).
Если используются вторые (что очень вероятно, судя по сообщениям отладчика), то 2 младших бита будут интерпретироваться системой как METHOD_IN_DIRECT (для 0x801) и как METHOD_OUT_DIRECT (для 0x802), а не как METHOD_BUFFERED (как в первом define).
Так какие IOCTL коды таки используются у Вас?
С уважением,
Геннадий Майко.