Ms Rem, доброго!!! прочитал твои статьи, хороший материал, скорей всего он будет использован мной в будущем. А теперь вопрос, ты наверное понмнишь мои предыдущии посты, и отталкиваясь от них, у меня вопрос к тебе , потому как думаю, ты точно знаешь на него ответ. И так, я пытаюсь открыть файл-лог из драйвера, но не получается, ZwCreateFile возвращает этот код ERROR_PATH_NOT_FOUND, путь я задаю так const DEFAULT_LOG_FILE_NAME = '\?\C:\avsd.log'; где именно я ошибся, как правильно задать пусть????? ниже код: Код (Text): function DVRH_Log: Boolean; const DEFAULT_LOG_FILE_NAME = '\?\C:\avsd.log'; var Length: ULONG; messagebuf: array[0..256-1] of char; IoStatus: IO_STATUS_BLOCK; objectAttributes: OBJECT_ATTRIBUTES; status: NTSTATUS; FileHandle: HANDLE; fileName: UNICODE_STRING; buf: array[0..300-1] of CHAR; time: LARGE_INTEGER; begin RtlInitUnicodeString( @fileName, DEFAULT_LOG_FILE_NAME ); InitializeObjectAttributes (@objectAttributes, @fileName, OBJ_CASE_INSENSITIVE or OBJ_KERNEL_HANDLE, 0, nil ); status := ZwCreateFile( @FileHandle, GENERIC_READ or GENERIC_WRITE or SYNCHRONIZE, @objectAttributes, @IoStatus, nil, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ or FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0); if ERROR_PATH_NOT_FOUND = status then begin DbgPrint('ERROR_PATH_NOT_FOUND'); DbgPrint(#13#10); end; if( NT_SUCCESS(status) )then begin Length := 300; buf[0] := '1'; buf[1] := '2'; buf[2] := '3'; ZwWriteFile( FileHandle, 0, nil, nil, @IoStatus, @buf, Length, nil, nil); ZwClose( FileHandle ); end; Result := NT_SUCCESS(STATUS_SUCCESS); end;
вроде вот так работает DEFAULT_LOG_FILE_NAME = '\Device\HarddiskVolume1\avsd.log'; но неужто нельзя, что-то попроще?????? почему не проходит этот вариант \?\C:\avsd.log????
Вариант с \??\C:\avsd.log должен работать. И вообще, я тебе не советую в драйвере привязываться к буквам дисков, лучше работать с каталогом Windows, он всегда доступен по пути \SystemRoot\, независимо от того, на каком диске стоит система. И для упрощения работы с файлами создай функции тапа: Код (Text): ULONG MyGetFileSize(HANDLE hFile) { FILE_STANDARD_INFORMATION Info; IO_STATUS_BLOCK IoStatusBlock; ZwQueryInformationFile(hFile, &IoStatusBlock, &Info, sizeof(Info), FileStandardInformation); return Info.EndOfFile.LowPart; } NTSTATUS MyReadFile( IN HANDLE hFile, OUT PVOID lpBuffer, IN ULONG nNumberOfBytesToRead) { IO_STATUS_BLOCK IoStatusBlock; return ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, lpBuffer, nNumberOfBytesToRead, NULL, NULL); } NTSTATUS MyWriteFile( IN HANDLE hFile, IN PVOID lpBuffer, IN ULONG nNumberOfBytesToWrite) { IO_STATUS_BLOCK IoStatusBlock; return ZwWriteFile(hFile, NULL, NULL, NULL, &IoStatusBlock, lpBuffer, nNumberOfBytesToWrite, NULL, NULL); }
Ms Rem, работает. За совет по функциям, большущий фэнкс. Лог файл мне нужен для отладки, потому как не все я могу увидеть через DbgPrint, да и при BSOD, в дампе почему-то не всегда присутсвует отладочная информация.
Кстати, у Dbgview есть функция восстановления из аварийного дампа информации выведенной через DbgPrint. Работает эта фича 100%, главное делать полный дамп памяти ядра.
Ms Rem. "Dbgview" ну так я о ней и говорил. что не работает, весь прикол заключается в том, что там может быть совершенно устаревшая информация, и мне не понятно почему это происходит
Ms Rem, очередной вопрос: почему функцию RtlUnicodeStringToAnsiString возращает не корректный результат RtlUnicodeStringToAnsiString(@astring,@buffer,FALSE) где buffer: array[0..1024] of Char; на момент выполнения данной функции в буфере находиться следующая информация: 8 байт "служебной" информации, а все остальное строка в представлении Unicode по структуре напоминает Код (Text): UNICODE_STRING = record Length : UShort; MaximumLength : UShort; Buffer : PWideChar; end; казалось бы именно это и нужной в качестве второй переменной данной функции, но результат получается иной в astring я получаю "Y\MACHINE\HARDWARE\DESCRIPTION\SYSTEM\MultifunctionAdapter", т.е. отсекается 8 байт. в чем может быть проблема?
Во первых: что за криворукий способ с buffer: array[0..1024] of Char? когда я писал дрова на дельфи и передавал указатель на UNICODE_STRING то все у меня работало. Во вторых: проверь как у тебя описана структура ANSI_STRING. Правильно будет так: Код (Text): PANSI_STRING = ^ANSI_STRING; ANSI_STRING = packed record Length: USHORT; MaximumLength : USHORT; Buffer: PChar; end; В третьих: после служебных данных у тебя в буфере находится строка, а куда указывает Buffer : PWideChar? Он должен указывать на начало строки, независимо от того где она находится. В четвертых: сколько раз говорить, что структуры надо описывать как packed record? И вообще, если решил писать серьезные дрова на дельфи, то надо избавляться от кривых мест типа buffer: array[0..1024] of Char; и десять раз перепроверять описания всех структур и функций, а иначе получится черт знает что. Если у тебя это и так компилится и работает, то это не означает что все описано правильно. Так что мой совет - ЕЩЕ РАЗ ВСЕ ПЕРЕПРОВЕРИТЬ.
И еще один совет: Надо четко понять разницу между строками и указателями, например array[0..255] of Char это строка, а PChar - это указатель. Поэтому работа с строками в динамической памяти будет выглядеть так: Код (Text): var Str: PUNICODE_STRING; Len: dword; begin // пусть Len - длина создаваемой строки в символах Str := ExAllocatePool(PagedPool, SizeOf(UNICODE_STRING) + SizeOf(WideChar) * Len); Str^.Buffer := pointer(ulong(@Str) + SizeOf(UNICODE_STRING)); end; В этом случае мы выделяем память и под структуру и под строку одновременно. Или так: Код (Text): const String: PWideChar = 'MyString'; var Str: UNICODE_STRING; begin RtlInitUnicodeString(Str, String); end; Так следует поступать с константной строкой. И вообще, забудь что пишешь на дельфи, думай и пиши так, как это делается на си.
Ms Rem ANSI_STRING у меня объявлена эта структура так Код (Text): type PString = ^TString; _STRING = record Length: USHORT; MaximumLength: USHORT; Buffer: PCHAR; end; TString = _STRING; ANSI_STRING = _STRING; PANSI_STRING = ^_STRING; по поводу кривого способа Uchar buffer[1024], этот спсобо из оригbнальной версии кода, и там этот кривой способ работает, я в данный момент не могу судить о кривости, но если ты так думаешь, то соглашусь. по поводу упаковки структур, первоначально я так и делал, но в процесси работы, не все структуры работали, после чего я убрал packed record, не скажу что именно из-за этого у меня все стало работать, но и без packed record тоже работает, на данного момент отлично. все же по твоему совету добавил packed , но результат остался не изменным. остается все еще раз перепроверить. ))) отругал ты меня как мальчишку )))
LuckyDevil Вроде структура ANSI_STRING описана правильно. Вероятно этот глюк можно отнести к разряду "багов метафизического порядка", тоесть когда все правильно и все равно не работает. У меня подобные ситуации бывали, и всегда оказывалось что дело в какой-нибудь мелкой фигне, которую забыл как надо сделать. Подобные ошибки неприятны тем, что для решения проблемы требуется длительная медитация и крепкие уши у окружающих (так как во время отладки произносится много неценурных выражений) Могу здесь посоветовать только поставить айс и прогнать под ним оригинальную и твою версии дров. И внимательно посмотреть какие структуры передаются апишкам и какие ими возвращаются. По достижении успехов в написании дров на дельфи, с тебя статья об этом Я думаю. что эта тема была бы многим интересна.
Ms Rem, <font color="red]"багов метафизического порядка"</font><!--color--> вот именно, учитывая мою природную рассеянность, то получаются вешалки на все 100%, да еще какие, про нецензурную брань... лучше ничего не говорить. А поповоду статьи, быть может... хотя мало вероятно. Зато можно будет сделать полную хронологию из постов форума )))), учитывая что я тут выкладываю практический весь свой код, правда в моей не корректной интерпретации .
Ms Rem кстати по поводу данной функции ExAllocatePool, у меня возникают проблемы, так она у меня объявлена: Код (Text): function ExAllocatePool( PoolType: POOL_TYPE; NumberOfBytes: SIZE_T):PVOID; stdcall; external NTOSKrnl name '_ExAllocatePool@8'; procedure ExFreePool( P: PVOID );stdcall; external NTOSKrnl name '_ExFreePool@4'; где-то здесь у меня ошибка, ткни пальцем что не так. структура POOL_TYPE: Код (Text): type _POOL_TYPE = (NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS ); POOL_TYPE = _POOL_TYPE;
Я тут панику зря подня по поводу того что RtlInitUnicodeString(@buf_un,@buffer) работает как-то не корректно, я был не прав работает, проблема в другом ... Код (Text): if(NT_SUCCESS(RtlUnicodeStringToAnsiString(@astring,@buf_un,FALSE))) then // <- @buffer[0] begin DVRH_LogMessage(astring.Buffer,astring.Length); PDOB_NAME_STRING(out_buffer)^.name := astring; PDOB_NAME_STRING(out_buffer)^.status := 1; [b]Irp^.IoStatus.Information := Irp^.IoStatus.Information + 8 + PDOB_NAME_STRING(out_buffer)^.name.Length;[/b] end; Проблема кажется тут Irp^.IoStatus.Information := Irp^.IoStatus.Information + 8 + PDOB_NAME_STRING(out_buffer)^.name.Length;
Ms Rem Как в SoftIce увидеть Дельфовский исходник?? Какие опции(директивы) нужно выставить в Дельфи?? Что мы получим и как энто загрузить в сайс?? Сам мучилса над этой проблемой, но у меня то вобше не находило отладоной инфы, то никак на нее не реагировало..(всеже там стоит Include TD32 debug info)
Где-то видал про конвертацию TD32 debug info в отладочные символы, но сам не юзал. А понять в чем проблема поможет и асм листинг, внимание следует обратить на то что передается апишкам и что они возвращают. Тогда и косяк свой найти можно.