Необходимо из драйвера передать структуру в ринг3. Делаю так: ринг3 (делфа ): Код (Text): type TCanIGetThisData = record DirName : LPWSTR; ProcessName : PCHAR; end; ..... var z : TCanIGetThisData; ..... hDriver := CreateFile (PChar ('\\.\' + DriverName),GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0); if (hDriver <> ERROR_FILE_NOT_FOUND) and (hDriver <> INVALID_HANDLE_VALUE) then begin if DeviceIoControl (hDriver, 2, nil,0, @z,sizeof (z) , BytesReaded, nil) = FALSE then MessageBox (0, 'Ошибка при передаче', 'caption', MB_ICONERROR) else if D.ProcessName <> '' then MessageBox (0, PChar (D.ProcessName), 'adfa', MB_OK); // Здесь вылетает((((( CloseHandle (hDriver); end; ринг0: Код (Text): if ( pisl->MajorFunction == IRP_MJ_DEVICE_CONTROL) { ULONG ControlCode = pisl->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x03; if (pisl->Parameters.DeviceIoControl.IoControlCode == 2) { ULONG InputLength = pisl->Parameters.DeviceIoControl.InputBufferLength; ULONG OutputLength = pisl->Parameters.DeviceIoControl.OutputBufferLength; DPRINT("Buffer outlength %d",OutputLength); if (OutputLength < sizeof (TCanIGetThisData)) { DPRINT ("Buffer is too small"); status = STATUS_INVALID_PARAMETER; } else { //Размер буфера подходит TCanIGetThisData *buff; if(method==METHOD_BUFFERED) { buff = (PCanIGetThisData)Irp->AssociatedIrp.SystemBuffer; buff->DirPath = L"adsfdsaf"; buff->ProcessName = "dsfds"; DPRINT("Method : BUFFERED"); } else if (method==METHOD_NEITHER) { buff=(TCanIGetThisData*)Irp->UserBuffer; buff->DirPath = L"adsfdsaf"; buff->ProcessName = "dsfds"; DPRINT("Method : NEITHER"); } else { //DPRINT("-Example- Method : unsupported."); //status = STATUS_INVALID_DEVICE_REQUEST; buff = (PCanIGetThisData) MmGetSystemAddressForMdlSafe (Irp->MdlAddress,NormalPagePriority); buff->DirPath = L"adsfdsaf"; buff->ProcessName = "dsfds"; } } } } } ....... IoCompleteRequest(Irp, IO_NO_INCREMENT); При выводе MessageBox программа вылетает...
Как же ей не вылетать то? Ведь в драйвер передается структура из двух указателей. Драйвер записывает туда указатели на строки, но строки то эти находятся в теле драйвера! Когда MessageBox пытается из прочитать, то залезает в ядерные адреса и обламывается. ЗЫ: В коде много других ошибок.
ох... Из тех что бросаются в глаза: 1. Т.к. данные передаются из драйвера, то в CreateFile вместо/<вместе с> GENERIC_WRITE должно быть GENERIC_READ. Иначе диспечтер в/в не отобразит ядерный буфер, заполненный драйвером, в юзермодный буфер. 2. Код (Text): ULONG ControlCode = pisl->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x03; if (pisl->Parameters.DeviceIoControl.IoControlCode == 2) Уверен, что имелось в виду... Код (Text): ULONG ControlCode = pisl->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x03; // METHOD_OUT_DIRECT == 2 if ( method == METHOD_OUT_DIRECT ) 3. Код (Text): if (method==METHOD_NEITHER) { buff=(TCanIGetThisData*)Irp->UserBuffer; buff->DirPath = L"adsfdsaf"; buff->ProcessName = "dsfds"; } Для метода NEITHER все обращения к юзермодному буферу обязательно оборачиваются в SEH и буферы предварительно проверяются на доступность. Код (Text): try { ProbeForRead( buff, InputLength, sizeof( UCHAR ) ); // если читаем или ProbeForWrite( buff, OutputLength, sizeof( UCHAR ) ); // если пишем // работаем с буфером } except(EXCEPTION_EXECUTE_HANDLER) { ntStatus = GetExceptionCode(); DPRINT("Exception 0X%08X \n", GetExceptionCode() ); } 4. Код (Text): if(method==METHOD_BUFFERED) { } else { if (method==METHOD_NEITHER) { } else { // тут плохо } } Если метод в/в не METHOD_BUFFERED и не METHOD_NEITHER, значит это METHOD_IN_DIRECT или METHOD_OUT_DIRECT, но дело в том, что METHOD_IN_DIRECT отличается от METHOD_OUT_DIRECT как небо и земля, хотя это и неочевидно, а твоём коде обрабатывается совершенно одинокого. Достаточно внимательно прочитать "Buffer Descriptions for I/O Control Codes" в DDK. 5. Код (Text): if(method==METHOD_BUFFERED) { код } else другой код (одна строка) В данном случае это не ошибка, но настоятельно не рекомендую делать if/else без {}, т.к. если в коде будет макрос, что не всегда очевидно, то он может раскрыться в несколько строк и компилятор запихает в if/else только первую строку. Вобщем советую всегда тупо делать. Код (Text): if(method==METHOD_BUFFERED) { код } else { другой код } 6. Не ошибка, но непонятно зачем городить огород с обработкой разных методов в/в. В данном случае размер данных мал, значит тупо METHOD_BUFFERED. Если есть какие-то другие соображения, то вниметельно разобраться со всеми методами поможет DDK\src\general\ioctl\.