Приветствую всех !!! У меня такой вопрос, как можно переимновать файл из драйвера? Но только без копирования с другим именем и удаления старого файла И еще : Требуется отслеживать изменение имен файлов в заданное имя. Как это можно сделать? Заранее спасибо
n0name Спасибо, Т.е. что бы отследить изменение имени надо перехватывать NtSetInformationFile с FileInformationClass = FileRenameInformation и проверять в FILE_RENAME_INFORMATION поле с именем файла.?
Проверьте пжл, правильно ли я понимаю эту структуру : FILE_RENAME_INFORMATION struct ReplaceIfExists db ? RootDirectory dd ? FileNameLength dd ? ; кол-во байт имени файла FileName dw ? ; первый знак в новом имени файла FILE_RENAME_INFORMATION ends
Код (Text): local buf_new_name[250]:byte edi - указывает на начало стека параметров NtSetInformationFile mov esi, [edi+(2 * sizeof dword)] ; pointer to FILE_RENAME_INFORMATION assume esi:ptr FILE_RENAME_INFORMATION mov ecx,[esi].FileNameLength dec ecx lea ebx,[esi].FileName lea edx,buf_new_name .while (ecx != -1) mov al, byte ptr [ebx+ecx] .if (al != 0) ; пропускаем 0 между буквами, т.к. строка WCHAR mov byte ptr [edx+ecx], al .endif dec ecx .endw invoke DbgPrint, addr buf_new_name assume esi:nothing В результате вылетает ошибка C0000005 - Неверная попытка доступа к адресу памяти. Вот никак не могу понять почему. Подскажите пжл кто сможет ЗЫ: В SoftIce'е поглядеть не могу, т.к. при нажатии на Ctrl-D вылетает черный экран и все висит :/
n0name Ух ты, заработало, спасибо. Из MSDN : typedef struct _FILE_RENAME_INFORMATION { BOOLEAN ReplaceIfExists; HANDLE RootDirectory; ULONG FileNameLength; WCHAR FileName[1]; } FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; BOOLEAN ReplaceIfExists; <- BOOLEAN вроде как byte Странно, но теперь DbgPrint показывает везде знак "/" и все, хотя у меня там вроде при копировании в buf_new_name нули пропускаются, или WCHAR FileName[1] это тоже указатель на строку, а не 1-ая буква имени файла как написано в MSDN ? ЗЫ: Как же плохо без SoftIca'а )
n0name Нет, у меня же там написано Код (Text): .if (al != 0) ; пропускаем 0 между буквами, т.к. строка WCHAR mov byte ptr [edx+ecx], al .endif Вот, т.е. в buf_new_name должна получиться обычная CHAR строка В этом то и проблема, что че то не то получается ) Ну не знаю, если б он щас у меня работал, я уже бы 2 часа назад поглядел что не так и испрвил, а тут сиди и думай :/ А с WCHAR FileName действительно имя файла начинается, или это указатель на имя. Я уже по всякому пробовал, никак не пишет мне имя нового файла :/
Ставь DDK и смотри, что такое конкретный тип. BOOL, BOOLEAN - это не bool (которого в чистых сях вообще нет). А если там путь на "местном наречии"? Не проще ли wcsncpy + DbgPrint("new file name: %ws\n")? Эх, горе-писатели. Не зная элементарных вещей суются драйвера писать. Кому нужны они, драйвера ваши?
IceStudent Я это просто так к слову написал, т.к. бывыет такое, что в простых вещах в которых полностью уверен и уже не обращаешь на них внимания, и бывают ошибки. Вот А с драйверами пока что у меня все нормально было. Небольшая путаница в типах получилась, т.к. я обычно пишу на асме или делфи, а на си довольно редко. Ну и поэтому не стоит так сразу называть. :/ "местные наречии" там врятли будут: только латинские и русские буквы n0name Он у меня отслеживает переименовывание файлов. И мне надо узнать новое имя, который вписал юзверь и решить, а нужно ли таким именем файл называть. Ну а если разобраться : тип WCHAR это 1-ый байт - символ, 2-й байт - 0, и если читать эту строку в другой буфер пропуская нули, то получим обычную ANSI строку, но блин не получается почему то.:/
Ура, ура, ура я нашел ошибку. Так, как я говорил, в самом простом месте Вот рабочий цикл : Код (Text): local buf_new_name[250]:byte invoke memset, addr buf_new_name, 0, sizeof buf_new_name edi - указывает на начало стека параметров NtSetInformationFile mov esi, [edi+(2 * sizeof dword)] ; pointer to FILE_RENAME_INFORMATION assume esi:ptr FILE_RENAME_INFORMATION xor ecx,ecx lea ebx,[esi].FileName lea edx,buf_new_name .while (ecx != [esi].FileNameLength) mov al, byte ptr [ebx+ecx] .if (al != 0) mov byte ptr [edx], al inc edx .endif inc ecx .endw invoke DbgPrint, addr buf_new_name assume esi:nothing
Балом правит MS и её SDK (а они на си), поэтому ты должен как минимум уметь читать код на си, чтобы понимать, как оно будет взаимодействовать с системой. А "русские буквы" под юникодом не видел, как кодируются? Посмотри. WCHAR - это wide char, Unicode (UTF-16). Каждый символ кодируется 16 битами. Естесственно, для первых 256 байт старший байт будет равен 0, но это только для первых 256 и если ты уверен, что у тебя только латиница, то можно пропускать старшие байты. Диапазон кириллицы же намного дальше и старший байт равен 4, поэтому здесь нужно применять специальное перекодирование. Что касается твоего кода: Код (Text): push esi push edi mov esi, [edi+(2 * sizeof dword)] ; pointer to FILE_RENAME_INFORMATION assume esi:ptr FILE_RENAME_INFORMATION mov ecx,[esi].FileNameLength mov edx,sizeof(buf_new_name)-1 cmp ecx,edx cmova ecx,edx lea edi,[buf_new_name] lea esi,[esi].FileName assume esi:nothing @@: lodsw stosb loop @B pop edi pop esi invoke DbgPrint, addr szStrFmt,addr buf_new_name ... szStrFmt db '%s',0 Ессно, здесь никакой оптимизации, только пример относительно корректного кода с оговоркой, что символы только латинские в имени файла.
IceStudent Да, я уже заметил ) Буду думать над перекодировкой в ANSI Ну это да, просто когда писал ступил чего-то
IceStudent Т.е. вот так : Код (Text): ; esi - pointer to FILE_RENAME_INFORMATION invoke memset, addr buf_new_name, 0, sizeof buf_new_name invoke memcpy, addr buf_new_name, addr [esi].FileName, [esi].FileNameLength invoke RtlInitUnicodeString, addr us, addr buf_new_name invoke RtlUnicodeStringToAnsiString, addr as, addr us, TRUE invoke DbgPrint, as.Buffer invoke RtlFreeAnsiString, addr as
IceStudent Да, спасибо, действительно проще и меньше Код (Text): invoke memset, addr buf_new_name, 0, sizeof buf_new_name invoke wcstombs, addr buf_new_name, addr [esi].FileName, [esi].FileNameLength invoke DbgPrint, addr buf_new_name
Да не пиши memset. Для строк достаточно завершающего нуля, стандартные функции его ставят. У тебя была ошибка, что ты не копировал 0, поэтому не работало.
IceStudent там ошибка в другом была: 0 копировался, но не туда А memset - это я на всякий случай написал; уже убрал