Здравствуйте! Возникла "маленькая проблема", которую я сам не в состоянии решить. Помогите, пожалуйста. При попытке доступа к элементу структуры - BSoD. Структура такая: Код (Text): #define MAX_KEYS 64 #define MAX_KEYHASH 32 ... typedef struct _OPEN_FILE_INFORMATION { USHORT KeyType; //0 None 1 2Fish 2 AES256 USHORT KeyNum; USHORT KeyLength; UCHAR Key[MAX_KEYS][MAX_KEYHASH]; } OPEN_FILE_INFORMATION, *POPEN_FILE_INFORMATION; Из приложения отправляю так: Код (Text): POPEN_FILE_INFORMATION OpenFileInformation; ... DeviceIoControl( hDevice, IO_DO_ACTION, OpenFileInformation, sizeof(OPEN_FILE_INFORMATION), OpenFileInformation, sizeof(OPEN_FILE_INFORMATION), &BytesReturned, NULL ) Выходные буферы не заполняются, но если их не указывать в программе, результат не отличается.Затем, в драйвере, выполняю следующее: Код (Text): if (irpStack->Parameters.DeviceIoControl.InputBufferLength <sizeof(OPEN_FILE_INFORMATION)) { DbgPrint("Invalid parameter 1!\n"); status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(OPEN_FILE_INFORMATION)) { DbgPrint("Invalid parameter 2!\n"); status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } open_file_information = (POPEN_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer; DbgPrint("Do Action successfully!\n"); device_extension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; DbgPrint("Do Action successfully again!\n");//WinDbg указывает на эту строку DbgPrint("Key Type %i\n",open_file_information->KeyType);//но на самом деле, если убрать эту строку, то ошибки нет При попытке выполнения этого кода - BSoD. Анализ дампа - в аттаче. Если кому-нибудь интересно и Вы желаете подробнее изучить проблему и помочь мне найти решение, - пишите, могу выслать полный код. Сюда не выкладываю, чтобы не обременять своими проблемами людей, у которых немного свободного времени. _778038817__dump.txt
Скорее всего у тебя проблема в методе обмена данными между user и kernel. Если используешь функции read write, тогда явно укажи в DEVICE_OBJECT->Flags метод обмена. Если используешь DeviceIoControl, тогда правильно задай ControlCode. (есть макрос CTL_CODE) Подробности в книге Солдатова или Art Baker и Jerry Lozano. Вот отрывок из Солдатова: "При методе METHOD_BUFFERED Диспетчер ввода/вывода выделяет единственный буфер в нестраничной памяти, достаточно большой, чтобы вместить входной или выходной буфер инициатора вызова. Адрес этой области размещается в пакете IRP в поле AssociatedIrp.SystemBuffer. Затем производится копирование входного (input) буфера с данными инициатора запроса в эту область. В поле UserBuffer пакета IRP заносится оригинальный адрес буфера для получения данных инициатора запроса. По завершении обработки IOCTL запроса, Диспетчер ввода/вывода копирует содержимое системного буфера, размещенного в нестраничной памяти, в собственно буфер инициатора. Следует обратить внимание, что только один внутренний буфер предоставляется драйверу, даже если пользователь указал два независимых буфера в качестве входного и выходного. При методе METHOD_IN_DIRECT и METHOD_OUT_DIRECT Диспетчер ввода/вывода проверяет приемлемость выходного (output) буфера инициатора вызова и производит его фиксацию (lock) в физической памяти. Затем производит построение списка MDL (Memory Descriptor List) для выходного буфера и сохраняет указатель на MDL в поле MdlAddress пакета IRP. Кроме того, Диспетчер ввода/вывода выделяет временную область в нестраничном пуле и сохраняет этот адрес в поле AssociatedIrp.SystemBuffer пакета IRP. Производится копирование содержимого входного (input) буфера инициатора вызова в выделенный системный буфер, а в поле UserBuffer производится запись значения NULL. После этого IRP пакет поступает в вызываемую рабочую процедуру драйвера. При методе METHOD_NEITHER Диспетчер ввода/вывода помещает адрес входного (input) буфера инициатора вызова в поле Parameters.DeviceIoControl.Type3InputBuffer в текущей ячейке стека пакета IRP текущей операции ввода/вывода. В поле UserBuffer производится запись адреса выходного (output) буфера инициатора вызова, где инициатор вызова ожидает получить результаты выполнения операции. Оба этих адреса указывают в область памяти инициатора вызова."
Спасибо, попробую. Но, дело в том, что я копировал код, отвечающий за обмен данными из работающего приложения (как моего, так и из чужих исходников) - результат одинаков. Но явно метод ВВ не указывал. Если у кого есть еще мысли - буду рад помощи.
Да, есть такие "грабли" Если не указать метод в/в то будет "каша". Это в DriverEntry Код (Text): mov eax, device_object or (DEVICE_OBJECT PTR [eax]).Flags, DO_DIRECT_IO mov edi, (DEVICE_OBJECT PTR [eax]).DeviceExtension Это управляющий код Код (Text): IOCTL_GET_ADDRESS equ CTL_CODE(FILE_DEVICE_UNKNOWN, 800h, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS)
Блин, а ведь в другом же драйвере писал. :-( Но там обрабатываются данные от системы. Не знал, что для передачи структуры надо это определять. Спасибо netex и SteelRat. В обед попробую (чтобы никто из окружающих в обморок не падал от BSoD да и время было компьютеру в себя прийти ). VMWare или нечто подобное пока не поставил, как когда-то советовал SteelRat. Один раз попробовал скачать, но файлик битым оказался, а еще раз 60М впустую, - жалко . Ребята мне обещали дать, но они в другом городе.
Само заполнение OPEN_FILE_INFORMATION и выделение памяти под эту структуру не наблюдается в приведенном коде (его юзерной части). Т.е. существует только переменная OpenFileInformation для хранения адреса, а выделение памяти под OPEN_FILE_INFORMATION и её заполнение отсутствует. Такой код и в юзере будет вызывать падение программы при попытке обращения к OpenFileInformation->KeyType
to cresta Так это же для краткости. Вот так выделяется (user-mode): OpenFileInformation = malloc(sizeof(OPEN_FILE_INFORMATION)); memset(OpenFileInformation, 0, sizeof(OPEN_FILE_INFORMATION)); memcpy(OpenFileInformation,&ka,sizeof(ka));