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
포인트를 거기에 4 MDLs과 MDL 체인. 이제 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은 모두 무시됩니다. 당신이 패킷에 데이터를 추가하려는 경우, 당신은 다음을 수행해야합니다
- 는 MDL의 버퍼의 마지막 바이트 논리 패킷 버퍼의 일부가 아닌 MDL 체인의 끝에서 모든 MDLs를 제거합니다. 위의 예에서 세 번째 MDL 인 두 번째 &을 모두 제거합니다.
- 위의 1 단계에서 삭제 한 실제 패킷 페이로드와 데이터를 저장할만큼 큰 새 버퍼를 할당하십시오. (이 예에서는 세 번째 MDL에서 처음 100 바이트를 보유하기 위해 추가 100 바이트를 할당해야합니다.)
- 새 MDL을 체인 끝에 연결하십시오.
- 증분
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
이전에 수정 한 사항을 실행 취소해야합니다.
- 감소
DataLength
.
- 추가 한 MDL을 제거하십시오.
- 추가 한 MDL을 해제하십시오.
- 제거한 원본 MDL을 복원하십시오.
감사합니다. jeff.내가 여분의 바이트 (24 홀수) 및 현재 패킷 끝에있는 데이터를 보내고받을 때 LWF 드라이버를 만들고 있습니다. 위에서 언급 한 방법이 그렇게하는 가장 정확하고 효율적인 방법입니까? – user2963521
어떻게 안전하게 마지막으로 mdl의 내용을 할당 된 mdl에 복사 할 수 있습니까? RtlCopyMemory가 작동해야합니까? – user2963521
패킷 끝에 데이터를 추가하는 유일한 방법입니다. 만약 당신이 미니 포트를 가지고 있다면, 마지막 MDL의 끝 부분에 24 바이트의 사용되지 않은 공간을 남겨 두는 것에 동의하게 할 수 있습니다. 먼저 MmGetSystemAddressForMdlSafe를 사용하면 RtlCopyMemory가 좋습니다. –