2014-12-01 5 views
0

Я создаю драйвер фильтра в NDIS 6. Я хочу добавить некоторые данные в конец моего NET_BUFFER. Чтобы добавить данные, я выделил MDL через API NdisAllocateMdl. Теперь я хочу знать, есть ли какая-либо оболочка для добавления этого MDL в существующую цепочку MDL?NdisChainBufferAtBack подстановка в NDIS 6

Если нет, правильно ли сделать последний указатель MDL Next указать на мой новый выделенный MDL, как я был в состоянии сделать это? Кроме того, какие поля в NET_BUFFER мне нужно изменить, чтобы распознать добавленный MDL?

ответ

1

Фактическая полезная нагрузка пакета NET_BUFFER является подмножеством полезной нагрузки всей цепочки MDL. Пакет может не запускаться в начале цепочки MDL, и пакет может не заканчиваться в конце цепочки MDL.

Таким образом, в самом общем случае вам нужно будет удалить некоторые MDL с конца NET_BUFFER, прежде чем вы добавите новый MDL. Позвольте мне привести конкретный пример:

NET_BUFFER 
    * DataOffset=300 bytes 
    * DataLength=200 bytes 
    * MdlChain=[200 bytes]->[200 bytes]->[300 bytes]->[200 bytes] 

Таким образом, в этом примере, NET_BUFFER точки к MDL цепи с 4 MDLs в нем. Давайте посмотрим на буферах в ASCII-арт:

0  100 200 300 400 500 600 700 800 900 
    |  |  |  |  |  |  |  |  |  | 

    [ First MDL ][ Second MDL ][ Third MDL  ][ Fourth MDL ] 


    ↑    ↑  [ Packet ]       ↑ 
    |    |            | 
    |    |  ↑   ↑       | 
    |    |  |   |       | 
MdlChain   | DataOffset DataLength    End-of-MDL-chain 
        | 
       CurrentMdl 

Как мы надеемся, диаграмма иллюстрирует, фактическая полезная нагрузка пакета только распространяется через второй & третьего MDLs. И первые & четвертые MDL полностью игнорируются. Так что если вы хотите добавить данные в пакет, вам необходимо:

  1. Удалить все MDLs с конца цепочки MDL, где последние байтами буфера MDL не является частью логического буфера пакетов. (В приведенном выше примере удалите и третьи & четвертые MDL).
  2. Выделите новый буфер, который достаточно большой, чтобы хранить ваши данные, а также любую фактическую загрузку пакета, которую вы удалили с шага № 1 выше. (В примере вам нужно будет выделить дополнительные 100 байт, чтобы удержать первые 100 байт от третьего MDL.)
  3. Цепь вашего нового MDL до конца цепочки.
  4. Increment NET_BUFFER::DataLength.
  5. Дайте пакет NDIS.

Вот диаграмма того, что пакет будет выглядеть после завершения шага 3:

0  100 200 300 400 500 600 700 800 900 
    |  |  |  |  |  |  |  |  |  | 

    [ First MDL ][ Second MDL ][ Your MDL ] 


    ↑    ↑  [ Packet ]  ↑ 
    |    |       | 
    |    |  ↑   ↑  | 
    |    |  |   |  | 
MdlChain   | DataOffset DataLength | 
        |       | 
       CurrentMdl    End-of-MDL-chain 

Тогда после шага # 4:

0  100 200 300 400 500 600 700 800 900 
    |  |  |  |  |  |  |  |  |  | 

    [ First MDL ][ Second MDL ][ Your MDL ] 


    ↑    ↑  [ Packet   ] 
    |    | 
    |    |  ↑     ↑ 
    |    |  |     | 
MdlChain   | DataOffset   DataLength    
        |       | 
       CurrentMdl    End-of-MDL-chain 

Когда пакет завершен обратно к водителю , вам необходимо отменить сделанные ранее изменения:

  1. Decrement DataLength.
  2. Удалить добавленный MDL.
  3. Бесплатно добавленный MDL.
  4. Восстановите исходные MDL, которые вы удалили.
+0

спасибо jeff.Я делаю LWF-драйвер, в котором я должен добавить дополнительные байты (24 нечетных) и данные в конце текущего пакета при отправке и приеме вызовов. Является ли вышеупомянутый способ наиболее правильным и эффективным способом этого? – user2963521

+0

также как я могу безопасно скопировать содержимое последнего mdl в мой выделенный mdl? Должен ли RtlCopyMemory работать? – user2963521

+0

Это единственный безопасный способ добавления данных в конец пакета. Если вы находитесь в сговоре с минипортом, вы можете заставить его согласиться оставить 24 байта неиспользуемого пространства в конце последнего MDL. RtlCopyMemory в порядке, если вы сначала используете MmGetSystemAddressForMdlSafe. –