Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
2.8 KiB

  1. /*++
  2. Copyright (c) 1997, Microsoft Corporation
  3. Module Name:
  4. edithlp.h
  5. Abstract:
  6. This module contains helper-declarations for the NAT's built-in editors.
  7. Author:
  8. Abolade Gbadegesin (t-abolag) 25-Aug-1997
  9. Revision History:
  10. --*/
  11. #ifndef _NAT_EDITHLP_H_
  12. #define _NAT_EDITHLP_H_
  13. //
  14. // Macro: COPY_FROM_BUFFER
  15. //
  16. // This macro copies from a buffer-chain to a flat buffer.
  17. //
  18. #define \
  19. COPY_FROM_BUFFER( \
  20. Destination, \
  21. Source, \
  22. Length, \
  23. Offset \
  24. ) \
  25. { \
  26. PUCHAR _Destination = Destination; \
  27. ULONG _Length = Length; \
  28. LONG _Offset = Offset; \
  29. IPRcvBuf* _Source = Source; \
  30. while ((LONG)_Source->ipr_size < _Offset) { \
  31. _Offset -= _Source->ipr_size; \
  32. _Source = _Source->ipr_next; \
  33. } \
  34. while (_Length) { \
  35. ULONG Bytes = min(_Length, _Source->ipr_size-_Offset); \
  36. RtlCopyMemory(_Destination, _Source->ipr_buffer+_Offset, Bytes);\
  37. _Length -= Bytes; \
  38. _Destination += Bytes; \
  39. _Source = _Source->ipr_next; \
  40. _Offset = 0; \
  41. } \
  42. }
  43. //
  44. // Macro: FIND_HEADER_FIELD
  45. //
  46. // This macro initializes a pseudo header's 'Field' member with the address
  47. // in a buffer chain of the corresponding application-header field.
  48. // It is assumed that each field of the application-header is aligned
  49. // on the natural boundary for its width (e.g. 32-bit fields aligned
  50. // on 32-bit boundaries).
  51. //
  52. // 'RecvBuffer' gives the first buffer in the chain containing the field,
  53. // and 'DataOffsetp' points to the (negative) offset into 'RecvBuffer'
  54. // of the header. This offset would be negative if the header is spread
  55. // over multiple buffers and 'RecvBuffer' is one of the later buffers.
  56. //
  57. // The macro advances through the buffer chain until it finds the buffer
  58. // containing the field (using FIELD_OFFSET). It then initializes the
  59. // pseudo-header's field pointer with the position of the field
  60. // (i.e. 'Header->Field = &(field in buffer-chain)).
  61. //
  62. // Given that it walks the buffer chain, the macro thus requires that
  63. // the pseudo-header's field pointers be initialized in-order,
  64. // since an earlier field cannot be found in the chain after we have
  65. // passed the buffer containing the latter while searching for a later field.
  66. //
  67. #define \
  68. FIND_HEADER_FIELD( \
  69. RecvBuffer, \
  70. DataOffsetp, \
  71. Header, \
  72. Field, \
  73. HeaderType, \
  74. FieldType \
  75. ) \
  76. while ((LONG)(RecvBuffer)->ipr_size < \
  77. *(DataOffsetp) + FIELD_OFFSET(HeaderType, Field) \
  78. ) { \
  79. *(DataOffsetp) -= (RecvBuffer)->ipr_size; \
  80. (RecvBuffer) = (RecvBuffer)->ipr_next; \
  81. if (!(RecvBuffer)) { break; } \
  82. } \
  83. if (RecvBuffer) { \
  84. (Header)->Field = \
  85. (FieldType)((RecvBuffer)->ipr_buffer + *(DataOffsetp) + \
  86. FIELD_OFFSET(HeaderType, Field)); \
  87. }
  88. #endif // _NAT_EDITHLP_H_