Fragmented NET_BUFFER_LIST Structures
An NDIS driver can create a fragmented NET_BUFFER_LIST structure from an existing NET_BUFFER_LIST structure. The fragmented structure references a set of NET_BUFFER structures that reference the original data; however, the data is divided into units that do not exceed a maximum size. Drivers can use this type of structure to efficiently break up large buffers into smaller buffers.
The following figure shows the relationship between a parent NET_BUFFER_LIST structure and a fragmented child.
The preceding figure contains a parent NET_BUFFER_LIST structure and a child structure that was derived from that parent. The parent structure has one NET_BUFFER_LIST_CONTEXT structure and one NET_BUFFER structure with MDLs attached. The parent structure's parent pointer is NULL indicating that it is not a derived structure.
The child NET_BUFFER_LIST structure has three NET_BUFFER structures with MDLs attached. The child NET_BUFFER_LIST structure has a pointer to the parent structure. The NULL where a NET_BUFFER_LIST_CONTEXT structure pointer would be indicates that the child has no NET_BUFFER_LIST_CONTEXT structure.
NDIS drivers call the NdisAllocateFragmentNetBufferList function to create a new fragmented NET_BUFFER_LIST structure that is based on the data in an existing NET_BUFFER_LIST structure. NDIS allocates new NET_BUFFER structures and MDLs for the fragmented NET_BUFFER_LIST structure. NDIS does not allocate a NET_BUFFER_LIST_CONTEXT structure for the fragmented structure. The fragment NET_BUFFER structures and MDLs describe the same data as does the parent structure. The data is not copied.
NdisAllocateFragmentNetBufferList creates the fragments, starting from the beginning of the used data space in each parent NET_BUFFER structure and offset by the value specified in the StartOffset parameter.
NdisAllocateFragmentNetBufferList divides the used data space in each source NET_BUFFER structure into fragments. The length of the used data space of each fragment is less than or equal to the value specified in the MaximumLength parameter. The used data space of the last fragment can be less than MaximumLength . The data offset of the new NET_BUFFER structures is retreated by the number of bytes specified in the DataOffsetDelta parameter.
If there are multiple NET_BUFFER structures in the parent NET_BUFFER_LIST structure (not shown in the illustration) the fragmenting process for each NET_BUFFER structure is the same as for a single structure. For example, if the last piece of data in any parent NET_BUFFER structure is smaller than the maximum size, NDIS does not combine such data with the data at the start of the next NET_BUFFER structure.
NDIS drivers call the NdisFreeFragmentNetBufferList function to free a NET_BUFFER_LIST structure and all associated NET_BUFFER structures and MDL chains that were previously allocated by calling NdisAllocateFragmentNetBufferList.