Leaked source code of windows server 2003
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.

1445 lines
54 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. if ( DESCLEN(parm_num_desc) >= MAX_DESC_SUBSTRING ) {
  614. return ERROR_BUFFER_OVERFLOW;
  615. }
  616. strncpy(parm_desc_16, parm_num_desc, MAX_DESC_SUBSTRING);
  617. NetpMemoryFree(parm_num_desc);
  618. }
  619. parm_num_desc = RxpGetSetInfoDescriptor(
  620. DataDesc32, // 32-bit data
  621. field_index, // which field
  622. TRUE // 32-bit data
  623. );
  624. if (parm_num_desc == NULL) {
  625. return NERR_InternalError;
  626. } else {
  627. if ( DESCLEN(parm_num_desc) >= MAX_DESC_SUBSTRING ) {
  628. return ERROR_BUFFER_OVERFLOW;
  629. }
  630. strncpy(parm_desc_32, parm_num_desc, MAX_DESC_SUBSTRING);
  631. NetpMemoryFree(parm_num_desc);
  632. }
  633. //
  634. // The following will get the size of a 16-bit parameter in
  635. // SendDataSizeNative. NOTE THAT THIS ASSUMES THERE IS ONLY
  636. // ONE UNSTRUCTURED PARAMETER IN THE BUFFER
  637. //
  638. SendDataSizeNative = RxpGetFieldSize(
  639. SendDataPtrNative,
  640. parm_desc_16
  641. );
  642. //
  643. // HACKHACK - if this is a string, treat it as unstructured
  644. // data by setting DataDescSmb to NULL. Code lower down
  645. // will inspect this and skip the data conversion
  646. //
  647. if (*parm_desc_16 == REM_ASCIZ) {
  648. //
  649. // setting convertUnstructuredDataToString to TRUE will
  650. // cause us to convert an input UNICODE string to ANSI.
  651. // SendDataSizeNative must also be recomputed
  652. //
  653. convertUnstructuredDataToString = TRUE;
  654. DataDescSmb = NULL;
  655. }
  656. }
  657. break;
  658. }
  659. case REM_FILL_BYTES: // Send parm pad field
  660. // This is a rare type but is needed to ensure that the
  661. // send parameters are at least as large as the return
  662. // parameters so that buffer management can be simplified
  663. // on the server.
  664. ArgumentSize = RapArrayLength(
  665. CurrentParmDescPtr,
  666. &CurrentParmDescPtr,
  667. Both); // Lie so space gets alloc'ed.
  668. CurrentOutputBlockSize += ArgumentSize;
  669. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  670. return (NERR_NoRoom);
  671. }
  672. // CurrentOutputBlockPtr += ArgumentSize;
  673. break;
  674. default: // Could be a digit from NULL send array
  675. break;
  676. } // switch
  677. } // for
  678. //
  679. // The parameter buffer now contains:
  680. // ApiNumber - word
  681. // ParmDescriptorString - asciiz, (NULL c,i,f,z identifiers replaced with O)
  682. // DataDescSmb - asciiz
  683. // parameters - as identified by ParmDescriptorString.
  684. //
  685. // Now process the data descriptor string.
  686. //
  687. //
  688. // For the receive buffer there is no data to set up for the call, but
  689. // there might have been an REM_AUX_COUNT descriptor in DataDescSmb
  690. // which requires the AuxDescSmb string to be copied onto the end of the
  691. // parameter buffer.
  692. //
  693. //
  694. // if we have data to receive BUT its unstructured then don't check the
  695. // DataDescSmb descriptor
  696. //
  697. // MOD 08/08/91 RLF
  698. // if ((*RcvDataPtrPtr != NULL && DataDescSmb) || SendDataPresent) {
  699. if (DataDescSmb) {
  700. // MOD 08/08/91 RLF
  701. //
  702. // If data to be transfered...
  703. //
  704. //
  705. // Find the length of the fixed length portion of the data
  706. // buffer.
  707. //
  708. // MOD 08/08/91 RLF
  709. // NetpAssert(DataDescSmb != NULL);
  710. // MOD 08/08/91 RLF
  711. AuxOffset = RapAuxDataCountOffset(
  712. DataDescSmb, // descriptor
  713. Both, // transmission mode
  714. FALSE); // not native format
  715. if (AuxOffset != NO_AUX_DATA) {
  716. DWORD AuxDescSize;
  717. DWORD no_aux_check; // check flag.
  718. NetpAssert(AuxDescSmb != NULL);
  719. NetpAssert(sizeof(DESC_CHAR) == 1); // Caller should only give us ASCII, and should handle UNICODE conversion
  720. AuxDescSize = DESCLEN(AuxDescSmb) + 1; // desc str and null
  721. CurrentOutputBlockSize += AuxDescSize; // Add to total len.
  722. if (CurrentOutputBlockSize > MaximumOutputBlockSize) {
  723. return (NERR_NoRoom);
  724. }
  725. IF_DEBUG(CONVARGS) {
  726. NetpKdPrint(( "RxpConvertArgs: copying aux desc...\n" ));
  727. }
  728. NetpMoveMemory(
  729. CurrentOutputBlockPtr, // dest
  730. AuxDescSmb, // src
  731. AuxDescSize); // len
  732. CurrentOutputBlockPtr += AuxDescSize; // Update buffer ptr.
  733. AuxSize = RapStructureSize(
  734. AuxDescSmb,
  735. Both,
  736. FALSE); // not native format
  737. NetpAssert(AuxDescSmb != NULL);
  738. no_aux_check = RapAuxDataCountOffset(
  739. AuxDescSmb, // descriptor
  740. Both, // transmission mode
  741. FALSE); // not native format
  742. if (no_aux_check != NO_AUX_DATA) {
  743. //
  744. // Error if N in AuxDescSmb
  745. //
  746. NetpKdPrint(("RxpConvertArgs: N in aux desc str.\n"));
  747. NetpBreakPoint();
  748. return (NERR_InternalError);
  749. }
  750. }
  751. }
  752. //
  753. // For a send buffer the data pointed to in the fixed structure
  754. // must be copied into the send buffer. Any pointers which already
  755. // point in the send buffer are NULLed as it is illegal to use
  756. // the buffer for the send data, it is our transport buffer.
  757. //
  758. // NOTE - if parmnum was specified the buffer contains only that
  759. // element of the structure so no length checking is needed at this
  760. // side. A parmnum for a pointer type means that the data is at the
  761. // start of the buffer so there is no copying to be done.
  762. //
  763. if (SendDataPresent) { // If a send buffer was specified
  764. //
  765. // if there is no smb data descriptor, but there is data to send, then
  766. // it is unstructured (usually meaning its a string). SendDataPtrNative
  767. // points to the data, and SendDataSizeNative is the amount to send.
  768. // Don't perform any conversions, just copy it to the send data buffer
  769. //
  770. if (DataDescSmb == NULL) {
  771. LPBYTE ptr;
  772. if ((ptr = NetpMemoryAllocate(SendDataSizeNative)) == NULL) {
  773. return ERROR_NOT_ENOUGH_MEMORY;
  774. }
  775. //
  776. // UniCode to ASCII. The caller should have made this
  777. // conversion. We only know about unstructured data
  778. // (ie bytes)
  779. //
  780. IF_DEBUG(CONVARGS) {
  781. NetpKdPrint((
  782. "RxpConvertArgs: copying unstructured (no desc)...\n" ));
  783. }
  784. //
  785. // we may have to convert UNICODE to ANSI
  786. //
  787. if (convertUnstructuredDataToString) {
  788. //
  789. // sleaze: the buffer we just allocated may be twice the size
  790. // of the buffer really required
  791. //
  792. #if defined(UNICODE) // RxpConvertArgs()
  793. NetpCopyWStrToStrDBCS( ptr, (LPTSTR)SendDataPtrNative );
  794. #else
  795. NetpCopyTStrToStr(ptr, SendDataPtrNative);
  796. #endif // defined(UNICODE)
  797. //
  798. // recompute the data size as the length of the narrow-character
  799. // string
  800. //
  801. SendDataSizeNative = strlen( (LPVOID) ptr) + 1;
  802. } else {
  803. NetpMoveMemory(ptr, SendDataPtrNative, SendDataSizeNative);
  804. }
  805. *SendDataPtrPtr16 = ptr;
  806. if( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  807. {
  808. NetpBreakPoint();
  809. return (ERROR_BUFFER_OVERFLOW);
  810. }
  811. *SendDataSizePtr16 = SendDataSizeNative;
  812. } else if ((ParmNum == PARMNUM_ALL) && (*DataDesc32 != REM_DATA_BLOCK)) {
  813. //
  814. // Only process buffer if no ParmNum and this is not a block send
  815. // (no data structure) or an ASCIZ concatenation send
  816. //
  817. BOOL BogusAllocFlag;
  818. DWORD BytesRequired = 0;
  819. DWORD FixedStructSize16;
  820. DWORD primary_structure_size;
  821. LPBYTE StringLocation;
  822. DWORD TotalStructSize16;
  823. DWORD TotalStructSize32;
  824. IF_DEBUG(CONVARGS) {
  825. NetpKdPrint(( "RxpConvertArgs: PARMNUM_ALL...\n" ));
  826. }
  827. //
  828. // here we calculate the TOTAL data requirement of both the 32-bit
  829. // and 16-bit data. This includes:
  830. // - primary data structures (NOTE: We assume only 1????)
  831. // - variable data for primary structure (strings, arrays, etc)
  832. // - aux data structures
  833. // - variable data for aux structures (strings, arrays, etc)
  834. //
  835. //
  836. // Compute size of 32 bit structure, and other pointers and numbers.
  837. //
  838. primary_structure_size = RapStructureSize(DataDesc32, Both, TRUE);
  839. TotalStructSize32 = RapTotalSize(
  840. SendDataPtrNative, // in structure
  841. DataDesc32, // in desc
  842. DataDesc32, // out desc
  843. FALSE, // no meaningless input ptrs
  844. Both, // transmission mode
  845. NativeToNative); // input and output are native
  846. //
  847. // Compute size of 16 bit structure, and other pointers and numbers.
  848. //
  849. FixedStructSize16 = RapStructureSize(DataDesc16,Both,FALSE);
  850. TotalStructSize16 = RapTotalSize(
  851. SendDataPtrNative, // in structure
  852. DataDesc32, // in desc
  853. DataDesc16, // out desc
  854. FALSE, // no meaningless input ptrs
  855. Both, // transmission mode
  856. NativeToRap); // input is native; output is not.
  857. //
  858. // account for any associated auxiliary structures
  859. //
  860. if (AuxDesc32) {
  861. DWORD aux_size;
  862. DWORD aux_count;
  863. DWORD aux_structure_size;
  864. LPBYTE next_structure;
  865. //
  866. // find out how many auxiliary structures are being sent along
  867. // with the primary
  868. //
  869. aux_count = RapAuxDataCount(SendDataPtrNative,
  870. DataDesc32,
  871. Both,
  872. TRUE // input is native format.
  873. );
  874. //
  875. // aux_structure_size is the size of the fixed portion of the
  876. // auxiliary data
  877. // next_structure is a pointer to the next auxiliary structure
  878. // for which to calculate the total space requirement
  879. //
  880. aux_structure_size = RapStructureSize(AuxDesc32, Request, FALSE);
  881. next_structure = SendDataPtrNative + primary_structure_size;
  882. while (aux_count--) {
  883. //
  884. // get the total size of the aux data - fixed structure
  885. // length (which we already know) and the variable data
  886. // requirement
  887. //
  888. aux_size = RapTotalSize(
  889. next_structure, // where the 32-bit data lives
  890. AuxDesc32, // convert 32-bit
  891. AuxDesc32, // to 32-bit
  892. FALSE, // pointers NOT meaningless
  893. Both, // ?
  894. NativeToNative // 32-bit to 32-bit
  895. );
  896. TotalStructSize32 += aux_size;
  897. //
  898. // do the same for the 16-bit version of the data
  899. //
  900. aux_size = RapTotalSize(
  901. next_structure, // where the 32-bit data lives
  902. AuxDesc32, // convert 32-bit
  903. AuxDesc16, // to 16-bit
  904. FALSE, // pointers NOT meaningless
  905. Both, // ?
  906. NativeToRap // 32-bit to 16-bit
  907. );
  908. TotalStructSize16 += aux_size;
  909. //
  910. // point to next aux structure (probably only 1 anyway?)
  911. //
  912. next_structure += aux_structure_size;
  913. }
  914. }
  915. IF_DEBUG(CONVARGS) {
  916. NetpKdPrint(( "RxpConvertArgs: total size(32)="
  917. FORMAT_DWORD ".\n", TotalStructSize32 ));
  918. }
  919. NetpAssert(TotalStructSize16 >= FixedStructSize16);
  920. IF_DEBUG(CONVARGS) {
  921. NetpKdPrint(( "RxpConvertArgs: total size(16)="
  922. FORMAT_DWORD ".\n", TotalStructSize16 ));
  923. }
  924. if( TotalStructSize16 > MAX_TRANSACT_SEND_DATA_SIZE )
  925. {
  926. NetpBreakPoint();
  927. return (ERROR_BUFFER_OVERFLOW);
  928. }
  929. *SendDataSizePtr16 = SendSize = TotalStructSize16;
  930. *SendDataPtrPtr16 = pSendData = NetpMemoryAllocate( TotalStructSize16 );
  931. if (pSendData == NULL) {
  932. return ERROR_NOT_ENOUGH_MEMORY;
  933. }
  934. StringLocation = (pSendData) + TotalStructSize16;
  935. IF_DEBUG(CONVARGS) {
  936. NetpKdPrint(("RxpConvertArgs: initial StringLocation is "
  937. FORMAT_LPVOID "\n", (LPVOID) StringLocation ));
  938. NetpKdPrint(("RxpConvertArgs: input data "
  939. "(before CSE, partial):\n"));
  940. NetpDbgHexDump( SendDataPtrNative,
  941. NetpDbgReasonable( TotalStructSize16 ) );
  942. NetpKdPrint(("RxpConvertArgs: output data area "
  943. "(before CSE, partial):\n"));
  944. NetpDbgHexDump( pSendData,
  945. NetpDbgReasonable( TotalStructSize16 ) );
  946. }
  947. //
  948. // This routine calls RapConvertSingleEntry to convert the primary
  949. // data structure, but will also convert any auxiliary structures
  950. //
  951. Status = RxpConvertDataStructures(
  952. DataDesc32, // 32-bit data
  953. DataDesc16, // converted from 16-bit
  954. AuxDesc32, // as are the aux structures
  955. AuxDesc16,
  956. SendDataPtrNative, // where the 32-bit lives
  957. pSendData, // and its new 16-bit address
  958. SendSize, // how big the buffer is
  959. 1, // only 1 primary structure.
  960. NULL, // don't need number of entries converted.
  961. Both, // do entire structure
  962. NativeToRap // explicit 32->16, implicit TCHAR->codepage
  963. );
  964. //
  965. // We allocated the output buffer large enough, so there's no
  966. // reason that conversion should fail.
  967. //
  968. NetpAssert(Status == NERR_Success);
  969. //
  970. // RxpConvertDataStructures calls RapConvertSingleEntry to pack the
  971. // fixed and variable parts of the data into the buffer. The down-
  972. // level server expects the data in the same order as that in which
  973. // it appears in the descriptor strings. RxpPackSendBuffer exists
  974. // to make this so. Do it
  975. //
  976. Status = RxpPackSendBuffer(
  977. (LPVOID *) SendDataPtrPtr16, // possibly reallocated
  978. SendDataSizePtr16, // possibly realloced
  979. &BogusAllocFlag,
  980. DataDesc16,
  981. AuxDesc16,
  982. FixedStructSize16,
  983. AuxOffset,
  984. AuxSize,
  985. ParmNumPresent
  986. );
  987. if (Status != NERR_Success) {
  988. NetpKdPrint(("RxpConvertArgs: pack send buffer failed, stat="
  989. FORMAT_API_STATUS "\n", Status));
  990. return (Status);
  991. }
  992. IF_DEBUG(CONVARGS) {
  993. NetpKdPrint(("RxpConvertArgs: data "
  994. "(after RxpPackSendBuffer):\n"));
  995. NetpDbgHexDump( pSendData, BytesRequired );
  996. }
  997. //
  998. // MOD 06/25/91 RLF
  999. // Remove this, since reallocation takes place. Does it have any other
  1000. // implications?
  1001. //
  1002. // MOD 08/08/91 RLF
  1003. NetpAssert(BogusAllocFlag == FALSE);
  1004. // MOD 08/08/91 RLF
  1005. //
  1006. // MOD 06/25/91 RLF
  1007. //
  1008. } else if (ParmNum) {
  1009. //
  1010. // here if there is a parameter to set. Create a buffer for the data
  1011. // to be sent in the setinfo call. Copy the caller's data into it.
  1012. //
  1013. LPBYTE ptr;
  1014. LPBYTE enddata;
  1015. DWORD bytes_required;
  1016. IF_DEBUG(CONVARGS) {
  1017. NetpKdPrint(( "RxpConvertArgs: parmnum (not all)...\n" ));
  1018. }
  1019. if ((ptr = NetpMemoryAllocate(SendDataSizeNative)) == NULL) {
  1020. return ERROR_NOT_ENOUGH_MEMORY; // gasp!
  1021. }
  1022. //
  1023. // we now convert the data for the single field from 32-bits to
  1024. // 16. Use the descriptors which identify the single field only
  1025. //
  1026. enddata = ptr + SendDataSizeNative;
  1027. bytes_required = 0;
  1028. Status = RapConvertSingleEntry(SendDataPtrNative,
  1029. parm_desc_32,
  1030. FALSE,
  1031. ptr,
  1032. ptr,
  1033. parm_desc_16,
  1034. FALSE,
  1035. &enddata,
  1036. &bytes_required,
  1037. Both,
  1038. NativeToRap
  1039. );
  1040. NetpAssert( Status == NERR_Success );
  1041. #if DBG
  1042. if (!(bytes_required <= SendDataSizeNative)) {
  1043. NetpKdPrint(("error: RxpConvertArgs.%d: "
  1044. "bytes_required=%d, SendDataSizeNative=%d\n"
  1045. "parm_desc_16=%s, parm_desc_32=%s\n",
  1046. __LINE__,
  1047. bytes_required,
  1048. SendDataSizeNative,
  1049. parm_desc_16,
  1050. parm_desc_32
  1051. ));
  1052. }
  1053. NetpAssert(bytes_required <= SendDataSizeNative);
  1054. #endif
  1055. *SendDataPtrPtr16 = ptr;
  1056. //
  1057. // SendDataSizeNative is either the size of the buffer in a "sT"
  1058. // descriptor pair, or was calculated based on the descriptor type
  1059. // and caller's data in a setinfo/parmnum ('P') case
  1060. //
  1061. if ( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  1062. {
  1063. NetpBreakPoint();
  1064. return (ERROR_BUFFER_OVERFLOW);
  1065. }
  1066. *SendDataSizePtr16 = SendDataSizeNative;
  1067. } else {
  1068. LPBYTE ptr;
  1069. //
  1070. // send data, PARMNUM_ALL, data desc is REM_DATA_BLOCK. This can
  1071. // happen with the NetServiceInstall API (see RxApi/SvcInst.c).
  1072. // cbBuffer arg is set by RxNetServiceInstall to be the OUTPUT
  1073. // buffer size, despite the LM 2.x app passing the INPUT size.
  1074. // (We're just propagating another LanMan kludge here.)
  1075. //
  1076. // UniCode to ASCII. The caller should have made this
  1077. // conversion. We only know about unstructured data
  1078. // (ie bytes)
  1079. //
  1080. NetpAssert( ParmNum == PARMNUM_ALL );
  1081. NetpAssert( *DataDesc16 == REM_DATA_BLOCK );
  1082. NetpAssert( SendDataSizeNative > 0 );
  1083. IF_DEBUG(CONVARGS) {
  1084. NetpKdPrint(( "RxpConvertArgs: "
  1085. "copying unstructured data with desc...\n" ));
  1086. }
  1087. //
  1088. // Copy unstructured data and tell caller where it is.
  1089. //
  1090. if ((ptr = NetpMemoryAllocate(SendDataSizeNative)) == NULL) {
  1091. return ERROR_NOT_ENOUGH_MEMORY;
  1092. }
  1093. NetpMoveMemory(
  1094. ptr, // dest
  1095. SendDataPtrNative, // src
  1096. SendDataSizeNative); // size
  1097. *SendDataPtrPtr16 = ptr;
  1098. if ( SendDataSizeNative > MAX_TRANSACT_SEND_DATA_SIZE )
  1099. {
  1100. NetpBreakPoint();
  1101. return (ERROR_BUFFER_OVERFLOW);
  1102. }
  1103. *SendDataSizePtr16 = SendDataSizeNative;
  1104. }
  1105. } // send buffer was specified
  1106. //
  1107. // The parameter buffers and data buffers are now set up for
  1108. // sending to the API worker so tell the caller.
  1109. //
  1110. *CurrentInputBlockSizePtr = CurrentInputBlockSize;
  1111. *CurrentOutputBlockSizePtr = CurrentOutputBlockSize;
  1112. *CurrentOutputBlockPtrPtr = CurrentOutputBlockPtr;
  1113. return NERR_Success;
  1114. } // RxpConvertArgs
  1115. DBGSTATIC
  1116. DWORD
  1117. RxpGetFieldSize(
  1118. IN LPBYTE Field,
  1119. IN LPDESC FieldDesc
  1120. )
  1121. {
  1122. NetpAssert(Field != NULL);
  1123. NetpAssert(FieldDesc != NULL);
  1124. if (*FieldDesc == REM_ASCIZ) {
  1125. return STRSIZE((LPTSTR)Field);
  1126. } else {
  1127. LPDESC TempDescPtr = FieldDesc;
  1128. return RapGetFieldSize(FieldDesc, &TempDescPtr, Both);
  1129. }
  1130. } // RxpGetFieldSize
  1131. DBGSTATIC
  1132. LPDESC
  1133. RxpGetSetInfoDescriptor(
  1134. IN LPDESC Descriptor,
  1135. IN DWORD FieldIndex,
  1136. IN BOOL Is32BitDesc
  1137. )
  1138. /*++
  1139. Routine Description:
  1140. Allocates a descriptor string which describes a single parameter element
  1141. of a structure, for SetInfo calls (where ParmNum != PARMNUM_ALL)
  1142. Arguments:
  1143. Descriptor - The full descriptor string for the relevant structure
  1144. FieldIndex - The ORDINAL number of the field (NOT ParmNum)
  1145. Is32BitDesc - Descriptor defines 16-bit data
  1146. Return Value:
  1147. Pointer to allocated descriptor or NULL if error
  1148. --*/
  1149. {
  1150. LPDESC lpdesc;
  1151. lpdesc = RapParmNumDescriptor(Descriptor, FieldIndex, Both, Is32BitDesc);
  1152. if (lpdesc == NULL) {
  1153. #if DBG
  1154. //
  1155. // don't expect this to happen - trap it in debug version
  1156. //
  1157. NetpKdPrint(("error: RxpGetSetInfoDescriptor: RapParmNumDescriptor didn't allocate string\n"));
  1158. NetpBreakPoint();
  1159. #endif
  1160. } else if (*lpdesc == REM_UNSUPPORTED_FIELD) {
  1161. #if DBG
  1162. //
  1163. // don't expect this to happen - trap it in debug version
  1164. //
  1165. NetpKdPrint(("error: RxpGetSetInfoDescriptor: parameter defines unsupported field\n"));
  1166. NetpBreakPoint();
  1167. #endif
  1168. NetpMemoryFree(lpdesc);
  1169. lpdesc = NULL;
  1170. }
  1171. return lpdesc;
  1172. }