Фактическая полезная нагрузка пакета 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 полностью игнорируются. Так что если вы хотите добавить данные в пакет, вам необходимо:
- Удалить все MDLs с конца цепочки MDL, где последние байтами буфера MDL не является частью логического буфера пакетов. (В приведенном выше примере удалите и третьи & четвертые MDL).
- Выделите новый буфер, который достаточно большой, чтобы хранить ваши данные, а также любую фактическую загрузку пакета, которую вы удалили с шага № 1 выше. (В примере вам нужно будет выделить дополнительные 100 байт, чтобы удержать первые 100 байт от третьего MDL.)
- Цепь вашего нового MDL до конца цепочки.
- Increment
NET_BUFFER::DataLength
.
- Дайте пакет 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
Когда пакет завершен обратно к водителю , вам необходимо отменить сделанные ранее изменения:
- Decrement
DataLength
.
- Удалить добавленный MDL.
- Бесплатно добавленный MDL.
- Восстановите исходные MDL, которые вы удалили.
спасибо jeff.Я делаю LWF-драйвер, в котором я должен добавить дополнительные байты (24 нечетных) и данные в конце текущего пакета при отправке и приеме вызовов. Является ли вышеупомянутый способ наиболее правильным и эффективным способом этого? – user2963521
также как я могу безопасно скопировать содержимое последнего mdl в мой выделенный mdl? Должен ли RtlCopyMemory работать? – user2963521
Это единственный безопасный способ добавления данных в конец пакета. Если вы находитесь в сговоре с минипортом, вы можете заставить его согласиться оставить 24 байта неиспользуемого пространства в конце последнего MDL. RtlCopyMemory в порядке, если вы сначала используете MmGetSystemAddressForMdlSafe. –