107 lines
2.8 KiB
C
107 lines
2.8 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1997, Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
edithlp.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module contains helper-declarations for the NAT's built-in editors.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Abolade Gbadegesin (t-abolag) 25-Aug-1997
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef _NAT_EDITHLP_H_
|
||
|
#define _NAT_EDITHLP_H_
|
||
|
|
||
|
|
||
|
//
|
||
|
// Macro: COPY_FROM_BUFFER
|
||
|
//
|
||
|
// This macro copies from a buffer-chain to a flat buffer.
|
||
|
//
|
||
|
|
||
|
#define \
|
||
|
COPY_FROM_BUFFER( \
|
||
|
Destination, \
|
||
|
Source, \
|
||
|
Length, \
|
||
|
Offset \
|
||
|
) \
|
||
|
{ \
|
||
|
PUCHAR _Destination = Destination; \
|
||
|
ULONG _Length = Length; \
|
||
|
LONG _Offset = Offset; \
|
||
|
IPRcvBuf* _Source = Source; \
|
||
|
while ((LONG)_Source->ipr_size < _Offset) { \
|
||
|
_Offset -= _Source->ipr_size; \
|
||
|
_Source = _Source->ipr_next; \
|
||
|
} \
|
||
|
while (_Length) { \
|
||
|
ULONG Bytes = min(_Length, _Source->ipr_size-_Offset); \
|
||
|
RtlCopyMemory(_Destination, _Source->ipr_buffer+_Offset, Bytes);\
|
||
|
_Length -= Bytes; \
|
||
|
_Destination += Bytes; \
|
||
|
_Source = _Source->ipr_next; \
|
||
|
_Offset = 0; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Macro: FIND_HEADER_FIELD
|
||
|
//
|
||
|
// This macro initializes a pseudo header's 'Field' member with the address
|
||
|
// in a buffer chain of the corresponding application-header field.
|
||
|
// It is assumed that each field of the application-header is aligned
|
||
|
// on the natural boundary for its width (e.g. 32-bit fields aligned
|
||
|
// on 32-bit boundaries).
|
||
|
//
|
||
|
// 'RecvBuffer' gives the first buffer in the chain containing the field,
|
||
|
// and 'DataOffsetp' points to the (negative) offset into 'RecvBuffer'
|
||
|
// of the header. This offset would be negative if the header is spread
|
||
|
// over multiple buffers and 'RecvBuffer' is one of the later buffers.
|
||
|
//
|
||
|
// The macro advances through the buffer chain until it finds the buffer
|
||
|
// containing the field (using FIELD_OFFSET). It then initializes the
|
||
|
// pseudo-header's field pointer with the position of the field
|
||
|
// (i.e. 'Header->Field = &(field in buffer-chain)).
|
||
|
//
|
||
|
// Given that it walks the buffer chain, the macro thus requires that
|
||
|
// the pseudo-header's field pointers be initialized in-order,
|
||
|
// since an earlier field cannot be found in the chain after we have
|
||
|
// passed the buffer containing the latter while searching for a later field.
|
||
|
//
|
||
|
|
||
|
#define \
|
||
|
FIND_HEADER_FIELD( \
|
||
|
RecvBuffer, \
|
||
|
DataOffsetp, \
|
||
|
Header, \
|
||
|
Field, \
|
||
|
HeaderType, \
|
||
|
FieldType \
|
||
|
) \
|
||
|
while ((LONG)(RecvBuffer)->ipr_size < \
|
||
|
*(DataOffsetp) + FIELD_OFFSET(HeaderType, Field) \
|
||
|
) { \
|
||
|
*(DataOffsetp) -= (RecvBuffer)->ipr_size; \
|
||
|
(RecvBuffer) = (RecvBuffer)->ipr_next; \
|
||
|
if (!(RecvBuffer)) { break; } \
|
||
|
} \
|
||
|
if (RecvBuffer) { \
|
||
|
(Header)->Field = \
|
||
|
(FieldType)((RecvBuffer)->ipr_buffer + *(DataOffsetp) + \
|
||
|
FIELD_OFFSET(HeaderType, Field)); \
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif // _NAT_EDITHLP_H_
|