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.

500 lines
14 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. msgutil.c
  5. Abstract:
  6. This module contains the common utility routines for needed to
  7. implement the NetMessageBufferSend API.
  8. Author:
  9. Rita Wong (ritaw) 26-July-1991
  10. Revision History:
  11. Terence Kwan (terryk) 20-Oct-1993
  12. Shut down the system iff we initiailize the system successfully.
  13. --*/
  14. #include "ws.h"
  15. #include "wsconfig.h" // WsInfo.WsComputerName
  16. #include "wsmsg.h"
  17. #include "wsmain.h"
  18. #include <stdarg.h>
  19. //
  20. // Global variables
  21. //
  22. //
  23. // Information structure which contains the number of networks, the adapter
  24. // numbers of the networks, an array of computer name numbers, and an array
  25. // of broadcast name numbers.
  26. //
  27. WSNETWORKS WsNetworkInfo;
  28. // Flag for initialization
  29. BOOL fInitialize = FALSE;
  30. NET_API_STATUS
  31. WsInitializeMessageSend(
  32. BOOLEAN FirstTime
  33. )
  34. /*++
  35. Routine Description:
  36. This function initializes the Workstation service to send messages using
  37. NetBIOS by adding the computername to every network adapter (both logical
  38. and physical network).
  39. Arguments:
  40. FirstTime - Flag to indicate first time initialization. This routine may be called
  41. later to reinitialize netbios configuration.
  42. Return Value:
  43. NET_API_STATUS - NERR_Success or reason for failure.
  44. --*/
  45. {
  46. NET_API_STATUS status;
  47. UCHAR Index;
  48. CHAR NetBiosName[NCBNAMSZ];
  49. //
  50. // Get the adapter numbers of networks
  51. //
  52. status = NetpNetBiosGetAdapterNumbers(
  53. &(WsNetworkInfo.LanAdapterNumbers),
  54. sizeof(LANA_ENUM)
  55. );
  56. if (status != NERR_Success) {
  57. //
  58. // Fatal error: Log error with NELOG_NetBios
  59. //
  60. IF_DEBUG(MESSAGE) {
  61. NetpKdPrint((
  62. "[Wksta] Error enumerating LAN adapters. "
  63. "Ignore if no UB card.\n"
  64. ));
  65. }
  66. return status;
  67. }
  68. //
  69. // Make the computer name a message type NetBIOS name
  70. //
  71. if ((status = NetpStringToNetBiosName(
  72. NetBiosName,
  73. WsInfo.WsComputerName,
  74. NAMETYPE_MESSAGEDEST,
  75. WKSTA_TO_MESSAGE_ALIAS_TYPE
  76. )) != NERR_Success) {
  77. return status;
  78. }
  79. //
  80. // Add the computer name (message alias) to every network managed by
  81. // the redirector, excluding the loopback network.
  82. //
  83. if (FirstTime) {
  84. WsLmsvcsGlobalData->NetBiosOpen();
  85. }
  86. for (Index = 0; Index < WsNetworkInfo.LanAdapterNumbers.length; Index++) {
  87. //
  88. // Reset the adapter first
  89. //
  90. if (WsLmsvcsGlobalData->NetBiosReset(WsNetworkInfo.LanAdapterNumbers.lana[Index])
  91. != NERR_Success) {
  92. IF_DEBUG(MESSAGE) {
  93. NetpKdPrint((
  94. "[Wksta] Error reseting LAN adapter number %u.\n"
  95. " Ignore if no UB card.\n",
  96. WsNetworkInfo.LanAdapterNumbers.lana[Index]
  97. ));
  98. }
  99. continue;
  100. }
  101. IF_DEBUG(MESSAGE) {
  102. NetpKdPrint(("[Wksta] About to add name on adapter number %u\n",
  103. WsNetworkInfo.LanAdapterNumbers.lana[Index]));
  104. }
  105. status = NetpNetBiosAddName(
  106. NetBiosName,
  107. WsNetworkInfo.LanAdapterNumbers.lana[Index],
  108. &WsNetworkInfo.ComputerNameNumbers[Index]
  109. );
  110. if (status != NERR_Success && status != NERR_AlreadyExists) {
  111. //
  112. // Fatal error: Log error with NELOG_NetBios
  113. //
  114. IF_DEBUG(MESSAGE) {
  115. NetpKdPrint((
  116. "[Wksta] Error adding computername to LAN "
  117. "Adapter number %u.\n Ignore if no UB card.\n",
  118. WsNetworkInfo.LanAdapterNumbers.lana[Index]
  119. ));
  120. }
  121. return status;
  122. }
  123. }
  124. // Initialize okay
  125. fInitialize = TRUE;
  126. return NERR_Success;
  127. }
  128. VOID
  129. WsShutdownMessageSend(
  130. VOID
  131. )
  132. /*++
  133. Routine Description:
  134. This function shuts down the Workstation service message send
  135. functionality by asking NetBIOS to delete the computername that
  136. was added to every network adapter.
  137. Arguments:
  138. None
  139. Return Value:
  140. None.
  141. --*/
  142. {
  143. // We shut down the component if and only if we successfully initialize
  144. // the system
  145. if ( fInitialize )
  146. {
  147. NET_API_STATUS status;
  148. UCHAR Index;
  149. CHAR NetBiosName[NCBNAMSZ];
  150. //
  151. // Make the computer name a message type NetBIOS name
  152. //
  153. if ((status = NetpStringToNetBiosName(
  154. NetBiosName,
  155. WsInfo.WsComputerName,
  156. NAMETYPE_MESSAGEDEST,
  157. WKSTA_TO_MESSAGE_ALIAS_TYPE
  158. )) != NERR_Success) {
  159. return;
  160. }
  161. //
  162. // Delete the computer name (message alias) from every network.
  163. //
  164. for (Index = 0; Index < WsNetworkInfo.LanAdapterNumbers.length; Index++) {
  165. (void) NetpNetBiosDelName(
  166. NetBiosName,
  167. WsNetworkInfo.LanAdapterNumbers.lana[Index]
  168. );
  169. }
  170. WsLmsvcsGlobalData->NetBiosClose();
  171. }
  172. }
  173. WORD
  174. WsMakeSmb(
  175. OUT PUCHAR SmbBuffer,
  176. IN UCHAR SmbFunctionCode,
  177. IN WORD NumberOfParameters,
  178. IN PCHAR FieldsDopeVector,
  179. ...
  180. )
  181. /*++
  182. Routine Description:
  183. This function builds a Server Message Block. It takes a variable
  184. number of arguments, but the first 4 are required to be present.
  185. If NumberOfParameters is some non-zero value, n, then immediately
  186. following the 4 required arguments there will be n WORD
  187. parameters.
  188. Arguments:
  189. SmbBuffer - Returns the Server Message Block in the supplied buffer.
  190. SmbFunctionCode - Supplies the function code for the command.
  191. NumberOfParameters - Supplies the number of WORD parameters passed
  192. to this routine immediately following the first 4 required parameters.
  193. FieldsDopeVector - Supplies an ASCIIZ string where each character of the
  194. string describes the remaining parameters:
  195. 's' - the next argument is a pointer to a null-terminated string
  196. which is to be copied into the SMB prefixed by a byte
  197. containing '\004'.
  198. 'b' - the next argument is a WORD specifying a length,
  199. and it is followed by a pointer to a buffer whose contents
  200. are to be placed in the SMB prefixed by a byte containing
  201. '\001' and a WORD containing the length.
  202. 't' - the next argument is a WORD specifying a length,
  203. and it is followed by a pointer to a text buffer whose
  204. contents are to be placed in the SMB prefixed by a byte
  205. containing '\001' and a WORD containg the length.
  206. This is the same as 'b' except that <CRLF>,<LFCR>,<CR>,<LF>
  207. are all converted to a single '\024' character.
  208. Return Value:
  209. Returns the length in bytes of the SMB created in SmbBuffer.
  210. Assumptions:
  211. The supplied SmbBuffer is large enough for the SMB created.
  212. --*/
  213. {
  214. va_list ArgList; // Argument List
  215. PSMB_HEADER Smb; // SMB header pointer
  216. PUCHAR SmbBufferPointer;
  217. PUCHAR LengthPointer; // length pointer
  218. PCHAR TextPointer; // Text pointer
  219. WORD TextBufferSize; // Size of SMB data to send
  220. WORD i; // Text loop index
  221. WORD Length; // Length after text conversion or
  222. // length of the buffer portion
  223. va_start(ArgList, FieldsDopeVector); // Init ArgList
  224. RtlZeroMemory((PVOID) SmbBuffer, WS_SMB_BUFFER_SIZE);
  225. Smb = (PSMB_HEADER) SmbBuffer;
  226. Smb->Protocol[0] = 0xff; // Message type
  227. Smb->Protocol[1] = 'S'; // Server
  228. Smb->Protocol[2] = 'M'; // Message
  229. Smb->Protocol[3] = 'B'; // Block
  230. Smb->Command = SmbFunctionCode; // Set function code
  231. //
  232. // Skip over SMB header
  233. //
  234. SmbBufferPointer = &SmbBuffer[sizeof(SMB_HEADER)];
  235. //
  236. // Set parameter count
  237. //
  238. *SmbBufferPointer++ = (UCHAR) NumberOfParameters;
  239. while (NumberOfParameters--) {
  240. short Parameters = va_arg(ArgList, short);
  241. //
  242. // Put parameters in the SMB
  243. //
  244. //
  245. // Assign message group id
  246. //
  247. *(SmbBufferPointer)++ = ((PUCHAR) &Parameters)[0];
  248. *(SmbBufferPointer)++ = ((PUCHAR) &Parameters)[1];
  249. }
  250. //
  251. // Save the pointer
  252. //
  253. Smb = (PSMB_HEADER) SmbBufferPointer;
  254. //
  255. // Skip data length field. After the rest of buffer is filled
  256. // in, we will come back to set the length of the data.
  257. //
  258. SmbBufferPointer += sizeof(WORD);
  259. while (*FieldsDopeVector != '\0') {
  260. switch (*FieldsDopeVector++) {
  261. case 's':
  262. //
  263. // Null-terminated string
  264. //
  265. //
  266. // Set buffer type code
  267. //
  268. *SmbBufferPointer++ = '\004';
  269. //
  270. // Copy string into SMB buffer
  271. //
  272. strcpy(SmbBufferPointer, va_arg(ArgList, LPSTR));
  273. //
  274. // Increment pointer past string and null terminator
  275. //
  276. SmbBufferPointer += strlen(SmbBufferPointer) + 1;
  277. break;
  278. case 'b':
  279. //
  280. // Length-prefixed buffer
  281. //
  282. //
  283. // Set buffer type code
  284. //
  285. *SmbBufferPointer++ = '\001';
  286. //
  287. // Get buffer size
  288. //
  289. TextBufferSize = va_arg(ArgList, WORD);
  290. //
  291. // Set the buffer length
  292. //
  293. *(SmbBufferPointer)++ = ((PUCHAR) &TextBufferSize)[0];
  294. *(SmbBufferPointer)++ = ((PUCHAR) &TextBufferSize)[1];
  295. //
  296. // Move data into SMB buffer
  297. //
  298. memcpy(SmbBufferPointer, va_arg(ArgList, PUCHAR), TextBufferSize);
  299. //
  300. // Increment buffer pointer
  301. //
  302. SmbBufferPointer += TextBufferSize;
  303. break;
  304. case 't':
  305. //
  306. // Length-prefixed text buffer
  307. //
  308. *SmbBufferPointer++ = '\001';
  309. //
  310. // Get non converted text length
  311. //
  312. TextBufferSize = va_arg(ArgList, WORD);
  313. IF_DEBUG(MESSAGE) {
  314. NetpKdPrint(("[Wksta] WsMakeSmb TexBufferSize=%u\n",
  315. TextBufferSize));
  316. }
  317. TextPointer = va_arg(ArgList, PCHAR);
  318. //
  319. // Where to put modified text length
  320. //
  321. LengthPointer = SmbBufferPointer;
  322. SmbBufferPointer += sizeof(WORD);
  323. //
  324. // Now copy the text into the buffer converting all occurences
  325. // of <CRLF>, <LFCR>, <CR>, <LF> to '\024'
  326. //
  327. for (i = 0, Length = 0; i < TextBufferSize; i++) {
  328. if (*TextPointer == '\n') {
  329. //
  330. // Convert to IBM end of line
  331. //
  332. *SmbBufferPointer++ = '\024';
  333. TextPointer++;
  334. Length++;
  335. //
  336. // Ignore LF following CR
  337. //
  338. if (*TextPointer == '\r') {
  339. TextPointer++;
  340. i++;
  341. }
  342. }
  343. else if (*TextPointer == '\r') {
  344. //
  345. // Convert to IBM end of line
  346. //
  347. *SmbBufferPointer++ = '\024';
  348. TextPointer++;
  349. Length++;
  350. //
  351. // Ignore CR following LF
  352. //
  353. if (*(TextPointer) == '\n') {
  354. TextPointer++;
  355. i++;
  356. }
  357. }
  358. else {
  359. *SmbBufferPointer++ = *TextPointer++;
  360. Length++;
  361. }
  362. }
  363. //
  364. // Set the buffer length
  365. //
  366. *(LengthPointer)++ = ((PUCHAR) &Length)[0];
  367. *(LengthPointer)++ = ((PUCHAR) &Length)[1];
  368. break;
  369. }
  370. }
  371. va_end(ArgList);
  372. //
  373. // Set length of buffer portion
  374. //
  375. Length = (WORD) ((DWORD) (SmbBufferPointer - (PUCHAR) Smb) - sizeof(WORD));
  376. *((PUCHAR) Smb)++ = ((PUCHAR) &Length)[0];
  377. *((PUCHAR) Smb)++ = ((PUCHAR) &Length)[1];
  378. //
  379. // Return length of SMB
  380. //
  381. return (WORD) (SmbBufferPointer - SmbBuffer);
  382. }