Двусвязные списки в драйвере

Тема в разделе "WASM.NT.KERNEL", создана пользователем DoZENT, 12 мар 2007.

  1. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    В драйвере перехватываю различные api функции, собираю с каждой нужные мне параметры. Возник вопрос, куда девать взятые мною данные (например имя открываемого файла, id завершаемого процесса и т.д.). Т.е. необходим какой-то аналог TList (как в делфе). Прочитал Драйверы режима ядра: Часть 7: Работа с памятью. Использование ассоциативных списков , пытаюсь сделать что-то подобное на C:

    При загрузке драйвера:
    Код (Text):
    1. g_PagedList = ExAllocatePool (NonPagedPool, sizeof (PAGED_LOOKASIDE_LIST));
    2.     if (g_PagedList != NULL)
    3.     {
    4.  
    5.         ExInitializePagedLookasideList (g_PagedList,NULL,NULL,0, sizeof(ObjectsList),'msaW',0);
    6.         DPRINT("LookasideList: Lookaside list initialized\n");
    7.         InitializeListHead (g_ListHead); //без этой строки выполняется
    8.  
    9.     }
    10.     else
    11.         DPRINT("LookasideList: Couldn't allocate nonpaged memory for lookaside list control structure");
    Комп перезагружается. В чем дело?

    И еще, как мне пройтись по всем элементам списка или узнать количество элементов в списке?
     
  2. nermest

    nermest New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2006
    Сообщения:
    157
    все только ручками

    Весь смысл этих функций в быстром отдавании памяти тебе. А уж заполнение контентом и, тем более, хождение по элементам только самостоятельно.
     
  3. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    OK, но пока я даже выделить память под лист не могу(( При выполнении InitializeListHead (g_ListHead) копм делает ребут((
     
  4. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    LIST_ENTRY
    A LIST_ENTRY structure describes an entry in a doubly-linked list or serves as the header for such a list.

    typedef struct _LIST_ENTRY {
    struct _LIST_ENTRY *Flink;
    struct _LIST_ENTRY *Blink;
    } LIST_ENTRY, *PLIST_ENTRY;


    Members
    Flink
    For a LIST_ENTRY structure that serves as a list entry, the Flink member points to the next entry in the list or to the list header if there is no next entry in the list.
    For a LIST_ENTRY structure that serves as the list header, the Flink member points to the first entry in the list or to the LIST_ENTRY structure itself if the list is empty.

    Blink
    For a LIST_ENTRY structure that serves as a list entry, the Blink member points to the previous entry in the list or to the list header if there is no previous entry in the list.
    For a LIST_ENTRY structure that serves as the list header, the Blink member points to the last entry in the list or to the LIST_ENTRY structure itself if the list is empty.




    Куда g_ListHead кажет?
     
  5. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Ужас какой. Такого ремикса я ещё не видел ;) DoZENT, ты же смешал воедино две абсолютно разные сущности: lookaside list и doubly linked list! Это не одно и то же.

    Код из первого поста сразу ф топку. Примеры приводить не буду, т.к. буквально в каждом исходнике в DDK используется doubly linked list и примеры использования lookaside list тоже можно найти в том же DDK.
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    lookaside list тут не подойдет, т.к. из него можно выделять память только фиксированного размера.
     
  7. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Делал все точно так же как в статье, сам только начал в этом всем разбираться
     
  8. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Извиняюсь, невнимательно смотрел. Привидилось, что g_PagedList и g_ListHead - это одна и таже переменная. Тогда ОК, микса нету, но lookaside list в данном случае не подойдет, т.к. куски памяти будут разного размера. Так что просто ExAllocatePool.

    Инициализировать doubly linked list так:
    LIST_ENTRY g_ListHead;
    InitializeListHead( &g_ListHead );

    Остальное лучше глянуть в DDK.
     
  9. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Извиняюсь, не понял
    Так какого размера куски памяти то будут? И если разного, то почему так нельзя сделать? Я же буду хранить данные в структуре фиксированного размера.
     
  10. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    В документации про пятый параметр функции ExInitializePagedLookasideList написано:

    Specifies the size in bytes of each entry in the lookaside list.

    Поэтому, если инициализировать ассоциативный список так

    ExInitializePagedLookasideList (g_PagedList,NULL,NULL,0, sizeof(ObjectsList),'msaW',0);

    то ExAllocateFromPagedLookasideList будет возвращать куски памяти размером sizeof(ObjectsList). И изменить размер динамически нельзя.


    Из ассоциативного списка можно выделять только определенный при инициализации размер.


    Это не вяжется с твоим первым постом:

    "Возник вопрос, куда девать взятые мною данные (например имя открываемого файла,...)."

    Имя файла в принципе не может иметь фиксированную длину. Мало того, длина имен файлов может отличаться в разы и более. Так что не получается структур фиксированного размера. Ну если только они не будут размером, равным максимально возможному размеру имени файла, но в этом случае большая часть памяти будет болтаться без дела.
     
  11. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    mb имя файла типа PWCHAR? :)
     
  12. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    ОК, это понятно, спасибо. Сейчас DDK читаю, немного не понял, что такое KSPIN_LOCK, KeInitializeSpinLock и т.д.? Типа для синхронизации? Обязательно ли в моем случае это дело использовать?
     
  13. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    К сожелению, нет времени отвечать на каждый вопрос, а их, я так понимаю будет ещё очень много ;)

    Могу посоветовать прочитать книгу Walter Oney "Programming the Microsoft Windows Driver Model, Second Edition" в подлиннике или перевод http://www.piter.com/book/978591180057/ (качество перевода оценить не могу - в руках ещё не держал).
     
  14. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Угу.
    Если один поток, то нет. Но для перехвата API желательно использовать в самом перехватчике, если ты собираешься работать со списками.
     
  15. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Кто-нибудь может написать пусть не код, конечно, но простейший алгоритм работы с двойными списками? Действия, которые мне нужны в принципе:
    I) инициализировать список,
    II) вставить в него элемент,
    III)удалить из него элемент,
    IV)проверить существование элемента


    Как я понял:

    Объявляем структуру
    Код (Text):
    1. typedef struct _SOME_STRUCT
    2. {
    3.    UNICODE_STRING FileName;  
    4.    LIST_ENTRY listHead;   // head pointer
    5. } SOME_STRUCT, *PSOME_STRUCT;
    I) 1. InitializeListHead( &some_structVar->listHead ); //Это все?

    II) 1. InsertHeadList (&some_structVar->listHead, Points to an entry to be inserted in the list)
    Что должно быть вторым параметром? Мне нужно вставить структуру данных типа SOME_STRUCT, а мне предлагают PLIST_ENTRY.. Объясните дураку, чего-то туплю я.

    III) 1. RemoveHeadList (&some_structVar->listHead);
    Так удалится структура, которая лежит на самой верхушке листа (последняя, добавленная). А если мне надо удалить ту, которая в середине?

    IV) Вообще не знаю…

    Заранее спасибо.
    P.S. Чувствую, что чего-то не понял в корне, просто раньше работал исключительно с делфами, так привык к тамошнему TList, TStringList, что что-то другое уже плохо воспринимается((
     
  16. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Есть у меня эта книга в электронном виде, почему-то не обращал на нее внимание. Действительно, надо почитать, там про списки есть?
     
  17. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Да. И про всё остальное тоже.
     
  18. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Имхо лучше listHead в начало структуры положить. Чтобы указатель на LIST_ENTRY совпадал с указателем на структуру.
    Кроме этогоне listHead, а ListEntry.
    Нет. Есть глобальная переменная listHead, её и надо инициализировать.
    Элемент который ты добавляешь. То есть тебе надо
    Код (Text):
    1. InitializeListHead(ListHead, &some_structVar->listEntry );
    RemoveEntryList(). Параметр - указатель на тот элемент который тебе надо удалить.
    Перебрать все элементы.
    Могу схемку нарисовать. Хотя можешь посмотреть схему связи EPROCESS. Правда не помню в какой статье её встречал.
     
  19. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    А в предложенной выше книжке написано так:
    Код (Text):
    1. typedef struct _DEVICE_EXTENSION {
    2.  
    3.   LIST_ENTRY IrpQueue;
    4.   BOOLEAN DeviceBusy;
    5.   } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    6.  
    7. NTSTATUS AddDevice(...)
    8.   {
    9.  
    10.     InitializeListHead(&pdx->IrpQueue);
    11.  
    12.   }
    Кому верить?)
     
  20. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Книжке.