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.

403 lines
12 KiB

  1. /*++
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. RcvConv.c
  5. Abstract:
  6. This module contains support routines for the RpcXlate code.
  7. Author:
  8. John Rogers (JohnRo) 01-Apr-1991 (NT version)
  9. (unknown Microsoft programmer) (original LM 2.x version)
  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. (various NBU people)
  15. LanMan 2.x code
  16. 01-Apr-1991 JohnRo
  17. Created portable version from LanMan 2.x sources.
  18. 13-Apr-1991 JohnRo
  19. Added some (quiet) debug output.
  20. Reduced recompile hits from header files.
  21. 03-May-1991 JohnRo
  22. Don't use NET_API_FUNCTION for non-APIs.
  23. 11-May-1991 JohnRo
  24. Fixed string ptr bug in RxpSetPointer(). Added assertions and.
  25. debug output.
  26. 13-May-1991 JohnRo
  27. Use DESC_CHAR typedef. Print num_aux for debugging.
  28. 17-May-1991 JohnRo
  29. Handle array of aux structs.
  30. 19-May-1991 JohnRo
  31. Make LINT-suggested changes (use DBGSTATIC).
  32. 20-May-1991 JohnRo
  33. Cast expression in RxpSetPointer more carefully.
  34. 02-Jun-1991 JohnRo
  35. Allow use on big-endian machines. (PC-LINT discovered a portability
  36. problem.)
  37. 17-Jul-1991 JohnRo
  38. Extracted RxpDebug.h from Rxp.h.
  39. 10-Sep-1991 JohnRo
  40. Made changes suggested by PC-LINT.
  41. 13-Nov-1991 JohnRo
  42. RAID 4408: Fixed MIPS alignment problems.
  43. 21-Nov-1991 JohnRo
  44. Removed NT dependencies to reduce recompiles.
  45. 07-May-1993 JohnRo
  46. RAID 6167: avoid access violation or assert with WFW print server.
  47. Corrected copyright and authorship.
  48. Use NetpKdPrint() where possible.
  49. Use PREFIX_ equates.
  50. --*/
  51. // These must be included first:
  52. #include <windef.h> // IN, DWORD, VOID, etc.
  53. #include <rxp.h> // Private header file.
  54. // These may be included in any order:
  55. #include <netdebug.h> // NetpKdPrint(), FORMAT_ equates, etc.
  56. #include <netlib.h> // NetpPointerPlusSomeBytes(), etc.
  57. #include <prefix.h> // PREFIX_ equates.
  58. #include <remtypes.h> // REM_BYTE, etc.
  59. #include <rxpdebug.h> // IF_DEBUG().
  60. #include <rapgtpt.h> // RapGetWord(), etc.
  61. #include <winbase.h>
  62. // Inputs to this function haven't been converted to 32-bit yet.
  63. #define INPUTS_ARE_NATIVE FALSE
  64. DBGSTATIC NET_API_STATUS
  65. RxpSetPointer(
  66. IN LPBYTE RcvBufferStart,
  67. IN DWORD RcvDataSize,
  68. IN OUT LPBYTE * RcvPointerPointer,
  69. IN DWORD Converter
  70. );
  71. DWORD
  72. RxpGetFieldSizeDl(
  73. IN LPDESC TypePointer,
  74. IN OUT LPDESC * TypePointerAddress,
  75. IN RAP_TRANSMISSION_MODE TransmissionMode
  76. );
  77. NET_API_STATUS
  78. RxpReceiveBufferConvert(
  79. IN OUT LPVOID RcvDataPointer,
  80. IN DWORD RcvDataSize,
  81. IN DWORD Converter,
  82. IN DWORD NumberOfStructures,
  83. IN LPDESC DataDescriptorString,
  84. IN LPDESC AuxDescriptorString,
  85. OUT LPDWORD NumAuxStructs
  86. )
  87. /*++
  88. Routine Description:
  89. RxpReceiveBufferConvert corrects all pointer fields present in a receive
  90. buffer. All pointers in the receive buffer are returned from the API
  91. worker as pointers into the buffer position given to the API on the API
  92. worker's station.
  93. This routine steps through the receive buffer and calls RxpSetPointer to
  94. perform the pointer conversions. On exit, all pointers (except NULL
  95. pointers) in receive buffer converted to local format.
  96. Arguments:
  97. RcvDataPointer - Pointer to receive buffer. This will be updated in place.
  98. RcvDataSize - Length of the data area that RcvDataPointer points to.
  99. Converter - Converter word from API worker.
  100. NumberOfStructures - Entries read parm (or 1 for GetInfo).
  101. DataDescriptorString - Descriptor string for data format.
  102. AuxDescriptorString - Descriptor string for aux format.
  103. NumAuxStructs - Points to a DWORD which will be set with the number
  104. of entries in the aux array. (This will be set to 0 if none.)
  105. Return Value:
  106. NET_API_STATUS (NO_ERROR or ERROR_INVALID_PARAMETER).
  107. --*/
  108. {
  109. NET_API_STATUS ApiStatus;
  110. DESC_CHAR c;
  111. DWORD i,j;
  112. LPBYTE data_ptr;
  113. LPBYTE end_of_data;
  114. LPDESC l_data;
  115. LPDESC l_aux;
  116. NetpAssert( RcvDataPointer != NULL );
  117. NetpAssert( RcvDataSize != 0 );
  118. NetpAssert( NumAuxStructs != NULL );
  119. data_ptr = RcvDataPointer; /* start of rcv data buffer */
  120. end_of_data = NetpPointerPlusSomeBytes( RcvDataPointer, RcvDataSize );
  121. IF_DEBUG(RCVCONV) {
  122. NetpKdPrint(( PREFIX_NETAPI
  123. "RxpReceiveBufferConvert: starting, Converter="
  124. FORMAT_HEX_DWORD "...\n", Converter ));
  125. }
  126. *NumAuxStructs = 0;
  127. for (i = 0; i < NumberOfStructures; i++) { /* For each entries read */
  128. for (l_data=DataDescriptorString; (c = *l_data) != '\0'; l_data++) {
  129. if (c == REM_AUX_NUM) {
  130. *NumAuxStructs = RapGetWord( data_ptr, INPUTS_ARE_NATIVE );
  131. IF_DEBUG(RCVCONV) {
  132. NetpKdPrint(( PREFIX_NETAPI
  133. "RxpReceiveBufferConvert: num aux is now "
  134. FORMAT_DWORD ".\n", *NumAuxStructs ));
  135. }
  136. }
  137. if (RapIsPointer(c)) { /* If field is pointer */
  138. ApiStatus = RxpSetPointer(
  139. RcvDataPointer,
  140. RcvDataSize,
  141. (LPBYTE *) data_ptr,
  142. Converter);
  143. if (ApiStatus != NO_ERROR) {
  144. goto Cleanup;
  145. }
  146. }
  147. data_ptr += RxpGetFieldSizeDl( l_data, &l_data, Both);
  148. if (data_ptr > end_of_data) {
  149. ApiStatus = ERROR_INVALID_PARAMETER;
  150. goto Cleanup;
  151. }
  152. }
  153. for (j = 0; j < *NumAuxStructs; j++) { /* For each aux struct */
  154. for (l_aux = AuxDescriptorString; (c = *l_aux) != '\0'; l_aux++) {
  155. if (RapIsPointer(c)) { /* If field is pointer */
  156. ApiStatus = RxpSetPointer(
  157. RcvDataPointer,
  158. RcvDataSize,
  159. (LPBYTE *) data_ptr,
  160. Converter);
  161. if (ApiStatus != NO_ERROR) {
  162. goto Cleanup;
  163. }
  164. }
  165. data_ptr += RxpGetFieldSizeDl( l_aux, &l_aux, Both);
  166. if (data_ptr > end_of_data) {
  167. ApiStatus = ERROR_INVALID_PARAMETER;
  168. goto Cleanup;
  169. }
  170. }
  171. }
  172. }
  173. ApiStatus = NO_ERROR;
  174. Cleanup:
  175. IF_DEBUG(RCVCONV) {
  176. NetpKdPrint(( PREFIX_NETAPI
  177. "RxpReceiveBufferConvert: done, status="
  178. FORMAT_API_STATUS ".\n", ApiStatus ));
  179. }
  180. return (ApiStatus);
  181. } // RxpReceiveBufferConvert
  182. DBGSTATIC NET_API_STATUS
  183. RxpSetPointer(
  184. IN LPBYTE RcvBufferStart,
  185. IN DWORD RcvDataSize,
  186. IN OUT LPBYTE * RcvPointerPointer,
  187. IN DWORD Converter
  188. )
  189. /*++
  190. Routine Description:
  191. RxpSetPointer corrects a pointer field in the rcv buffer. All pointers in
  192. the receive buffer are returned from the API worker as
  193. pointers into the buffer position given to the API on the API worker's
  194. station. The pointer will be set to:
  195. addr(rcv buffer) + pointer - converter word.
  196. This routine performs the above conversion on a rcv buffer pointer. On
  197. exit, the pointer (unless NULL) in receive buffer will be converted to
  198. local format.
  199. Arguments:
  200. RcvBufferStart - pointer to start of receive buffer.
  201. RcvDataSize - Length of the data area that RcvBufferStart points to.
  202. RcvPointerPointer - pointer to pointer to convert.
  203. Converter - Converter word from API worker.
  204. Return Value:
  205. NET_API_STATUS (NO_ERROR or ERROR_INVALID_PARAMETER).
  206. --*/
  207. {
  208. DWORD BufferOffsetToData; // offset within buffer
  209. DWORD OldOffset; // offset within segment
  210. NetpAssert( ! RapValueWouldBeTruncated(Converter) );
  211. NetpAssert(RcvBufferStart != NULL);
  212. NetpAssert(RcvPointerPointer != NULL);
  213. NetpAssert(
  214. ((LPBYTE)(LPVOID)RcvPointerPointer) // First byte of pointer
  215. >= RcvBufferStart ); // can't be before buffer.
  216. NetpAssert(
  217. (((LPBYTE)(LPVOID)RcvPointerPointer) + sizeof(NETPTR)-1)
  218. // Last byte of pointer
  219. <= (RcvBufferStart+RcvDataSize) ); // can't be after buffer.
  220. //
  221. // Null pointer is (segment:offset) 0:0, which just appears as 4 bytes
  222. // of zeros. Check for that here.
  223. //
  224. if (RapGetDword( RcvPointerPointer, INPUTS_ARE_NATIVE ) == 0) {
  225. return (NO_ERROR);
  226. }
  227. // OK, this gets fun. What's in the buffer is a 2 byte offset followed
  228. // by a 2 byte (useless) segment number. So, we cast to LPWORD to get
  229. // the offset. We'll adjust the offset by the converter to
  230. OldOffset = (DWORD) RapGetWord( RcvPointerPointer, INPUTS_ARE_NATIVE );
  231. IF_DEBUG(RCVCONV) {
  232. NetpKdPrint(( PREFIX_NETAPI
  233. "RxpSetPointer: OldOffset is " FORMAT_HEX_DWORD
  234. ".\n", OldOffset ));
  235. }
  236. BufferOffsetToData = (DWORD) (( OldOffset - (WORD) Converter ) & 0xffff);
  237. IF_DEBUG(RCVCONV) {
  238. NetpKdPrint(( PREFIX_NETAPI
  239. "RxpSetPointer: BufferOffsetToData is " FORMAT_HEX_DWORD
  240. ".\n", BufferOffsetToData ));
  241. }
  242. //
  243. // Make sure that what we point to is still in the buffer.
  244. //
  245. if (BufferOffsetToData >= RcvDataSize) {
  246. NetpKdPrint(( PREFIX_NETAPI
  247. "RxpSetPointer: *** BUFFER OFFSET TOO LARGE *** "
  248. "(conv=" FORMAT_HEX_DWORD ", "
  249. "offset=" FORMAT_HEX_DWORD ", "
  250. "size=" FORMAT_HEX_DWORD ").\n",
  251. Converter, BufferOffsetToData, RcvDataSize ));
  252. return (ERROR_INVALID_PARAMETER);
  253. }
  254. #if defined (_WIN64)
  255. //
  256. // Store only the 32-bit buffer offset. Later, RapGetPointer() will
  257. // add the buffer start address.
  258. //
  259. RapPutDword( RcvPointerPointer,
  260. BufferOffsetToData,
  261. INPUTS_ARE_NATIVE );
  262. #else
  263. //
  264. // For 32-bit, the pointers are stored directly, and will be retrieved
  265. // directly from RapGetPointer().
  266. //
  267. RapPutDword(RcvPointerPointer,
  268. NetpPointerPlusSomeBytes( RcvBufferStart, BufferOffsetToData ),
  269. INPUTS_ARE_NATIVE);
  270. #endif
  271. return (NO_ERROR);
  272. } // RxpSetPointer
  273. DWORD
  274. RxpGetFieldSizeDl(
  275. IN LPDESC TypePointer,
  276. IN OUT LPDESC * TypePointerAddress,
  277. IN RAP_TRANSMISSION_MODE TransmissionMode
  278. )
  279. /*++
  280. Routine Description:
  281. This is a wrapper for RapGetFieldSize().
  282. The pointer fields in the downlevel buffers that this module deals with
  283. are always 32 bits in width. RapGetFieldSize(<somepointertype>) will
  284. return the size of a native pointer, which is not necessarily 32 bits
  285. in width.
  286. This wrapper overrides the result of RapGetFieldSize() with sizeof(DWORD)
  287. for all pointer types.
  288. See the description of RapGetFieldSize() for additional info.
  289. --*/
  290. {
  291. DWORD fieldSize;
  292. BOOL isPointer;
  293. fieldSize = RapGetFieldSize( TypePointer,
  294. TypePointerAddress,
  295. TransmissionMode );
  296. #if defined (_WIN64)
  297. isPointer = RapIsPointer(*TypePointer);
  298. if (isPointer != FALSE){
  299. fieldSize = sizeof(DWORD);
  300. }
  301. #endif
  302. return fieldSize;
  303. } // RxpGetFieldSizeDl