Переименование файла из драйвера

Тема в разделе "WASM.BEGINNERS", создана пользователем AB_Celitel, 21 окт 2006.

  1. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    Приветствую всех !!!

    У меня такой вопрос, как можно переимновать файл из драйвера?
    Но только без копирования с другим именем и удаления старого файла

    И еще :
    Требуется отслеживать изменение имен файлов в заданное имя.
    Как это можно сделать?

    Заранее спасибо
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    NtSetInformationFile, с FileInformationClass = FileRenameInformation.
     
  3. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    n0name

    Спасибо,

    Т.е. что бы отследить изменение имени надо перехватывать NtSetInformationFile с FileInformationClass = FileRenameInformation и
    проверять в FILE_RENAME_INFORMATION поле с именем файла.?
     
  4. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    Проверьте пжл, правильно ли я понимаю эту структуру :

    FILE_RENAME_INFORMATION struct
    ReplaceIfExists db ?
    RootDirectory dd ?
    FileNameLength dd ? ; кол-во байт имени файла
    FileName dw ? ; первый знак в новом имени файла
    FILE_RENAME_INFORMATION ends
     
  5. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    Код (Text):
    1. local buf_new_name[250]:byte
    2.  
    3.   edi - указывает на начало стека параметров NtSetInformationFile
    4.  
    5.    mov esi, [edi+(2 * sizeof dword)]  ; pointer to FILE_RENAME_INFORMATION
    6.    assume esi:ptr FILE_RENAME_INFORMATION
    7.    mov ecx,[esi].FileNameLength
    8.    dec ecx
    9.    lea ebx,[esi].FileName
    10.    lea edx,buf_new_name
    11.    .while (ecx != -1)
    12.      mov al, byte ptr [ebx+ecx]
    13.      .if (al != 0)                ; пропускаем 0 между буквами, т.к. строка WCHAR
    14.       mov byte ptr [edx+ecx], al
    15.      .endif
    16.      dec ecx
    17.    .endw
    18.    invoke DbgPrint, addr buf_new_name
    19.    
    20.    assume esi:nothing
    В результате вылетает ошибка C0000005 - Неверная попытка доступа к адресу памяти.

    Вот никак не могу понять почему. Подскажите пжл кто сможет :)

    ЗЫ:
    В SoftIce'е поглядеть не могу, т.к. при нажатии на Ctrl-D вылетает черный экран и все висит :/
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    а там случаем на dd?
     
  7. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    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'а :))
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    нет.
    да не за что =)
    разве DbgPrint печатает PWideChar строку?
    я им и не пользовался никогда :P
     
  9. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    n0name

    Нет, у меня же там написано
    Код (Text):
    1.      .if (al != 0)                ; пропускаем 0 между буквами, т.к. строка WCHAR
    2.       mov byte ptr [edx+ecx], al
    3.      .endif
    Вот, т.е. в buf_new_name должна получиться обычная CHAR строка
    В этом то и проблема, что че то не то получается :))


    Ну не знаю, если б он щас у меня работал, я уже бы 2 часа назад поглядел что не так и испрвил, а тут сиди и думай :/

    А с WCHAR FileName действительно имя файла начинается, или это указатель на имя.
    Я уже по всякому пробовал, никак не пишет мне имя нового файла :/
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    дык может ты не правильно заполняешь его, или он у тебя паереименовавает?
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Ставь DDK и смотри, что такое конкретный тип. BOOL, BOOLEAN - это не bool (которого в чистых сях вообще нет).

    А если там путь на "местном наречии"? Не проще ли wcsncpy + DbgPrint("new file name: %ws\n")?

    Эх, горе-писатели. Не зная элементарных вещей суются драйвера писать. Кому нужны они, драйвера ваши?
     
  12. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    IceStudent

    Я это просто так к слову написал, т.к. бывыет такое, что в простых вещах в которых полностью уверен и уже не обращаешь на них внимания, и бывают ошибки. Вот
    А с драйверами пока что у меня все нормально было. Небольшая путаница в типах получилась, т.к. я обычно пишу на асме или делфи, а на си довольно редко. Ну и поэтому не стоит так
    сразу называть.:) :/

    "местные наречии" там врятли будут: только латинские и русские буквы :)

    n0name

    Он у меня отслеживает переименовывание файлов. И мне надо узнать новое имя, который вписал юзверь и решить, а нужно ли таким именем файл называть.

    Ну а если разобраться : тип WCHAR это 1-ый байт - символ, 2-й байт - 0, и если
    читать эту строку в другой буфер пропуская нули, то получим обычную ANSI строку,
    но блин не получается почему то.:/
     
  13. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    Ура, ура, ура я нашел ошибку. Так, как я говорил, в самом простом месте
    Вот рабочий цикл :
    Код (Text):
    1. local buf_new_name[250]:byte
    2.  
    3.  invoke memset, addr buf_new_name, 0, sizeof buf_new_name
    4.  
    5.   edi - указывает на начало стека параметров NtSetInformationFile
    6.  
    7.    mov esi, [edi+(2 * sizeof dword)]  ; pointer to FILE_RENAME_INFORMATION
    8.    assume esi:ptr FILE_RENAME_INFORMATION
    9.    xor ecx,ecx
    10.    lea ebx,[esi].FileName
    11.    lea edx,buf_new_name
    12.    .while (ecx != [esi].FileNameLength)
    13.      mov al, byte ptr [ebx+ecx]
    14.      .if (al != 0)
    15.        mov byte ptr [edx], al
    16.        inc edx
    17.      .endif
    18.      inc ecx
    19.    .endw
    20.    invoke DbgPrint, addr buf_new_name
    21.    
    22.    assume esi:nothing
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Балом правит MS и её SDK (а они на си), поэтому ты должен как минимум уметь читать код на си, чтобы понимать, как оно будет взаимодействовать с системой.

    А "русские буквы" под юникодом не видел, как кодируются? Посмотри.

    WCHAR - это wide char, Unicode (UTF-16). Каждый символ кодируется 16 битами. Естесственно, для первых 256 байт старший байт будет равен 0, но это только для первых 256 и если ты уверен, что у тебя только латиница, то можно пропускать старшие байты. Диапазон кириллицы же намного дальше и старший байт равен 4, поэтому здесь нужно применять специальное перекодирование.

    Что касается твоего кода:
    Код (Text):
    1.    push esi
    2.    push edi
    3.    mov esi, [edi+(2 * sizeof dword)]  ; pointer to FILE_RENAME_INFORMATION
    4.    assume esi:ptr FILE_RENAME_INFORMATION
    5.    mov ecx,[esi].FileNameLength
    6.    mov edx,sizeof(buf_new_name)-1
    7.    cmp ecx,edx
    8.    cmova ecx,edx
    9.    lea edi,[buf_new_name]
    10.    lea esi,[esi].FileName
    11.    assume esi:nothing
    12. @@:
    13.    lodsw
    14.    stosb
    15.    loop @B
    16.    pop edi
    17.    pop esi
    18.    invoke DbgPrint, addr szStrFmt,addr buf_new_name
    19. ...
    20. szStrFmt  db '%s',0
    Ессно, здесь никакой оптимизации, только пример относительно корректного кода с оговоркой, что символы только латинские в имени файла.
     
  15. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    IceStudent

    Да, я уже заметил :))
    Буду думать над перекодировкой в ANSI :)

    Ну это да, просто когда писал ступил чего-то :)
     
  16. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    А что там думать? Использовать API либо свои библиотеки. Проще API - wcstombs, например.
     
  17. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    IceStudent

    Т.е. вот так :
    Код (Text):
    1.   ; esi - pointer to FILE_RENAME_INFORMATION
    2.   invoke memset, addr buf_new_name, 0, sizeof buf_new_name
    3.   invoke memcpy, addr buf_new_name, addr [esi].FileName, [esi].FileNameLength  
    4.   invoke RtlInitUnicodeString, addr us, addr buf_new_name
    5.   invoke RtlUnicodeStringToAnsiString, addr as, addr us, TRUE
    6.   invoke DbgPrint, as.Buffer
    7.   invoke RtlFreeAnsiString, addr as
     
  18. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    IceStudent

    Да, спасибо, действительно проще и меньше :)
    Код (Text):
    1.  invoke memset, addr buf_new_name, 0, sizeof buf_new_name
    2.  invoke wcstombs, addr buf_new_name, addr [esi].FileName, [esi].FileNameLength
    3.  invoke DbgPrint, addr buf_new_name
     
  19. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Да не пиши memset. Для строк достаточно завершающего нуля, стандартные функции его ставят. У тебя была ошибка, что ты не копировал 0, поэтому не работало.
     
  20. AB_Celitel

    AB_Celitel New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2005
    Сообщения:
    72
    Адрес:
    Россия, г.Иваново
    IceStudent

    там ошибка в другом была: 0 копировался, но не туда :)

    А memset - это я на всякий случай написал; уже убрал :)