Вопросик про память и строки в R0

Тема в разделе "WASM.BEGINNERS", создана пользователем test555, 24 дек 2008.

  1. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Драйвер, есть потребность хранить в глобальной переменной список строк (данные будут поступать из юзермода).

    Решил воспользоваться статьей
    http://www.wasm.ru/article.php?article=drvw2k07
    Драйверы режима ядра: Часть 7: Работа с памятью. Использование ассоциативных списков

    Как создавать списки - с этим все ясно. Как с ними делать все остальное - тоже ясно.

    Приведу пример структуры:

    Код (Text):
    1.  SOME_STRUCTURE STRUCT
    2.      SomeField1    DWORD        ?
    3.      SomeField2    DWORD        ?
    4.      ListEntry    LIST_ENTRY    <>    ; Двусвязный список для управления структурами
    5.      SomeFieldX    DWORD        ?
    6.  SOME_STRUCTURE ENDS
    С DWORDами мне все ясно, сколько они памяти заимают, столько и выделится.
    А я бы хотел строки хранить в UNICODE_STRING
    Это связанно с тем, что в одном обработчике (NtQueryDirectoryFile) очень часто пришлось бы сравнивать то что содержится в списке с тем что перечислаяется в обработчике, игнорируя регистр. Почему-то нету функции сравнения 2-х анси-строк, чтобы регистр не учитывался..

    Поэтому было решено сравнивать в юникод-строках. Но при каждом сравнении чтобы не инициализировать полный список скрываемых файлов, сделать это только один раз.

    Отсюда вопрос, если я структурку сделаю к примеру такую:
    LIST_ENTRY ListEntry
    UNICODE_STRING FileName
    ULONG Index

    То при поступлении данных из юзермода, вначале добавлю в двусвязный список эту структуру а потом проинициализирую юникод-стринг?

    И соотв. перед удалением очередной структуры из списка мне надо освободить память через RtlFreeUnicodeString??

    Вообще не очень понятно, допустим есть
    PCWSTR = L"val1";

    Когда инициализируем RtlInitUnicodeString, и работает с юникод строкой, то память мы освобождать не должны, (это было написано в каком-то сообщении)

    А если у меня к примеру
    PWSTR a;

    Потом в процессе я выделяю под нее память ExAllocatePool, копирую туда данные, потом
    Код (Text):
    1. RtlInitUnicodeString(&Unic_str, &a);
    И после еще каких-то действий
    ExFreePool(&a);

    То моя то Unic_str что в данный момент содержит? Нужно ли ее FreeUnicodeString делать после этого?


    Если в RtlAnsiStringToUnicodeString в качестве третьего параметра указать TRUE то мне нужно будет память освободить. А в предыдущем примере? А что если третий параметр указать в ЛОЖЬ, то каким образом у меня будет вообще организовала эта строка?

    Судя по описанию,

    Код (Text):
    1. typedef struct _STRING {
    2.   USHORT  Length;
    3.   USHORT  MaximumLength;
    4.   PCHAR  Buffer;
    5. } ANSI_STRING, *PANSI_STRING;
    6.  
    7. typedef struct _UNICODE_STRING {
    8.   USHORT  Length;
    9.   USHORT  MaximumLength;
    10.   PWSTR  Buffer;
    11. } UNICODE_STRING, *PUNICODE_STRING;
    Анси-строка имеет указатель на буфер по 1 байту на символ, а юникод - по два байта.
    Так вот, так понимаю что если укажу RtlAnsiStringToUnicodeString(&unicode, &ansi, TRUE)
    ТО под PWSTR Buffer юникод строки будет выделена память и туда неким образом скопированы данные анси-строки, и ее потом нужно освободить.
    А что если RtlAnsiStringToUnicodeString(&unicode, &ansi, FALSE )
    Куда будут указывать поля Buffer анси и юникод строки?


    Итак, мне интересно 3 вопроса:

    1. Двухсвязный список, добавляю структуру, инициализирую в новой структуре юникод строку (из полученних ранее данных через IOCTRL, и по удалению структуры должен освободить юникод строку?

    2. Пример:
    Код (Text):
    1. UNICODE_STRING Us;
    2.  
    3. PFILE_BOTH_DIR_INFORMATION InfoPBDI;
    4. PWSTR constFile;
    5. ..
    6.     constFile = ExAllocatePool(NonPagedPool, InfoPBDI->FileNameLength +2);
    7.     RtlFillBytes(constFile, InfoPBDI->FileNameLength +2, 0);
    8.     memcpy(constFile,InfoPBDI->FileName, InfoPBDI->FileNameLength);
    9. // в троку constFile выделили память и скопировали нужные данные, потом
    10. RtlInitUnicodeString( &Us, constFile);
    11.  
    12. ExFreePool(constFile);
    Вопрос: Что произойдет о строкой Us после освобождения памяти ExFreePool(constFile)??
    Нужно ли будет грохать Us??

    Еще одна ситуация, данные поступают через IO_CTRL запросы, передается из юзермода буфер данных.
    Этими данными я хочу RtlInitUnicodeString юникод строку после добавления очередной структуры в двусвязный список.. Вопрос такой, на что будет указывать указатель PWSTR Buffer ?? На адрес поступивших из юзермода данных?


    Ну и третий вопрос,
    Какие отличия будут в
    RtlAnsiStringToUnicodeString(&unicode, &ansi, FALSE )
    RtlAnsiStringToUnicodeString(&unicode, &ansi, TRUE )
    Где в первом случае будут храниться юникод-данные? Куда указывает буфер?

    Вот. Книжку Солдатова читал, мало что написано.. А такого вот материала по строкам я не нашел ..

    Спасибо.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    test555
    Структура описывающая строки это размер её и указатель на строку. Никак сама строка не зависит от этой структуры её описывающей.
    Последний параметр даёт знать функции что она должна сама выделить под новую строку память, в таком случае после использования этой строки память должна быть освобождена.
    Это строка в пуле, укозатель на неё в стеке в структуре UNICODE_STRING, после освобождения пула укозатель на строку будет невалидным. Само собой понятно.
    Во втором случае функция сама выделит памяти в пуле для хранения строки.
     
  3. _Aspire

    _Aspire New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2008
    Сообщения:
    62
    http://msdn.microsoft.com/en-us/library/bb759942(VS.85).aspx Правда, это для юзермода..

    Какая в этом трудность? Просто в обработчике удаления структуры освобождай и все...

    Наверное, в твоем случае, я бы воспользовался разделяемой памятью для хранения строк передавая в драйвер укзатели на них.
     
  4. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    _Aspire, нужен именно кернел-мод...
    Решил все же в структуре объявить статический массив, сочел что этого достаточно будет.

    Clerk,

    Вопрос то бы все же где в ПЕРВОМ случае будет храниться строка, т.к. в анси она по 1 байту на символ, а в юникод - по два.
    Указатели на одно и то же место будут указывать что ли?
    Если так условно изобразить память:
    ANSI | | | | | | | | | | |
    UNIC | ' | ' | ' | ' | ' |

    Щас мне это не ясно...
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    В первом случае ты сам должен указать буфер, где будет хранитсо строка, поместив на него указатель в UNICODE_STRING.Buffer