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.

1443 lines
52 KiB

  1. /*++
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. ConvArgs.c
  5. Abstract:
  6. This module just contains RxpConvertArgs, which is a "captive" subroutine
  7. of RxRemoteApi.
  8. Author:
  9. John Rogers (JohnRo) and a cast of thousands.
  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. 01-Apr-1991 JohnRo
  15. Created portable LanMan (NT) version from LanMan 2.x.
  16. 03-May-1991 JohnRo
  17. Clarify that RcvData items are application's, and are 32-bit format.
  18. Fixed bug where aux data caused null pointer fault.
  19. Fixed total avail bytes count bug.
  20. RcvDataPtrPtr and RcvDataPresent are redundant.
  21. More assertion checking.
  22. Quiet debug output.
  23. Reduced recompile hits from header files.
  24. 14-May-1991 JohnRo
  25. Need different kinds of data and aux descriptors.
  26. Use FORMAT_LPVOID instead of FORMAT_POINTER (max portability).
  27. 05-Jun-1991 JohnRo
  28. Call RapConvertSingleEntry on send data (for setinfo APIs).
  29. Caller needs SendDataPtr and SendDataSize.
  30. Don't set StructSize too small (also, it's really FixedStructSize16).
  31. Show status when various things fail.
  32. Use PARMNUM_ALL equate.
  33. Changed to use CliffV's naming conventions (size=byte count).
  34. Return better error codes.
  35. 13-Jun-1991 JohnRo
  36. Must call RxpPackSendBuffer after all. (This fixes server set info
  37. for level 102.) Need DataDesc16 and AuxDesc16 for that purpose.
  38. Also, RxpConvertSingleEntry needs to set ptrs (not offsets) for
  39. use by RxpPackSendBuffer.
  40. 15-Jul-1991 JohnRo
  41. Changed RxpConvertDataStructures to allow ERROR_MORE_DATA, e.g. for
  42. print APIs.
  43. 17-Jul-1991 JohnRo
  44. Extracted RxpDebug.h from Rxp.h.
  45. 18-Jul-1991 RFirth
  46. SetInfo calls pass in 2 parmnums welded into a single DWORD - parmnum
  47. proper (which gets transmitted to down-level server) and field-index
  48. which RapParmNumDescriptor uses to get the type and size of the field
  49. that ParmNum indicates
  50. 15-Aug-1991 JohnRo
  51. PC-LINT found a bug calling RxpAuxDataCount(). Changed tabs to spaces.
  52. 19-Aug-1991 rfirth
  53. Added Flags parameter
  54. 30-Sep-1991 JohnRo
  55. Handle REM_FILL_BYTES correctly so RxNetServiceInstall() works.
  56. Provide debug output indicating cause of ERROR_INVALID_PARAMETER.
  57. Handle possible UNICODE (LPTSTR) for REM_ASCIZ.
  58. Allow descriptors to be UNICODE someday.
  59. DBG is always defined.
  60. 21-Nov-1991 JohnRo
  61. Removed NT dependencies to reduce recompiles.
  62. 31-Mar-1992 JohnRo
  63. Prevent too large size requests.
  64. 10-Dec-1992 JohnRo
  65. Made changes suggested by PC-LINT 5.0
  66. 18-May-1993 JohnRo
  67. DosPrintQGetInfoW underestimates number of bytes needed.
  68. Made more changes suggested by PC-LINT 5.0
  69. 27-May-1993 JimKel and JohnRo
  70. RAID 11758: Wrong error code for DosPrint APIs with NULL buffer pointer.
  71. --*/
  72. // These must be included first:
  73. #include <rxp.h> // RpcXlate private header file.
  74. // These may be included in any order:
  75. #include <limits.h> // CHAR_BIT.
  76. #include <lmerr.h> // NERR_ and ERROR_ equates.
  77. #include <netdebug.h> // NetpKdPrint(()), FORMAT_ equates, etc.
  78. #include <netlib.h> // NetpMoveMemory(), etc.
  79. #include <prefix.h> // PREFIX_ equates.
  80. #include <remtypes.h> // REM_BYTE, etc.
  81. #include <rxpdebug.h> // IF_DEBUG().
  82. #include <smbgtpt.h> // SmbPutUshort().
  83. #include <tstring.h> // NetpCopy routines, STRLEN().
  84. //
  85. // replace this with a call to RxpFieldSize, currently in setfield.c
  86. //
  87. DBGSTATIC
  88. DWORD
  89. RxpGetFieldSize(
  90. IN LPBYTE Field,
  91. IN LPDESC FieldDesc
  92. );
  93. DBGSTATIC
  94. LPDESC
  95. RxpGetSetInfoDescriptor(
  96. IN LPDESC Descriptor,
  97. IN DWORD FieldIndex,
  98. IN BOOL Is32BitDesc
  99. );
  100. NET_API_STATUS
  101. RxpConvertArgs(
  102. IN LPDESC ParmDescriptorString,
  103. IN LPDESC DataDesc16 OPTIONAL,
  104. IN LPDESC DataDesc32 OPTIONAL,
  105. IN LPDESC DataDescSmb OPTIONAL,
  106. IN LPDESC AuxDesc16 OPTIONAL,
  107. IN LPDESC AuxDesc32 OPTIONAL,
  108. IN LPDESC AuxDescSmb OPTIONAL,
  109. IN DWORD MaximumInputBlockSize,
  110. IN DWORD MaximumOutputBlockSize,
  111. IN OUT LPDWORD CurrentInputBlockSizePtr,
  112. IN OUT LPDWORD CurrentOutputBlockSizePtr,
  113. IN OUT LPBYTE *CurrentOutputBlockPtrPtr,
  114. IN va_list *FirstArgumentPtr, // rest of API's arguments (after
  115. // server name)
  116. OUT LPDWORD SendDataSizePtr16,
  117. OUT LPBYTE *SendDataPtrPtr16,
  118. OUT LPDWORD RcvDataSizePtr,
  119. OUT LPBYTE *RcvDataPtrPtr,
  120. IN DWORD Flags
  121. )
  122. /*++
  123. Routine Description:
  124. RxpConvertArgs is called to convert a set of arguments to a LanMan API
  125. from "stdargs" format (with 32-bit data) to the Remote Admin Protocol
  126. format (with 16-bit data). This routine deals with an "output block"
  127. (a transact SMB request) and an "input block" (a transact SMB response).
  128. Note that this routine assumes that RxpStartBuildingTransaction has
  129. already been called, as has va_start. This routine also assumes that
  130. the caller will invoke va_end.
  131. This routine further builds the parameter buffer, which was initiated by
  132. RxpStartBuildingTransaction. That routine left the parameter buffer in
  133. the following state:
  134. <api_num><parameter_descriptor_string><data_descriptor_string>
  135. This routine adds the parameters to the end of the parameter buffer as it
  136. scans the parameter list as passed to RxRemoteApi and then to this routine.
  137. If there is auxiliary data associated with the primary data structure
  138. (assuming there is a primary data structure), then the auxiliary data
  139. descriptor is added to the end of the parameter buffer. The parameter
  140. buffer will look either like this:
  141. <api_num><parm_desc><data_desc><parms>
  142. or this:
  143. <api_num><parm_desc><data_desc><parms><aux_desc>
  144. depending on whether an auxiliary count was present in data_desc (again, if
  145. there was one). If data is being sent down-level, then it is converted from
  146. native (32-bit) to down-level (16-bit) format. All primary data structures
  147. and associated data structures are packed into a buffer allocated in this
  148. routine and returned to the caller. Variable data (strings/arrays/etc.) is
  149. packed into the buffer in the reverse order to that in which it is
  150. encountered in the descriptor strings. The routine RxpPackSendBuffer must
  151. be called to sort out this situation - the down-level server expects the
  152. variable data in the same order as that in the descriptor strings.
  153. If the parameter string contains "sT" meaning the stack contains a pointer
  154. to a data buffer which is sent, followed by the length of the 16-bit data
  155. (a word) then the 'T' value is actually ignored. We calculate the amount
  156. of data to send based on the descriptors and the data in the buffer
  157. If the parameter string contains 'P' meaning the stack contains a parameter
  158. number, the size of the actual data for that parameter is calculated from
  159. the type of the corresponding field in the data descriptor
  160. Arguments:
  161. ParmDescriptorString - A pointer to a ASCIIZ string describing the API
  162. call parameters (other than server name). Note that this must be the
  163. descriptor string which is actually IN the block being built, as the
  164. string will be modified before it is sent to the remote system.
  165. DataDesc16, DataDesc32, DataDescSmb - pointers to ASCIIZ strings describing
  166. the structure of the data in the call, i.e. the return data structure
  167. for a Enum or GetInfo call. This string is used for adjusting pointers
  168. to data in the local buffers after transfer across the net. If there
  169. is no structure involved in the call then the data descriptors must be
  170. NULL pointers.
  171. AuxDesc16, AuxDesc32, AuxDescSmb - Will be NULL in most cases unless a
  172. REM_AUX_COUNT descriptor char is present in the data descriptors in
  173. which case the aux descriptors define a secondary data format as the
  174. data descriptors define the primary.
  175. MaximumInputBlockSize - Gives the total number of bytes allocated
  176. for the input block.
  177. MaximumOutputBlockSize - Gives the total number of bytes allocated
  178. for the output block.
  179. CurrentInputBlockSizePtr - Points to a DWORD which indicates the number
  180. of bytes needed for the input block so far. This will be updated on
  181. exit from this routine.
  182. CurrentOutputBlockSizePtr - Points to a DWORD which indicates the number
  183. of bytes used in the output block so far. This will be updated on exit
  184. from this routine.
  185. CurrentOutputBlockPtrPtr - Points to a pointer to the next free byte in
  186. the output block. This pointer will be updated by this routine, to
  187. point to the byte after the last byte placed by this routine into the
  188. output block.
  189. FirstArgumentPtr - The remainder of the parameters for the API call as
  190. given by the application. The server name is not included in these
  191. arguments. These arguments will be processing using the ANSI
  192. <stdarg.h> macros. The caller must have called va_start for this, and
  193. must call va_end for RxpConvertArgs.
  194. SendDataSizePtr16 - Points to a DWORD which will be set to the size in
  195. bytes of the area allocated at SendDataSizePtr16.
  196. SendDataPtrPtr16 - Points to an LPBYTE which will be set to point to
  197. a 16-bit version of the API's send buffer (or NULL if none is given).
  198. The caller must free this area after it has been used.
  199. RcvDataSizePtr - Points to a DWORD which will be set with the size of
  200. the receive buffer, if any. (This buffer is in 32-bit format, and is
  201. specified by the application.)
  202. RcvDataPtrPtr - Points to an LPBYTE which will be set with the pointer to
  203. a receive buffer if one was specified in the API's arguments. (For
  204. instance, this will point to the return area for a get-info call.)
  205. This is set to NULL if no receive buffer was specified. The buffer
  206. is in 32-bit native format.
  207. Flags - bit-mapped flags word. Currently the only flag we are interested in
  208. in this routine is ALLOCATE_RESPONSE. If this is set then the caller
  209. wants RxRemoteApi to allocate the final returned data buffer. We need
  210. to know this because we either pass back in RcvDataPtrPtr the address
  211. of the callers buffer or the address of the address of the callers
  212. buffer (in which case the caller must give RxRemoteApi &buffer, not
  213. just buffer. Confused? You will be after this episode of sope)
  214. Return Value:
  215. NET_API_STATUS.
  216. --*/
  217. {
  218. DWORD ArgumentSize; // Size of an argument (in bytes).
  219. DWORD AuxSize = 0; // Size of aux data struct.
  220. DWORD AuxOffset = 0; // aux structure expected.
  221. va_list CurrentArgumentPtr; // Pointer to stack parms.
  222. DWORD CurrentInputBlockSize; // Length of expected parms.
  223. DWORD CurrentOutputBlockSize; // Length of send parameters.
  224. LPBYTE CurrentOutputBlockPtr; // Ptr moves as we put stuff in.
  225. LPDESC CurrentParmDescPtr; // Used to index ParmDescriptorString.
  226. DWORD ParmNum; // Caller's value for ParmNum.
  227. BOOL ParmNumPresent; // API has a ParmNum.
  228. BOOL SendDataPresent; // Send buf ptr present flag.
  229. LPBYTE SendDataPtrNative;
  230. DWORD SendDataSizeNative;
  231. NET_API_STATUS Status;
  232. DESC_CHAR parm_desc_16[MAX_DESC_SUBSTRING+1]; // 16-bit parameter descriptor for setinfo
  233. DESC_CHAR parm_desc_32[MAX_DESC_SUBSTRING+1]; // 32-bit " " " "
  234. //
  235. // create aliases for *SendDataPtrPtr16 and *SendDataSizePtr16 to remove a
  236. // level of indirection every time we use these values
  237. //
  238. LPBYTE pSendData;
  239. DWORD SendSize;
  240. //
  241. // convertUnstructuredDataToString - if TRUE this means that the caller is
  242. // supplying unstructured data which is a UNICODE string. This must be
  243. // converted to ANSI (or OEM)
  244. //
  245. BOOL convertUnstructuredDataToString = FALSE;
  246. IF_DEBUG(CONVARGS) {
  247. NetpKdPrint(("RxpConvertArgs: parm desc='" FORMAT_LPDESC "',\n",
  248. ParmDescriptorString));
  249. if (DataDesc32 != NULL) {
  250. NetpKdPrint((" Data desc 32='" FORMAT_LPDESC "',\n",
  251. DataDesc32));
  252. NetpAssert(DataDesc16 != NULL);
  253. NetpAssert(DataDescSmb != NULL);
  254. if (DataDescSmb != NULL) {
  255. NetpKdPrint((" Data desc (SMB)='" FORMAT_LPDESC "',\n",
  256. DataDescSmb));
  257. }
  258. } else {
  259. NetpAssert(DataDesc16 == NULL);
  260. NetpAssert(DataDescSmb == NULL);
  261. }
  262. if (AuxDesc32 != NULL) {
  263. NetpKdPrint((" Aux desc 32='" FORMAT_LPDESC "',\n",
  264. AuxDesc32));
  265. NetpAssert(AuxDesc16 != NULL);
  266. NetpAssert(AuxDescSmb != NULL);
  267. if (AuxDescSmb != NULL) {
  268. NetpKdPrint((" Aux desc (SMB)='" FORMAT_LPDESC "',\n",
  269. AuxDescSmb));
  270. }
  271. } else {
  272. NetpAssert(AuxDesc16 == NULL);
  273. NetpAssert(AuxDescSmb == NULL);
  274. }
  275. NetpKdPrint((" max inp blk len=" FORMAT_DWORD
  276. ", max outp blk len=" FORMAT_DWORD ",\n",
  277. MaximumInputBlockSize, MaximumOutputBlockSize));
  278. NetpKdPrint((" curr inp blk len=" FORMAT_DWORD
  279. ", curr outp blk len=" FORMAT_DWORD ".\n",
  280. *CurrentInputBlockSizePtr, *CurrentOutputBlockSizePtr));
  281. NetpAssert( SendDataPtrPtr16 != NULL );
  282. NetpAssert( SendDataSizePtr16 != NULL );
  283. }
  284. //
  285. // Code in this file depends on 16-bit words; the Remote Admin Protocol
  286. // demands it.
  287. //
  288. NetpAssert( ( (sizeof(WORD)) * CHAR_BIT) == 16);
  289. //
  290. // Set found parameter flags to FALSE and pointers to NULL.
  291. //
  292. SendDataPresent = FALSE;
  293. ParmNum = PARMNUM_ALL;
  294. ParmNumPresent = FALSE;
  295. *RcvDataSizePtr = 0;
  296. *RcvDataPtrPtr = NULL;
  297. *SendDataSizePtr16 = 0;
  298. *SendDataPtrPtr16 = NULL;
  299. SendDataSizeNative = 0;
  300. SendDataPtrNative = NULL;
  301. CurrentArgumentPtr = *FirstArgumentPtr;
  302. CurrentInputBlockSize = *CurrentInputBlockSizePtr;
  303. CurrentOutputBlockPtr = *CurrentOutputBlockPtrPtr;
  304. CurrentOutputBlockSize = *CurrentOutputBlockSizePtr;
  305. //
  306. // Now loop for each parameter in the variable arg list. We're going to
  307. // use the COPY of the descriptor here, as we may update it as we go.
  308. //
  309. CurrentParmDescPtr = ParmDescriptorString;
  310. for(; *CurrentParmDescPtr; CurrentParmDescPtr++) {
  311. IF_DEBUG(CONVARGS) {
  312. NetpKdPrint(("RxpConvertArgs: "
  313. "desc at " FORMAT_LPVOID " (" FORMAT_DESC_CHAR ")\n",
  314. (LPVOID) CurrentParmDescPtr, *CurrentParmDescPtr));
  315. }
  316. switch(*CurrentParmDescPtr) {
  317. case REM_WORD: // Word (in 16-bit desc).
  318. {
  319. DWORD Temp; // All "words" in 32-bit APIs are now dwords.
  320. CurrentOutputBlockSize += sizeof(WORD);
  321. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  322. return (NERR_NoRoom);
  323. }
  324. Temp = va_arg(CurrentArgumentPtr, DWORD);
  325. if (RapValueWouldBeTruncated(Temp)) {
  326. NetpKdPrint(("RxpConvertArgs: WORD would be trunc'ed.\n"));
  327. return (ERROR_INVALID_PARAMETER); // Would be truncated.
  328. }
  329. //
  330. // Convert endian and length.
  331. //
  332. SmbPutUshort( (LPWORD) CurrentOutputBlockPtr, (WORD) Temp);
  333. CurrentOutputBlockPtr += sizeof(WORD);
  334. break;
  335. }
  336. case REM_ASCIZ: // pointer to send asciz
  337. {
  338. LPTSTR Temp;
  339. Temp = va_arg(CurrentArgumentPtr, LPTSTR);
  340. if (Temp == NULL) {
  341. //
  342. // Update parm desc string: indicate null pointer.
  343. //
  344. *(CurrentParmDescPtr ) = REM_NULL_PTR;
  345. break;
  346. }
  347. #if defined(UNICODE) // RxpConvertArgs()
  348. ArgumentSize = NetpUnicodeToDBCSLen(Temp) + 1;
  349. #else
  350. ArgumentSize = STRLEN(Temp) + 1;
  351. #endif // defined(UNICODE)
  352. CurrentOutputBlockSize += ArgumentSize;
  353. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  354. return (NERR_NoRoom);
  355. }
  356. //
  357. // Copy str to output area, converting if necessary.
  358. // (This handles UNICODE to default LAN codepage.)
  359. //
  360. #if defined(UNICODE) // RxpConvertArgs()
  361. NetpCopyWStrToStrDBCS(
  362. (LPSTR) CurrentOutputBlockPtr, // dest
  363. Temp ); // src
  364. #else
  365. NetpCopyTStrToStr(
  366. (LPSTR) CurrentOutputBlockPtr, // dest
  367. Temp); // src
  368. #endif // defined(UNICODE)
  369. CurrentOutputBlockPtr += ArgumentSize;
  370. break;
  371. }
  372. case REM_BYTE_PTR: // pointer to send byte(s)
  373. {
  374. LPVOID Temp;
  375. Temp = va_arg(CurrentArgumentPtr, LPVOID);
  376. if (Temp == NULL) {
  377. //
  378. // Update parm desc string to indicate null pointer.
  379. //
  380. *(CurrentParmDescPtr) = REM_NULL_PTR;
  381. break;
  382. }
  383. ArgumentSize = RapArrayLength(
  384. CurrentParmDescPtr,
  385. &CurrentParmDescPtr,
  386. Request);
  387. CurrentOutputBlockSize += ArgumentSize;
  388. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  389. return (NERR_NoRoom);
  390. }
  391. //
  392. // Caller is responsible for all UNICODE-ASCII conversions, we only do ASCII
  393. //
  394. NetpMoveMemory(
  395. CurrentOutputBlockPtr, // dest
  396. Temp, // src
  397. ArgumentSize); // len
  398. CurrentOutputBlockPtr += ArgumentSize;
  399. break;
  400. }
  401. case REM_WORD_PTR: // ptr to send word(s)
  402. case REM_DWORD_PTR: // ptr to send Dword(s)
  403. {
  404. LPVOID Temp;
  405. Temp = va_arg(CurrentArgumentPtr, LPVOID);
  406. if (Temp == NULL) {
  407. //
  408. // Update parm desc string to indicate null pointer.
  409. //
  410. *(CurrentParmDescPtr) = REM_NULL_PTR;
  411. break;
  412. }
  413. ArgumentSize = RapArrayLength(
  414. CurrentParmDescPtr,
  415. &CurrentParmDescPtr,
  416. Request);
  417. CurrentOutputBlockSize += ArgumentSize;
  418. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  419. return (NERR_NoRoom);
  420. }
  421. NetpMoveMemory(
  422. CurrentOutputBlockPtr, // dest
  423. Temp, // src
  424. ArgumentSize); // len
  425. CurrentOutputBlockPtr += ArgumentSize;
  426. break;
  427. }
  428. case REM_RCV_WORD_PTR: // pointer to rcv word(s)
  429. case REM_RCV_BYTE_PTR: // pointer to rcv byte(s)
  430. case REM_RCV_DWORD_PTR: // pointer to rcv Dword(s)
  431. {
  432. LPVOID Temp;
  433. Temp = va_arg(CurrentArgumentPtr, LPVOID);
  434. //
  435. // Added this test for a NULL pointer to allow for
  436. // a reserved field (currently MBN) to be a recv
  437. // pointer. - ERICPE 7/19/89
  438. //
  439. if (Temp == NULL) {
  440. // Update parm desc string to indicate null pointer.
  441. *(CurrentParmDescPtr) = REM_NULL_PTR;
  442. break;
  443. }
  444. CurrentInputBlockSize
  445. += RapArrayLength(
  446. CurrentParmDescPtr,
  447. &CurrentParmDescPtr,
  448. Response);
  449. if ( CurrentInputBlockSize > MaximumInputBlockSize) {
  450. NetpKdPrint(("RxpConvertArgs: len exceeded\n"));
  451. NetpBreakPoint();
  452. return (NERR_InternalError);
  453. }
  454. break;
  455. }
  456. case REM_DWORD: // DWord
  457. {
  458. DWORD Temp;
  459. CurrentOutputBlockSize += sizeof(DWORD);
  460. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  461. return (NERR_NoRoom);
  462. }
  463. Temp = va_arg(CurrentArgumentPtr, DWORD);
  464. SmbPutUlong( (LPDWORD) CurrentOutputBlockPtr, Temp);
  465. CurrentOutputBlockPtr += sizeof(DWORD);
  466. break;
  467. }
  468. case REM_RCV_BUF_LEN: // Size of 32-bit receive data buffer
  469. {
  470. DWORD Temp;
  471. Temp = va_arg(CurrentArgumentPtr, DWORD);
  472. IF_DEBUG(CONVARGS) {
  473. NetpKdPrint(("RxpConvertArgs: 32-bit rcv buf len is "
  474. FORMAT_DWORD "\n", Temp));
  475. }
  476. if (RapValueWouldBeTruncated(Temp)) {
  477. NetpKdPrint(("RxpConvertArgs: rcv.buf.len trunc'ed.\n"));
  478. return (ERROR_INVALID_PARAMETER);
  479. }
  480. //
  481. // If the caller of RxRemoteApi requested that we allocate the
  482. // 32-bit receive buffer (typically for an Enum or GetInfo call)
  483. // then this value is still important - it tells the other side
  484. // how large a buffer it should allocate. We could just stick
  485. // in 64K here, but we defer to the caller who might have a
  486. // better idea, and thus make the allocation on the down-level
  487. // machine more efficient. We have the potential problem that if
  488. // we always use 64K then we reduce efficiency at the down-level
  489. // server without being able to easily rectify the situation
  490. //
  491. if( Temp > MAX_TRANSACT_RET_DATA_SIZE )
  492. {
  493. NetpBreakPoint();
  494. return (ERROR_BUFFER_OVERFLOW);
  495. }
  496. *RcvDataSizePtr = Temp;
  497. CurrentOutputBlockSize += sizeof(WORD);
  498. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  499. return (NERR_NoRoom);
  500. }
  501. SmbPutUshort( (LPWORD)CurrentOutputBlockPtr, (WORD)Temp);
  502. CurrentOutputBlockPtr += sizeof(WORD);
  503. break;
  504. }
  505. case REM_RCV_BUF_PTR: // pointer to 32-bit receive data buffer
  506. {
  507. LPVOID Temp;
  508. Temp = va_arg(CurrentArgumentPtr, LPBYTE *);
  509. //
  510. // NOTE: This pointer could be NULL. For instance, someone
  511. // could call DosPrintQGetInfo with NULL ptr and 0 bytes in
  512. // buffer, to get the number of bytes needed.
  513. //
  514. if ( Flags & ALLOCATE_RESPONSE ) {
  515. if (Temp == NULL) {
  516. NetpKdPrint(( PREFIX_NETAPI
  517. "RxpConvertArgs: NULL rcv buf ptr.\n" ));
  518. return (ERROR_INVALID_PARAMETER);
  519. }
  520. }
  521. //
  522. // If the caller of RxRemoteApi requested that we allocate the
  523. // 32-bit receive buffer then this value is THE ADDRESS OF THE
  524. // POINTER TO THE BUFFER WHICH WILL BE ALLOCATED LATER.
  525. // RxRemoteApi must make sense of this and do the right thing.
  526. // RxpConvertBlock will make the situation right and allocate a
  527. // buffer into which the 16-bit data will be converted
  528. // (hopefully). This paradigm increases buffer efficiency
  529. // (because after we have received the 16-bit data we know how
  530. // large a buffer to allocate in order to return the 32-bit
  531. // data. Before we receive the data, we don't know how much
  532. // will come back and hence allocate the largest possible
  533. // buffer, which is inefficient)
  534. //
  535. *RcvDataPtrPtr = Temp;
  536. break;
  537. }
  538. case REM_SEND_BUF_PTR: // pointer to send data buffer
  539. SendDataPresent = TRUE;
  540. SendDataPtrNative = va_arg(CurrentArgumentPtr, LPBYTE);
  541. break;
  542. case REM_SEND_BUF_LEN: // Size of send data buffer
  543. SendDataSizeNative = va_arg(CurrentArgumentPtr, DWORD);
  544. if ( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  545. {
  546. NetpBreakPoint();
  547. return (ERROR_BUFFER_OVERFLOW);
  548. }
  549. break;
  550. case REM_ENTRIES_READ: // Entries read identifier
  551. CurrentInputBlockSize += sizeof(WORD);
  552. if (CurrentInputBlockSize > MaximumInputBlockSize) {
  553. NetpKdPrint(("RxpConvertArgs: entries read, len exceeded\n"));
  554. NetpBreakPoint();
  555. return (NERR_InternalError);
  556. }
  557. (void) va_arg(CurrentArgumentPtr, LPDWORD);
  558. break;
  559. case REM_PARMNUM: // ParmNum identifier
  560. {
  561. DWORD Temp;
  562. DWORD field_index;
  563. LPDESC parm_num_desc;
  564. CurrentOutputBlockSize += sizeof(WORD);
  565. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  566. return (NERR_NoRoom);
  567. }
  568. Temp = va_arg(CurrentArgumentPtr, DWORD);
  569. #if 0
  570. // no longer required - parmnum is a pair of words packed into a DWORD making
  571. // the following check meaningless
  572. if (RapValueWouldBeTruncated(Temp)) {
  573. NetpKdPrint(("RxpConvertArgs: parmnum truncated.\n"));
  574. return (ERROR_INVALID_PARAMETER);
  575. }
  576. #endif
  577. ParmNumPresent = TRUE;
  578. //
  579. // ParmNum is the actual value which is sent over the wire and
  580. // uniquely identifies a field. It is a sort of handle
  581. //
  582. ParmNum = PARMNUM_FROM_PARMNUM_PAIR(Temp);
  583. //
  584. // field_index is not sent over the wire but is the ordinal of
  585. // the field that ParmNum refers to, in the structure/descriptor
  586. // This is the value we must use to determine the size of the
  587. // field identified by ParmNum, or else RapParmNumDescriptor
  588. // could have a minor spasm
  589. //
  590. field_index = FIELD_INDEX_FROM_PARMNUM_PAIR(Temp);
  591. SmbPutUshort( (LPWORD)CurrentOutputBlockPtr, (WORD)ParmNum);
  592. CurrentOutputBlockPtr += sizeof(WORD);
  593. //
  594. // if ParmNum is not PARMNUM_ALL get the size of the parameter
  595. // from the data descriptor
  596. //
  597. if (ParmNum != PARMNUM_ALL) {
  598. //
  599. // This call is for a set info. We need to calculate the
  600. // size of the data being passed in the buffer - the caller
  601. // no longer supplies this info
  602. // NOTE: RapParmNumDescriptor wants the FIELD INDEX, not
  603. // the PARMNUM, hence the reason for the convolutions
  604. //
  605. parm_num_desc = RxpGetSetInfoDescriptor(
  606. DataDescSmb, // 16-bit data
  607. field_index, // which field
  608. FALSE // not 32-bit data
  609. );
  610. if (parm_num_desc == NULL) {
  611. return NERR_InternalError;
  612. } else {
  613. NetpAssert(
  614. DESCLEN(parm_num_desc) <= MAX_DESC_SUBSTRING );
  615. strcpy(parm_desc_16, parm_num_desc);
  616. NetpMemoryFree(parm_num_desc);
  617. }
  618. parm_num_desc = RxpGetSetInfoDescriptor(
  619. DataDesc32, // 32-bit data
  620. field_index, // which field
  621. TRUE // 32-bit data
  622. );
  623. if (parm_num_desc == NULL) {
  624. return NERR_InternalError;
  625. } else {
  626. NetpAssert(
  627. DESCLEN(parm_num_desc) <= MAX_DESC_SUBSTRING );
  628. strcpy(parm_desc_32, parm_num_desc);
  629. NetpMemoryFree(parm_num_desc);
  630. }
  631. //
  632. // The following will get the size of a 16-bit parameter in
  633. // SendDataSizeNative. NOTE THAT THIS ASSUMES THERE IS ONLY
  634. // ONE UNSTRUCTURED PARAMETER IN THE BUFFER
  635. //
  636. SendDataSizeNative = RxpGetFieldSize(
  637. SendDataPtrNative,
  638. parm_desc_16
  639. );
  640. //
  641. // HACKHACK - if this is a string, treat it as unstructured
  642. // data by setting DataDescSmb to NULL. Code lower down
  643. // will inspect this and skip the data conversion
  644. //
  645. if (*parm_desc_16 == REM_ASCIZ) {
  646. //
  647. // setting convertUnstructuredDataToString to TRUE will
  648. // cause us to convert an input UNICODE string to ANSI.
  649. // SendDataSizeNative must also be recomputed
  650. //
  651. convertUnstructuredDataToString = TRUE;
  652. DataDescSmb = NULL;
  653. }
  654. }
  655. break;
  656. }
  657. case REM_FILL_BYTES: // Send parm pad field
  658. // This is a rare type but is needed to ensure that the
  659. // send parameters are at least as large as the return
  660. // parameters so that buffer management can be simplified
  661. // on the server.
  662. ArgumentSize = RapArrayLength(
  663. CurrentParmDescPtr,
  664. &CurrentParmDescPtr,
  665. Both); // Lie so space gets alloc'ed.
  666. CurrentOutputBlockSize += ArgumentSize;
  667. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  668. return (NERR_NoRoom);
  669. }
  670. // CurrentOutputBlockPtr += ArgumentSize;
  671. break;
  672. default: // Could be a digit from NULL send array
  673. break;
  674. } // switch
  675. } // for
  676. //
  677. // The parameter buffer now contains:
  678. // ApiNumber - word
  679. // ParmDescriptorString - asciiz, (NULL c,i,f,z identifiers replaced with O)
  680. // DataDescSmb - asciiz
  681. // parameters - as identified by ParmDescriptorString.
  682. //
  683. // Now process the data descriptor string.
  684. //
  685. //
  686. // For the receive buffer there is no data to set up for the call, but
  687. // there might have been an REM_AUX_COUNT descriptor in DataDescSmb
  688. // which requires the AuxDescSmb string to be copied onto the end of the
  689. // parameter buffer.
  690. //
  691. //
  692. // if we have data to receive BUT its unstructured then don't check the
  693. // DataDescSmb descriptor
  694. //
  695. // MOD 08/08/91 RLF
  696. // if ((*RcvDataPtrPtr != NULL && DataDescSmb) || SendDataPresent) {
  697. if (DataDescSmb) {
  698. // MOD 08/08/91 RLF
  699. //
  700. // If data to be transfered...
  701. //
  702. //
  703. // Find the length of the fixed length portion of the data
  704. // buffer.
  705. //
  706. // MOD 08/08/91 RLF
  707. // NetpAssert(DataDescSmb != NULL);
  708. // MOD 08/08/91 RLF
  709. AuxOffset = RapAuxDataCountOffset(
  710. DataDescSmb, // descriptor
  711. Both, // transmission mode
  712. FALSE); // not native format
  713. if (AuxOffset != NO_AUX_DATA) {
  714. DWORD AuxDescSize;
  715. DWORD no_aux_check; // check flag.
  716. NetpAssert(AuxDescSmb != NULL);
  717. NetpAssert(sizeof(DESC_CHAR) == 1); // Caller should only give us ASCII, and should handle UNICODE conversion
  718. AuxDescSize = DESCLEN(AuxDescSmb) + 1; // desc str and null
  719. CurrentOutputBlockSize += AuxDescSize; // Add to total len.
  720. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  721. return (NERR_NoRoom);
  722. }
  723. IF_DEBUG(CONVARGS) {
  724. NetpKdPrint(( "RxpConvertArgs: copying aux desc...\n" ));
  725. }
  726. NetpMoveMemory(
  727. CurrentOutputBlockPtr, // dest
  728. AuxDescSmb, // src
  729. AuxDescSize); // len
  730. CurrentOutputBlockPtr += AuxDescSize; // Update buffer ptr.
  731. AuxSize = RapStructureSize(
  732. AuxDescSmb,
  733. Both,
  734. FALSE); // not native format
  735. NetpAssert(AuxDescSmb != NULL);
  736. no_aux_check = RapAuxDataCountOffset(
  737. AuxDescSmb, // descriptor
  738. Both, // transmission mode
  739. FALSE); // not native format
  740. if (no_aux_check != NO_AUX_DATA) {
  741. //
  742. // Error if N in AuxDescSmb
  743. //
  744. NetpKdPrint(("RxpConvertArgs: N in aux desc str.\n"));
  745. NetpBreakPoint();
  746. return (NERR_InternalError);
  747. }
  748. }
  749. }
  750. //
  751. // For a send buffer the data pointed to in the fixed structure
  752. // must be copied into the send buffer. Any pointers which already
  753. // point in the send buffer are NULLed as it is illegal to use
  754. // the buffer for the send data, it is our transport buffer.
  755. //
  756. // NOTE - if parmnum was specified the buffer contains only that
  757. // element of the structure so no length checking is needed at this
  758. // side. A parmnum for a pointer type means that the data is at the
  759. // start of the buffer so there is no copying to be done.
  760. //
  761. if (SendDataPresent) { // If a send buffer was specified
  762. //
  763. // if there is no smb data descriptor, but there is data to send, then
  764. // it is unstructured (usually meaning its a string). SendDataPtrNative
  765. // points to the data, and SendDataSizeNative is the amount to send.
  766. // Don't perform any conversions, just copy it to the send data buffer
  767. //
  768. if (DataDescSmb == NULL) {
  769. LPBYTE ptr;
  770. if ((ptr = NetpMemoryAllocate(SendDataSizeNative)) == NULL) {
  771. return ERROR_NOT_ENOUGH_MEMORY;
  772. }
  773. //
  774. // UniCode to ASCII. The caller should have made this
  775. // conversion. We only know about unstructured data
  776. // (ie bytes)
  777. //
  778. IF_DEBUG(CONVARGS) {
  779. NetpKdPrint((
  780. "RxpConvertArgs: copying unstructured (no desc)...\n" ));
  781. }
  782. //
  783. // we may have to convert UNICODE to ANSI
  784. //
  785. if (convertUnstructuredDataToString) {
  786. //
  787. // sleaze: the buffer we just allocated may be twice the size
  788. // of the buffer really required
  789. //
  790. #if defined(UNICODE) // RxpConvertArgs()
  791. NetpCopyWStrToStrDBCS( ptr, (LPTSTR)SendDataPtrNative );
  792. #else
  793. NetpCopyTStrToStr(ptr, SendDataPtrNative);
  794. #endif // defined(UNICODE)
  795. //
  796. // recompute the data size as the length of the narrow-character
  797. // string
  798. //
  799. SendDataSizeNative = strlen( (LPVOID) ptr) + 1;
  800. } else {
  801. NetpMoveMemory(ptr, SendDataPtrNative, SendDataSizeNative);
  802. }
  803. *SendDataPtrPtr16 = ptr;
  804. if( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  805. {
  806. NetpBreakPoint();
  807. return (ERROR_BUFFER_OVERFLOW);
  808. }
  809. *SendDataSizePtr16 = SendDataSizeNative;
  810. } else if ((ParmNum == PARMNUM_ALL) && (*DataDesc32 != REM_DATA_BLOCK)) {
  811. //
  812. // Only process buffer if no ParmNum and this is not a block send
  813. // (no data structure) or an ASCIZ concatenation send
  814. //
  815. BOOL BogusAllocFlag;
  816. DWORD BytesRequired = 0;
  817. DWORD FixedStructSize16;
  818. DWORD primary_structure_size;
  819. LPBYTE StringLocation;
  820. DWORD TotalStructSize16;
  821. DWORD TotalStructSize32;
  822. IF_DEBUG(CONVARGS) {
  823. NetpKdPrint(( "RxpConvertArgs: PARMNUM_ALL...\n" ));
  824. }
  825. //
  826. // here we calculate the TOTAL data requirement of both the 32-bit
  827. // and 16-bit data. This includes:
  828. // - primary data structures (NOTE: We assume only 1????)
  829. // - variable data for primary structure (strings, arrays, etc)
  830. // - aux data structures
  831. // - variable data for aux structures (strings, arrays, etc)
  832. //
  833. //
  834. // Compute size of 32 bit structure, and other pointers and numbers.
  835. //
  836. primary_structure_size = RapStructureSize(DataDesc32, Both, TRUE);
  837. TotalStructSize32 = RapTotalSize(
  838. SendDataPtrNative, // in structure
  839. DataDesc32, // in desc
  840. DataDesc32, // out desc
  841. FALSE, // no meaningless input ptrs
  842. Both, // transmission mode
  843. NativeToNative); // input and output are native
  844. //
  845. // Compute size of 16 bit structure, and other pointers and numbers.
  846. //
  847. FixedStructSize16 = RapStructureSize(DataDesc16,Both,FALSE);
  848. TotalStructSize16 = RapTotalSize(
  849. SendDataPtrNative, // in structure
  850. DataDesc32, // in desc
  851. DataDesc16, // out desc
  852. FALSE, // no meaningless input ptrs
  853. Both, // transmission mode
  854. NativeToRap); // input is native; output is not.
  855. //
  856. // account for any associated auxiliary structures
  857. //
  858. if (AuxDesc32) {
  859. DWORD aux_size;
  860. DWORD aux_count;
  861. DWORD aux_structure_size;
  862. LPBYTE next_structure;
  863. //
  864. // find out how many auxiliary structures are being sent along
  865. // with the primary
  866. //
  867. aux_count = RapAuxDataCount(SendDataPtrNative,
  868. DataDesc32,
  869. Both,
  870. TRUE // input is native format.
  871. );
  872. //
  873. // aux_structure_size is the size of the fixed portion of the
  874. // auxiliary data
  875. // next_structure is a pointer to the next auxiliary structure
  876. // for which to calculate the total space requirement
  877. //
  878. aux_structure_size = RapStructureSize(AuxDesc32, Request, FALSE);
  879. next_structure = SendDataPtrNative + primary_structure_size;
  880. while (aux_count--) {
  881. //
  882. // get the total size of the aux data - fixed structure
  883. // length (which we already know) and the variable data
  884. // requirement
  885. //
  886. aux_size = RapTotalSize(
  887. next_structure, // where the 32-bit data lives
  888. AuxDesc32, // convert 32-bit
  889. AuxDesc32, // to 32-bit
  890. FALSE, // pointers NOT meaningless
  891. Both, // ?
  892. NativeToNative // 32-bit to 32-bit
  893. );
  894. TotalStructSize32 += aux_size;
  895. //
  896. // do the same for the 16-bit version of the data
  897. //
  898. aux_size = RapTotalSize(
  899. next_structure, // where the 32-bit data lives
  900. AuxDesc32, // convert 32-bit
  901. AuxDesc16, // to 16-bit
  902. FALSE, // pointers NOT meaningless
  903. Both, // ?
  904. NativeToRap // 32-bit to 16-bit
  905. );
  906. TotalStructSize16 += aux_size;
  907. //
  908. // point to next aux structure (probably only 1 anyway?)
  909. //
  910. next_structure += aux_structure_size;
  911. }
  912. }
  913. IF_DEBUG(CONVARGS) {
  914. NetpKdPrint(( "RxpConvertArgs: total size(32)="
  915. FORMAT_DWORD ".\n", TotalStructSize32 ));
  916. }
  917. NetpAssert(TotalStructSize16 >= FixedStructSize16);
  918. IF_DEBUG(CONVARGS) {
  919. NetpKdPrint(( "RxpConvertArgs: total size(16)="
  920. FORMAT_DWORD ".\n", TotalStructSize16 ));
  921. }
  922. if( TotalStructSize16 > MAX_TRANSACT_SEND_DATA_SIZE )
  923. {
  924. NetpBreakPoint();
  925. return (ERROR_BUFFER_OVERFLOW);
  926. }
  927. *SendDataSizePtr16 = SendSize = TotalStructSize16;
  928. *SendDataPtrPtr16 = pSendData = NetpMemoryAllocate( TotalStructSize16 );
  929. if (pSendData == NULL) {
  930. return ERROR_NOT_ENOUGH_MEMORY;
  931. }
  932. StringLocation = (pSendData) + TotalStructSize16;
  933. IF_DEBUG(CONVARGS) {
  934. NetpKdPrint(("RxpConvertArgs: initial StringLocation is "
  935. FORMAT_LPVOID "\n", (LPVOID) StringLocation ));
  936. NetpKdPrint(("RxpConvertArgs: input data "
  937. "(before CSE, partial):\n"));
  938. NetpDbgHexDump( SendDataPtrNative,
  939. NetpDbgReasonable( TotalStructSize16 ) );
  940. NetpKdPrint(("RxpConvertArgs: output data area "
  941. "(before CSE, partial):\n"));
  942. NetpDbgHexDump( pSendData,
  943. NetpDbgReasonable( TotalStructSize16 ) );
  944. }
  945. //
  946. // This routine calls RapConvertSingleEntry to convert the primary
  947. // data structure, but will also convert any auxiliary structures
  948. //
  949. Status = RxpConvertDataStructures(
  950. DataDesc32, // 32-bit data
  951. DataDesc16, // converted from 16-bit
  952. AuxDesc32, // as are the aux structures
  953. AuxDesc16,
  954. SendDataPtrNative, // where the 32-bit lives
  955. pSendData, // and its new 16-bit address
  956. SendSize, // how big the buffer is
  957. 1, // only 1 primary structure.
  958. NULL, // don't need number of entries converted.
  959. Both, // do entire structure
  960. NativeToRap // explicit 32->16, implicit TCHAR->codepage
  961. );
  962. //
  963. // We allocated the output buffer large enough, so there's no
  964. // reason that conversion should fail.
  965. //
  966. NetpAssert(Status == NERR_Success);
  967. //
  968. // RxpConvertDataStructures calls RapConvertSingleEntry to pack the
  969. // fixed and variable parts of the data into the buffer. The down-
  970. // level server expects the data in the same order as that in which
  971. // it appears in the descriptor strings. RxpPackSendBuffer exists
  972. // to make this so. Do it
  973. //
  974. Status = RxpPackSendBuffer(
  975. (LPVOID *) SendDataPtrPtr16, // possibly reallocated
  976. SendDataSizePtr16, // possibly realloced
  977. &BogusAllocFlag,
  978. DataDesc16,
  979. AuxDesc16,
  980. FixedStructSize16,
  981. AuxOffset,
  982. AuxSize,
  983. ParmNumPresent
  984. );
  985. if (Status != NERR_Success) {
  986. NetpKdPrint(("RxpConvertArgs: pack send buffer failed, stat="
  987. FORMAT_API_STATUS "\n", Status));
  988. return (Status);
  989. }
  990. IF_DEBUG(CONVARGS) {
  991. NetpKdPrint(("RxpConvertArgs: data "
  992. "(after RxpPackSendBuffer):\n"));
  993. NetpDbgHexDump( pSendData, BytesRequired );
  994. }
  995. //
  996. // MOD 06/25/91 RLF
  997. // Remove this, since reallocation takes place. Does it have any other
  998. // implications?
  999. //
  1000. // MOD 08/08/91 RLF
  1001. NetpAssert(BogusAllocFlag == FALSE);
  1002. // MOD 08/08/91 RLF
  1003. //
  1004. // MOD 06/25/91 RLF
  1005. //
  1006. } else if (ParmNum) {
  1007. //
  1008. // here if there is a parameter to set. Create a buffer for the data
  1009. // to be sent in the setinfo call. Copy the caller's data into it.
  1010. //
  1011. LPBYTE ptr;
  1012. LPBYTE enddata;
  1013. DWORD bytes_required;
  1014. IF_DEBUG(CONVARGS) {
  1015. NetpKdPrint(( "RxpConvertArgs: parmnum (not all)...\n" ));
  1016. }
  1017. if ((ptr = NetpMemoryAllocate(SendDataSizeNative)) == NULL) {
  1018. return ERROR_NOT_ENOUGH_MEMORY; // gasp!
  1019. }
  1020. //
  1021. // we now convert the data for the single field from 32-bits to
  1022. // 16. Use the descriptors which identify the single field only
  1023. //
  1024. enddata = ptr + SendDataSizeNative;
  1025. bytes_required = 0;
  1026. Status = RapConvertSingleEntry(SendDataPtrNative,
  1027. parm_desc_32,
  1028. FALSE,
  1029. ptr,
  1030. ptr,
  1031. parm_desc_16,
  1032. FALSE,
  1033. &enddata,
  1034. &bytes_required,
  1035. Both,
  1036. NativeToRap
  1037. );
  1038. NetpAssert( Status == NERR_Success );
  1039. #if DBG
  1040. if (!(bytes_required <= SendDataSizeNative)) {
  1041. NetpKdPrint(("error: RxpConvertArgs.%d: "
  1042. "bytes_required=%d, SendDataSizeNative=%d\n"
  1043. "parm_desc_16=%s, parm_desc_32=%s\n",
  1044. __LINE__,
  1045. bytes_required,
  1046. SendDataSizeNative,
  1047. parm_desc_16,
  1048. parm_desc_32
  1049. ));
  1050. }
  1051. NetpAssert(bytes_required <= SendDataSizeNative);
  1052. #endif
  1053. *SendDataPtrPtr16 = ptr;
  1054. //
  1055. // SendDataSizeNative is either the size of the buffer in a "sT"
  1056. // descriptor pair, or was calculated based on the descriptor type
  1057. // and caller's data in a setinfo/parmnum ('P') case
  1058. //
  1059. if ( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  1060. {
  1061. NetpBreakPoint();
  1062. return (ERROR_BUFFER_OVERFLOW);
  1063. }
  1064. *SendDataSizePtr16 = SendDataSizeNative;
  1065. } else {
  1066. LPBYTE ptr;
  1067. //
  1068. // send data, PARMNUM_ALL, data desc is REM_DATA_BLOCK. This can
  1069. // happen with the NetServiceInstall API (see RxApi/SvcInst.c).
  1070. // cbBuffer arg is set by RxNetServiceInstall to be the OUTPUT
  1071. // buffer size, despite the LM 2.x app passing the INPUT size.
  1072. // (We're just propagating another LanMan kludge here.)
  1073. //
  1074. // UniCode to ASCII. The caller should have made this
  1075. // conversion. We only know about unstructured data
  1076. // (ie bytes)
  1077. //
  1078. NetpAssert( ParmNum == PARMNUM_ALL );
  1079. NetpAssert( *DataDesc16 == REM_DATA_BLOCK );
  1080. NetpAssert( SendDataSizeNative > 0 );
  1081. IF_DEBUG(CONVARGS) {
  1082. NetpKdPrint(( "RxpConvertArgs: "
  1083. "copying unstructured data with desc...\n" ));
  1084. }
  1085. //
  1086. // Copy unstructured data and tell caller where it is.
  1087. //
  1088. if ((ptr = NetpMemoryAllocate(SendDataSizeNative)) == NULL) {
  1089. return ERROR_NOT_ENOUGH_MEMORY;
  1090. }
  1091. NetpMoveMemory(
  1092. ptr, // dest
  1093. SendDataPtrNative, // src
  1094. SendDataSizeNative); // size
  1095. *SendDataPtrPtr16 = ptr;
  1096. if ( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  1097. {
  1098. NetpBreakPoint();
  1099. return (ERROR_BUFFER_OVERFLOW);
  1100. }
  1101. *SendDataSizePtr16 = SendDataSizeNative;
  1102. }
  1103. } // send buffer was specified
  1104. //
  1105. // The parameter buffers and data buffers are now set up for
  1106. // sending to the API worker so tell the caller.
  1107. //
  1108. *CurrentInputBlockSizePtr = CurrentInputBlockSize;
  1109. *CurrentOutputBlockSizePtr = CurrentOutputBlockSize;
  1110. *CurrentOutputBlockPtrPtr = CurrentOutputBlockPtr;
  1111. return NERR_Success;
  1112. } // RxpConvertArgs
  1113. DBGSTATIC
  1114. DWORD
  1115. RxpGetFieldSize(
  1116. IN LPBYTE Field,
  1117. IN LPDESC FieldDesc
  1118. )
  1119. {
  1120. NetpAssert(Field != NULL);
  1121. NetpAssert(FieldDesc != NULL);
  1122. if (*FieldDesc == REM_ASCIZ) {
  1123. return STRSIZE((LPTSTR)Field);
  1124. } else {
  1125. LPDESC TempDescPtr = FieldDesc;
  1126. return RapGetFieldSize(FieldDesc, &TempDescPtr, Both);
  1127. }
  1128. } // RxpGetFieldSize
  1129. DBGSTATIC
  1130. LPDESC
  1131. RxpGetSetInfoDescriptor(
  1132. IN LPDESC Descriptor,
  1133. IN DWORD FieldIndex,
  1134. IN BOOL Is32BitDesc
  1135. )
  1136. /*++
  1137. Routine Description:
  1138. Allocates a descriptor string which describes a single parameter element
  1139. of a structure, for SetInfo calls (where ParmNum != PARMNUM_ALL)
  1140. Arguments:
  1141. Descriptor - The full descriptor string for the relevant structure
  1142. FieldIndex - The ORDINAL number of the field (NOT ParmNum)
  1143. Is32BitDesc - Descriptor defines 16-bit data
  1144. Return Value:
  1145. Pointer to allocated descriptor or NULL if error
  1146. --*/
  1147. {
  1148. LPDESC lpdesc;
  1149. lpdesc = RapParmNumDescriptor(Descriptor, FieldIndex, Both, Is32BitDesc);
  1150. if (lpdesc == NULL) {
  1151. #if DBG
  1152. //
  1153. // don't expect this to happen - trap it in debug version
  1154. //
  1155. NetpKdPrint(("error: RxpGetSetInfoDescriptor: RapParmNumDescriptor didn't allocate string\n"));
  1156. NetpBreakPoint();
  1157. #endif
  1158. } else if (*lpdesc == REM_UNSUPPORTED_FIELD) {
  1159. #if DBG
  1160. //
  1161. // don't expect this to happen - trap it in debug version
  1162. //
  1163. NetpKdPrint(("error: RxpGetSetInfoDescriptor: parameter defines unsupported field\n"));
  1164. NetpBreakPoint();
  1165. #endif
  1166. NetpMemoryFree(lpdesc);
  1167. lpdesc = NULL;
  1168. }
  1169. return lpdesc;
  1170. }