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.

406 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991-1992 Microsoft Corporation
  3. Module Name:
  4. Examine.c
  5. Abstract:
  6. This module contains Remote Admin Protocol (RAP) routines. These routines
  7. are shared between XactSrv and RpcXlate.
  8. Author:
  9. David Treadwell (davidtr) 07-Jan-1991
  10. Environment:
  11. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. Revision History:
  14. 05-Mar-1991 JohnRo
  15. Converted from Xs (XactSrv) to Rap (Remote Admin Protocol) names.
  16. 15-Mar-1991 W-Shanku
  17. Additional character support; changes to make code neater.
  18. 14-Apr-1991 JohnRo
  19. Reduce recompiles.
  20. 15-May-1991 JohnRo
  21. Added first cut at native vs. RAP handling.
  22. Added support for REM_SEND_LENBUF for print APIs.
  23. 04-Jun-1991 JohnRo
  24. Made changes suggested by PC-LINT.
  25. 11-Jul-1991 JohnRo
  26. Support StructureAlignment parameter.
  27. 07-Oct-1991 JohnRo
  28. Made changes suggested by PC-LINT.
  29. 16-Aug-1992 JohnRo
  30. RAID 2920: Support UTC timezone in net code.
  31. Use PREFIX_ equates.
  32. --*/
  33. // These must be included first:
  34. #include <windef.h> // IN, LPDWORD, NULL, OPTIONAL, DWORD, etc.
  35. #include <lmcons.h> // NET_API_STATUS
  36. // These may be included in any order:
  37. #include <align.h> // ALIGN_WORD, etc.
  38. #include <netdebug.h> // NetpAssert().
  39. #include <prefix.h> // PREFIX_ equates.
  40. #include <rap.h> // My prototype, LPDESC.
  41. #include <remtypes.h> // REM_WORD, etc.
  42. VOID
  43. RapExamineDescriptor (
  44. IN LPDESC DescriptorString,
  45. IN LPDWORD ParmNum OPTIONAL,
  46. OUT LPDWORD StructureSize OPTIONAL,
  47. OUT LPDWORD LastPointerOffset OPTIONAL,
  48. OUT LPDWORD AuxDataCountOffset OPTIONAL,
  49. OUT LPDESC * ParmNumDescriptor OPTIONAL,
  50. OUT LPDWORD StructureAlignment OPTIONAL,
  51. IN RAP_TRANSMISSION_MODE TransmissionMode,
  52. IN BOOL Native
  53. )
  54. /*++
  55. Routine Description:
  56. Performs various examination functions on a descriptor string, including
  57. - finding the size of the fixed structure.
  58. - finding the last pointer to variable-length data in the structure.
  59. - finding the auxiliary descriptor character in the string.
  60. - finding the type of a given field in the descriptor.
  61. These functions traverse the descriptor string in a similar manner, and
  62. are thus grouped together, with wrappers for individual functions
  63. elsewhere.
  64. Arguments:
  65. DescriptorString - a string that describes a fixed-length structure.
  66. ParmNum - an optional pointer to a DWORD indicating the field within
  67. the descriptor to find.
  68. StructureSize - a pointer to a DWORD to receive the size, in bytes,
  69. of the structure.
  70. LastPointerOffset - a pointer to a DWORD to receive the last pointer
  71. to variable-length data in the structure. If there is no pointer
  72. in the structure, the DWORD receives the constant value
  73. NO_POINTER_IN_STRUCTURE.
  74. AuxDataCountOffset - an optional pointer to a DWORD to receive the offset
  75. of the auxiliary data structure count. This is set to
  76. NO_AUX_DATA if none is found.
  77. ParmNumDescriptor - an optional pointer to a LPDESC to receive a
  78. pointer to a specific field within the descriptor.
  79. StructureAlignment - an optional pointer to a DWORD to receive the
  80. alignment of this structure if it must be aligned and padded to appear
  81. in an array. (This will be set to 1 if no alignment is necessary.)
  82. Transmission Mode - Indicates whether this array is part of a response,
  83. a request, or both.
  84. Native - TRUE iff the descriptor defines a native structure. (This flag is
  85. used to decide whether or not to align fields.)
  86. Return Value:
  87. None.
  88. --*/
  89. {
  90. LPDESC s;
  91. DWORD field;
  92. DWORD size = 0;
  93. DWORD auxDataCountOffset = NO_AUX_DATA;
  94. DWORD lastPointerOffset = NO_POINTER_IN_STRUCTURE;
  95. LPDESC parmNumDescriptor = NULL;
  96. DWORD worstAlignmentSoFar = ALIGN_BYTE;
  97. #define UPDATE_WORST_ALIGNMENT(value) \
  98. if ( (value) > worstAlignmentSoFar) { \
  99. worstAlignmentSoFar = value; \
  100. }
  101. #define POINTER_SIZE (Native ? sizeof(PVOID) : sizeof(DWORD))
  102. //
  103. // Check for wierdness that could break null pointer handling.
  104. //
  105. NetpAssert(sizeof(LPSTR) == sizeof(LPVOID));
  106. //
  107. // Walk through the descriptor string, updating the length count
  108. // for each field described.
  109. //
  110. field = 1;
  111. for ( s = DescriptorString; *s != '\0'; field++ ) {
  112. if (( ParmNum != NULL ) && ( *ParmNum == field )) {
  113. parmNumDescriptor = s;
  114. }
  115. switch ( *(s++) ) {
  116. case REM_RCV_BYTE_PTR:
  117. if (TransmissionMode == Request) {
  118. //
  119. // These aren't sent as part of request. Just skip past any
  120. // array size numeric characters in descriptor.
  121. //
  122. (void) RapAsciiToDecimal( &s );
  123. break;
  124. }
  125. /* FALLTHROUGH */
  126. case REM_BYTE:
  127. //
  128. // A byte or array of bytes.
  129. //
  130. size += sizeof(CHAR) * RapDescArrayLength( s );
  131. UPDATE_WORST_ALIGNMENT( ALIGN_BYTE );
  132. break;
  133. case REM_BYTE_PTR:
  134. case REM_FILL_BYTES:
  135. //
  136. // A pointer to a byte or array of bytes.
  137. //
  138. if (TransmissionMode == Response ) {
  139. //
  140. // In a response (Xactsrv-style) context, this type
  141. // is allocated enough room for the pointer. Also skip
  142. // over any array size numeric characters.
  143. //
  144. size = RapPossiblyAlignCount(size, ALIGN_LPBYTE, Native);
  145. UPDATE_WORST_ALIGNMENT( ALIGN_LPBYTE );
  146. lastPointerOffset = size;
  147. size += POINTER_SIZE;
  148. } else {
  149. size += POINTER_SIZE;
  150. UPDATE_WORST_ALIGNMENT( ALIGN_BYTE );
  151. }
  152. //
  153. // must move the descriptor past any arraylength info
  154. //
  155. (void) RapAsciiToDecimal( &s );
  156. break;
  157. case REM_RCV_WORD_PTR :
  158. case REM_SEND_BUF_LEN :
  159. if (TransmissionMode == Request) {
  160. //
  161. // These aren't sent as part of request. Just skip past any
  162. // array size numeric characters in descriptor.
  163. //
  164. (void) RapAsciiToDecimal( &s );
  165. break;
  166. }
  167. /* FALLTHROUGH */
  168. case REM_WORD:
  169. case REM_PARMNUM:
  170. case REM_RCV_BUF_LEN:
  171. case REM_ENTRIES_READ:
  172. //
  173. // A word or array of words.
  174. //
  175. size = RapPossiblyAlignCount(size, ALIGN_WORD, Native);
  176. size += sizeof(WORD) * RapDescArrayLength( s );
  177. UPDATE_WORST_ALIGNMENT( ALIGN_WORD );
  178. break;
  179. case REM_RCV_DWORD_PTR :
  180. if (TransmissionMode == Request) {
  181. //
  182. // These aren't sent as part of request. Just skip past any
  183. // array size numeric characters in descriptor.
  184. //
  185. (void) RapAsciiToDecimal( &s );
  186. break;
  187. }
  188. /* FALLTHROUGH */
  189. case REM_DWORD:
  190. case REM_SIGNED_DWORD:
  191. //
  192. // A doubleword or array of doublewords.
  193. //
  194. size = RapPossiblyAlignCount(size, ALIGN_DWORD, Native);
  195. size += sizeof(DWORD) * RapDescArrayLength( s );
  196. UPDATE_WORST_ALIGNMENT( ALIGN_DWORD );
  197. break;
  198. case REM_ASCIZ: // ptr to ASCIIZ string
  199. case REM_ASCIZ_TRUNCATABLE: // ptr to truncatable ASCIZ string
  200. size = RapPossiblyAlignCount(size, ALIGN_LPSTR, Native);
  201. lastPointerOffset = size;
  202. size += POINTER_SIZE;
  203. UPDATE_WORST_ALIGNMENT( ALIGN_LPBYTE );
  204. (void) RapDescStringLength( s );
  205. break;
  206. case REM_SEND_BUF_PTR: // ptr to send buffer
  207. case REM_SEND_LENBUF: // FAR ptr to send buffer w/ len.
  208. if (TransmissionMode == Request) {
  209. //
  210. // These aren't sent as part of request.
  211. //
  212. break;
  213. }
  214. /* FALLTHROUGH */
  215. case REM_RCV_BUF_PTR: // ptr to receive buffer
  216. size = RapPossiblyAlignCount(size, ALIGN_LPBYTE, Native);
  217. lastPointerOffset = size;
  218. /* FALLTHROUGH */
  219. case REM_NULL_PTR: // null ptr
  220. size = RapPossiblyAlignCount(size, ALIGN_LPSTR, Native);
  221. size += POINTER_SIZE;
  222. UPDATE_WORST_ALIGNMENT( ALIGN_LPBYTE );
  223. break;
  224. case REM_AUX_NUM: // 16-bit aux. data count
  225. size = RapPossiblyAlignCount(size, ALIGN_WORD, Native);
  226. auxDataCountOffset = size;
  227. size += sizeof(WORD);
  228. UPDATE_WORST_ALIGNMENT( ALIGN_WORD );
  229. break;
  230. case REM_AUX_NUM_DWORD: // 32-bit aux. data count
  231. size = RapPossiblyAlignCount(size, ALIGN_DWORD, Native);
  232. auxDataCountOffset = size;
  233. size += sizeof(DWORD);
  234. UPDATE_WORST_ALIGNMENT( ALIGN_DWORD );
  235. break;
  236. case REM_IGNORE :
  237. case REM_UNSUPPORTED_FIELD :
  238. //
  239. // A placeholder for pad bytes. It represents no space in the
  240. // structure.
  241. //
  242. break;
  243. case REM_EPOCH_TIME_GMT: /*FALLTHROUGH*/
  244. case REM_EPOCH_TIME_LOCAL:
  245. //
  246. // A time in seconds since 1970. 32-bits, unsigned.
  247. //
  248. size = RapPossiblyAlignCount(size, ALIGN_DWORD, Native);
  249. size += sizeof(DWORD);
  250. UPDATE_WORST_ALIGNMENT( ALIGN_DWORD );
  251. break;
  252. default:
  253. // !!!!
  254. NetpKdPrint(( PREFIX_NETRAP
  255. "RapExamineDescriptor: unsupported character: "
  256. FORMAT_DESC_CHAR " at " FORMAT_LPVOID ".\n",
  257. *(s - 1), s - 1 ));
  258. NetpAssert(FALSE);
  259. }
  260. }
  261. //
  262. // Set up return information as appropriate.
  263. //
  264. if ( StructureSize != NULL ) {
  265. *StructureSize = size;
  266. }
  267. if ( LastPointerOffset != NULL ) {
  268. *LastPointerOffset = lastPointerOffset;
  269. }
  270. if ( AuxDataCountOffset != NULL ) {
  271. *AuxDataCountOffset = auxDataCountOffset;
  272. }
  273. if ( ParmNumDescriptor != NULL ) {
  274. *ParmNumDescriptor = parmNumDescriptor;
  275. }
  276. if ( StructureAlignment != NULL ) {
  277. *StructureAlignment = worstAlignmentSoFar;
  278. }
  279. return;
  280. } // RapExamineDescriptor