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.

368 lines
9.2 KiB

  1. /*--
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. grpmsngr.c
  5. Abstract:
  6. This file contains the routines that provide support for messaging
  7. in a multi-domaign lan. These routines comprise the group message thread
  8. of the messenger service. The support of domain messaging is broken up
  9. into two phases. The first, which takes place at initialization time of
  10. the messenger, sets up a mailslot thru which the second phase receives the
  11. information that it will need to process. The second, phase, which runs
  12. in parallel with the existing messenger thread, reads messages out of this
  13. mailslot and logs them.
  14. Author:
  15. Dan Lafferty (danl) 17-Jul-1991
  16. Environment:
  17. User Mode -Win32
  18. Notes:
  19. These routines receive and manipulate ansi strings, not UNICODE strings.
  20. The ANSI to UNICODE translation will be done in logsmb().
  21. Revision History:
  22. 17-Jul-1991 danl
  23. ported from LM2.0
  24. --*/
  25. #include "msrv.h"
  26. #include <string.h>
  27. #include <stdio.h>
  28. #include <netlib.h> // UNUSED macro
  29. #include "msgdbg.h" // MSG_LOG
  30. #include "msgdata.h"
  31. //
  32. // GLOBALS
  33. //
  34. LPSTR DieMessage = "DIE";
  35. extern HANDLE g_hGrpEvent;
  36. //
  37. // PROTOTYPES of internal functions
  38. //
  39. STATIC VOID
  40. MsgDisectMessage(
  41. IN LPSTR message,
  42. OUT LPSTR *from,
  43. OUT LPSTR *to,
  44. IN LPSTR text);
  45. //
  46. // Defines
  47. //
  48. //
  49. // Size of mailslot messages (bytes)
  50. //
  51. #define MESSNGR_MS_MSIZE 512
  52. //
  53. // size of mailslot (bytes)
  54. //
  55. #define MESSNGR_MS_SIZE (5*MESSNGR_MS_MSIZE)
  56. static char Msg_Buf[MESSNGR_MS_MSIZE + 3]; // Buffer for messages + 3 NULs
  57. static OVERLAPPED Overlapped;
  58. static DWORD bytes_read = 0;
  59. NET_API_STATUS
  60. MsgInitGroupSupport(DWORD iGrpMailslotWakeupSem)
  61. {
  62. DWORD err = 0; // Error code info from the group processor.
  63. GrpMailslotHandle = CreateMailslotA(
  64. MESSNGR_MS_NAME, // lpName
  65. MESSNGR_MS_MSIZE, // nMaxMessageSize
  66. MAILSLOT_WAIT_FOREVER, // lReadTimeout
  67. NULL); // lpSecurityAttributes
  68. if (GrpMailslotHandle == INVALID_HANDLE_VALUE) {
  69. err = GetLastError();
  70. MSG_LOG(ERROR,"GroupMsgProcessor: CreateMailslot FAILURE %d\n",
  71. err);
  72. }
  73. else {
  74. MSG_LOG1(GROUP,"InitGroupSupport: MailSlotHandle = 0x%lx\n",
  75. GrpMailslotHandle);
  76. }
  77. return err;
  78. }
  79. VOID
  80. MsgReadGroupMailslot(
  81. VOID
  82. )
  83. {
  84. NET_API_STATUS Err = 0;
  85. //
  86. // Clean out receive buffers before each message
  87. //
  88. memset(Msg_Buf, 0, sizeof(Msg_Buf));
  89. memset(&Overlapped, 0, sizeof(Overlapped));
  90. //
  91. // If this handle is no longer good, it means the
  92. // mailslot system is down. So we can't go on using
  93. // mailslots in the messenger. Therefore, we want to
  94. // ignore the error and shutdown this thread anyhow.
  95. //
  96. ReadFile(GrpMailslotHandle,
  97. Msg_Buf,
  98. sizeof(Msg_Buf) - 3, // Leave 3 NULs at the end (see MsgDisectMessage)
  99. &bytes_read,
  100. &Overlapped);
  101. return;
  102. }
  103. NET_API_STATUS
  104. MsgServeGroupMailslot()
  105. {
  106. LPSTR from;
  107. LPSTR to;
  108. CHAR text[MAXGRPMSGLEN+3]; // +3 is for length word at
  109. // start of string (for
  110. // logsbm) and for NULL
  111. // terminator at end. NOTE:
  112. // disect_message() below
  113. // makes assumptions about
  114. // the length of this array.
  115. DWORD code;
  116. //
  117. // Process the message
  118. //
  119. if( !GetOverlappedResult( GrpMailslotHandle,
  120. &Overlapped,
  121. &bytes_read,
  122. TRUE ) ) {
  123. MSG_LOG1(ERROR,"MsgServeGroupMailslot: GetOverlappedResult failed %d\n",
  124. GetLastError());
  125. return(GetMsgrState());
  126. }
  127. //
  128. // Check for Shutdown...
  129. //
  130. if ((bytes_read == 4) && (strcmp(Msg_Buf, DieMessage)==0)) {
  131. return(GetMsgrState());
  132. }
  133. MSG_LOG(TRACE,"MailSlot Message Received\n",0);
  134. MsgDisectMessage( Msg_Buf, &from, &to, text );
  135. if (g_IsTerminalServer)
  136. {
  137. Msglogsbm (from, to, text, (ULONG)EVERYBODY_SESSION_ID);
  138. }
  139. else
  140. {
  141. Msglogsbm (from, to, text, 0);
  142. }
  143. return(RUNNING);
  144. }
  145. /* Function: MsgDisectMessage
  146. *
  147. * This function isolates the details of the structure of the message
  148. * that gets sent through the mailslot from the rest of the thread. Given
  149. * the message buffer, this routine fills in the module globals From, To
  150. * and Text with the proper parts of the message.
  151. *
  152. * ENTRY
  153. *
  154. * Expects one argument, which is a pointer to the buffer containing
  155. * the message.
  156. *
  157. * EXIT
  158. *
  159. * This function does not return a value.
  160. *
  161. * SIDE EFFECTS
  162. *
  163. * Modifies the variables from, to and text. The Msg_Buf
  164. * may also be modified.
  165. * Assumes the length of Text is at least MAXGRPMSGLEN+3.
  166. *
  167. */
  168. VOID
  169. MsgDisectMessage(
  170. IN LPSTR message,
  171. OUT LPSTR *from,
  172. OUT LPSTR *to,
  173. IN LPSTR text)
  174. {
  175. LPSTR txt_ptr;
  176. PSHORT size_ptr;
  177. //
  178. // Note that message (a.k.a. Msg_Buf) is always triple-NUL terminated,
  179. // so calling strlen twice and adding 1 will always succeed, even if
  180. // the message isn't properly NUL-terminated (in that case, "from" will
  181. // point to all the text in the buffer and both "to" and "text will
  182. // point to empty strings).
  183. //
  184. *from = message;
  185. *to = (*from) + strlen(*from) +1;
  186. txt_ptr = (*to) + strlen(*to) +1;
  187. text[2] = '\0';
  188. strncpy(text+2, txt_ptr, MAXGRPMSGLEN);
  189. //
  190. // make sure it is NULL terminated
  191. //
  192. text[MAXGRPMSGLEN+2] = '\0';
  193. //
  194. // The first two bytes in the text buffer are to contain the length
  195. // the message. (in bytes).
  196. //
  197. size_ptr = (PSHORT)text;
  198. *size_ptr = (SHORT)strlen(text+2);
  199. }
  200. VOID
  201. MsgGrpThreadShutdown(
  202. VOID
  203. )
  204. /*++
  205. Routine Description:
  206. This routine wakes up the wait on the Group Mailslot handle.
  207. Arguments:
  208. none
  209. Return Value:
  210. none
  211. --*/
  212. {
  213. DWORD i;
  214. DWORD numWritten;
  215. HANDLE mailslotHandle;
  216. // If already stopped, don't bother
  217. if (GrpMailslotHandle == INVALID_HANDLE_VALUE) {
  218. MSG_LOG0(TRACE,"MsgGroupThreadShutdown: Group Thread has completed\n");
  219. return;
  220. }
  221. //
  222. // Wake up the Group Thread by sending "DIE" to its mailbox.
  223. //
  224. MSG_LOG(TRACE,"MsgThreadWakeup:Wake up Group Thread & tell it to DIE\n",0);
  225. mailslotHandle = CreateFileA (
  226. MESSNGR_MS_NAME, // lpFileName
  227. GENERIC_WRITE, // dwDesiredAccess
  228. FILE_SHARE_WRITE | FILE_SHARE_READ, // dwShareMode
  229. NULL, // lpSecurityAttributes
  230. OPEN_EXISTING, // dwCreationDisposition
  231. FILE_ATTRIBUTE_NORMAL, // dwFileAttributes
  232. 0L); // hTemplateFile
  233. if (mailslotHandle == INVALID_HANDLE_VALUE) {
  234. //
  235. // A failure occured. It is assumed that the mailslot hasn't
  236. // been created yet. In which case, the GrpMessageProcessor will
  237. // check the MsgrState directly after it creates the Mailslot and
  238. // will shut down as required.
  239. //
  240. MSG_LOG(TRACE,"MsgThreadWakeup: CreateFile on Mailslot Failed %d\n",
  241. GetLastError());
  242. //
  243. // Deregister the group work item lest the mailslot handle get closed
  244. // while the thread pool is still waiting on it when this function returns
  245. //
  246. DEREGISTER_WORK_ITEM(g_hGrpEvent);
  247. return;
  248. }
  249. MSG_LOG(TRACE,"MsgGroupThreadShutdown: MailSlotHandle = 0x%lx\n",mailslotHandle);
  250. if ( !WriteFile (
  251. mailslotHandle,
  252. DieMessage,
  253. strlen(DieMessage)+1,
  254. &numWritten,
  255. NULL)) {
  256. MSG_LOG(TRACE,"MsgThreadWakeup: WriteFile on Mailslot Failed %d\n",
  257. GetLastError())
  258. //
  259. // Since we can't wake up the group thread,
  260. // deregister the work item here instead
  261. //
  262. DEREGISTER_WORK_ITEM(g_hGrpEvent);
  263. }
  264. CloseHandle(mailslotHandle);
  265. //
  266. // Wait for the group messenger to be shutdown.
  267. // We will wait up to 20.300 seconds for this before going on.
  268. //
  269. Sleep(300);
  270. for (i=0; i<20; i++) {
  271. if (GrpMailslotHandle == INVALID_HANDLE_VALUE) {
  272. MSG_LOG0(TRACE,"MsgGroupThreadShutdown: Group Thread has completed\n");
  273. break;
  274. }
  275. MSG_LOG1(TRACE,"MsgGroupThreadShutdown: Group Thread alive after %d seconds\n",
  276. (i + 1) * 1000);
  277. Sleep(1000);
  278. }
  279. return;
  280. }