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.

263 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. Start.c
  5. Abstract:
  6. RxpStartBuildingTransaction builds the first part of the transaction
  7. SMB which will be used with the Remote Admin Protocol to perform an
  8. API on a downlevel server.
  9. Author:
  10. John Rogers (JohnRo) 01-Apr-1991
  11. Environment:
  12. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  13. Requires ANSI C extensions: slash-slash comments, long external names.
  14. Revision History:
  15. 01-Apr-1991 JohnRo
  16. Created.
  17. 04-Apr-1991 JohnRo
  18. Quiet debug output by default.
  19. 03-May-1991 JohnRo
  20. Indicate that data descriptor is SMB version (no Q's or U's).
  21. Added test for valid SMB descriptor. Reduced recompile hits from
  22. header files. Fix transaction SMB when no data desc is present.
  23. Clarify that buffer is really used as OUT.
  24. 15-May-1991 JohnRo
  25. Added native vs. RAP handling.
  26. 28-May-1991 JohnRo
  27. Don't be so aggressive checking buffer size, because this may be
  28. a set info API. Also, use DESCLEN() instead of strlen().
  29. 17-Jul-1991 JohnRo
  30. Extracted RxpDebug.h from Rxp.h.
  31. 21-Nov-1991 JohnRo
  32. Removed NT dependencies to reduce recompiles.
  33. 27-Nov-1991 JohnRo
  34. Do some checking of ApiNumber.
  35. 31-Mar-1992 JohnRo
  36. Prevent too large size requests.
  37. 06-May-1993 JohnRo
  38. RAID 8849: Export RxRemoteApi for DEC and others.
  39. Use NetpKdPrint() where possible.
  40. Use PREFIX_ equates.
  41. Made some changes suggested by CliffV way back when.
  42. --*/
  43. // These must be included first:
  44. #include <windef.h> // IN, DWORD, LPTSTR, etc.
  45. #include <rxp.h> // My prototype, MAX_TRANSACT_ equates, etc.
  46. // These may be included in any order:
  47. #include <lmerr.h> // NERR_ and ERROR_ equates.
  48. #include <netdebug.h> // NetpKdPrint(), FORMAT_ equates, etc.
  49. #include <netlib.h> // NetpMoveMemory(), etc.
  50. #include <prefix.h> // PREFIX_ equates.
  51. #include <rap.h> // LPDESC, DESC_CHAR, DESC_LEN().
  52. #include <rxpdebug.h> // IF_DEBUG().
  53. NET_API_STATUS
  54. RxpStartBuildingTransaction(
  55. OUT LPVOID Buffer,
  56. IN DWORD BufferLength,
  57. IN DWORD ApiNumber,
  58. IN LPDESC ParmDesc,
  59. IN LPDESC DataDescSmb OPTIONAL,
  60. OUT LPVOID *RovingOutputPointer,
  61. OUT LPDWORD LengthSoFarPointer,
  62. OUT LPVOID *LastStringPointer OPTIONAL,
  63. OUT LPDESC *ParmDescCopyPointer OPTIONAL
  64. )
  65. /*++
  66. Routine Description:
  67. RxpStartBuildingTransaction builds the initial part of a transaction
  68. SMB for RpcXlate.
  69. Arguments:
  70. Buffer - Address of the buffer to be built. There should be nothing in
  71. this area before calling this routine.
  72. BufferLength - Size of the area at Buffer (in bytes).
  73. ApiNumber - The number of the API.
  74. ParmDesc - The descriptor string for the API's parameters (16-bit version).
  75. DataDescSmb - The optional descriptor string for the API's data (SMB
  76. version).
  77. RovingOutputPointer - This will be set to point to the first available
  78. location after the items which this routine places in the buffer.
  79. LengthSoFarPointer - Points to a DWORD which will be updated with the
  80. number of bytes used by this routine.
  81. LastStringPointer - Optionally points to a pointer which will be set to
  82. point to an area (at the end of the buffer) to be filled-in with
  83. variable-length data (e.g. strings).
  84. ParmDescCopyPointer - Optionally points to a pointer which will be set with
  85. the location of the copy of ParmDesc in the buffer.
  86. Return Value:
  87. NET_API_STATUS - NERR_Success or NERR_NoRoom.
  88. --*/
  89. {
  90. DWORD CurrentLength;
  91. LPVOID CurrentPointer;
  92. DWORD DescSize;
  93. DWORD FixedLengthRequired;
  94. //
  95. // Make sure API number doesn't get truncated.
  96. // Note that we can't check against the MAX_API equate anymore, as
  97. // that only includes APIs which we know about. Now that RxRemoteApi is
  98. // being exported for use by anyone, we don't know the maximum API number
  99. // which the app might be using.
  100. //
  101. if ( ((DWORD)(WORD)ApiNumber) != ApiNumber ) {
  102. NetpKdPrint(( PREFIX_NETAPI
  103. "RxpStartBuildingTransaction: API NUMBER "
  104. "(" FORMAT_HEX_DWORD ") TOO LARGE, "
  105. "returning ERROR_INVALID_PARAMETER.\n",
  106. ApiNumber ));
  107. return (ERROR_INVALID_PARAMETER);
  108. }
  109. //
  110. // Check for other caller errors.
  111. //
  112. NetpAssert( Buffer != NULL );
  113. // BufferLength checked below.
  114. NetpAssert( ParmDesc != NULL );
  115. NetpAssert( RovingOutputPointer != NULL);
  116. NetpAssert( LengthSoFarPointer != NULL);
  117. //
  118. // Make sure caller has allocated enough room.
  119. //
  120. FixedLengthRequired = sizeof(WORD) // api number
  121. + DESCLEN(ParmDesc) + sizeof(char); // parm str and null
  122. if (DataDescSmb != NULL) {
  123. // Make sure data descriptor and null will fit in buffer.
  124. FixedLengthRequired += DESCLEN(DataDescSmb) + sizeof(char);
  125. // Note that we used to check that the entire structure defined by
  126. // the data descriptor would fit in the buffer. However, this could
  127. // be a set info API, which passes the entire descriptor but might
  128. // only need space for one field. So we just do a minimal check now.
  129. FixedLengthRequired += sizeof(BYTE); // smallest field.
  130. } else {
  131. FixedLengthRequired += sizeof(char); // null (no data desc)
  132. }
  133. IF_DEBUG(START) {
  134. NetpKdPrint(( PREFIX_NETAPI
  135. "RxpStartBuildingTransaction: fixed len=" FORMAT_DWORD
  136. ", buff len=" FORMAT_DWORD ".\n",
  137. FixedLengthRequired, BufferLength ));
  138. }
  139. if (FixedLengthRequired > BufferLength) {
  140. return (NERR_NoRoom);
  141. }
  142. NetpAssert( BufferLength <= MAX_TRANSACT_SEND_PARM_SIZE );
  143. //
  144. // Initialize current variables, which we'll update as we go along.
  145. //
  146. CurrentPointer = Buffer; /* Start of parameter buffer */
  147. CurrentLength = 0;
  148. //
  149. // Copy the API number into the first word.
  150. //
  151. SmbPutUshort( (LPWORD) CurrentPointer, (WORD) ApiNumber );
  152. CurrentLength += sizeof(WORD); // Update buffer ptr & length.
  153. CurrentPointer = NetpPointerPlusSomeBytes(CurrentPointer, sizeof(WORD));
  154. IF_DEBUG(START) {
  155. NetpKdPrint(( PREFIX_NETAPI
  156. "RxpStartBuildingTransaction: Done API number.\n" ));
  157. }
  158. //
  159. // Copy the 16-bit version of the parm descriptor string next.
  160. //
  161. NetpAssert(RapIsValidDescriptorSmb(ParmDesc));
  162. DescSize = DESCLEN(ParmDesc) + 1; // Length of parm desc.
  163. NetpAssert(sizeof(DESC_CHAR) == 1);
  164. NetpMoveMemory(
  165. CurrentPointer, // dest
  166. ParmDesc, // src
  167. DescSize); // byte count
  168. if (ParmDescCopyPointer != NULL) {
  169. *ParmDescCopyPointer = CurrentPointer;
  170. }
  171. CurrentLength += DescSize; // Add to total length.
  172. CurrentPointer = NetpPointerPlusSomeBytes(CurrentPointer, DescSize);
  173. IF_DEBUG(START) {
  174. NetpKdPrint(( PREFIX_NETAPI
  175. "RxpStartBuildingTransaction: Done parm desc.\n" ));
  176. }
  177. //
  178. // Copy the SMB version of the data descriptor string next.
  179. //
  180. if (DataDescSmb != NULL) {
  181. NetpAssert(RapIsValidDescriptorSmb(DataDescSmb));
  182. DescSize = strlen(DataDescSmb) + 1; // Length of data desc.
  183. NetpMoveMemory(
  184. CurrentPointer, // dest
  185. DataDescSmb, // src
  186. DescSize); // byte count
  187. } else {
  188. DescSize = 1; // Only end of string.
  189. * (LPBYTE) CurrentPointer = '\0'; // Null at end of string.
  190. }
  191. CurrentLength += DescSize; // Add to total length.
  192. CurrentPointer = NetpPointerPlusSomeBytes(CurrentPointer, DescSize);
  193. IF_DEBUG(START) {
  194. NetpKdPrint(( PREFIX_NETAPI
  195. "RxpStartBuildingTransaction: Done data desc (if any).\n" ));
  196. }
  197. //
  198. // Tell caller what we did.
  199. //
  200. *RovingOutputPointer = CurrentPointer;
  201. *LengthSoFarPointer = CurrentLength;
  202. if (LastStringPointer != NULL) {
  203. *LastStringPointer =
  204. NetpPointerPlusSomeBytes(
  205. Buffer,
  206. BufferLength);
  207. }
  208. IF_DEBUG(START) {
  209. NetpKdPrint(( PREFIX_NETAPI
  210. "RxpStartBuildingTransaction: Done setting outputs.\n" ));
  211. }
  212. return (NERR_Success);
  213. } // RxpStartBuildingTransaction