Visual Basic Network Services
WriteFile: Broadcasting System Messages using Mailslots
Posted:   Thursday October 10. 2002
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows XP
OS restrictions:   None
Author:   VBnet - Randy Birch


NetMessageBufferSend: Broadcasting System Messages
None. This code will broadcast to, and can be run on, both 9x and NT-based systems. To receive broadcasts on 9x/ME, WinPopup must be running.

Where system admins had wanted to send system-wide broadcasts of alert notifications to other computers (ala Net Send), VBnet has up till now only offered the NT-based NetMessageBufferSend solution.

This page details another method that does exactly the same thing as NetMessageBufferSend. But unlike NetMessageBufferSend: Broadcasting System Messages this method uses APIs and functionality native to all versions of Windows - the code here can be run on a 95, 98, ME, NT, 2000, XP or .Net server system to send messages to any other system. However, in order to receive the messages on 9x, the WinPopup must be running.

Mailslots are used for interprocess communications -- mailslots broadcast messages within a domain. If several processes in a domain each create a mailslot using the same name, every message that is addressed to that mailslot and sent to the domain is received by the participating processes. Because one process can control both a server mailslot handle and the client handle retrieved when the mailslot is opened for a write operation, applications can easily implement a simple message-passing facility within a domain. This makes it possible to use mailslots created with VB to allow an application running on one machine to communicate directly with an application (or applications) on the same machine or on other machines across the network. 

But in addition to the interprocess functionality, a mailslot can also be used to transmit a message to the user on a specific machine, a group of machines, or the entire domain, by formatting the message appropriately. Such messages are transmitted to the default system mailslot and are displayed to the user as a system-modal message box.  And unlike mailslot interprocess communication applications that utilize CreateMailslot, broadcasting a machine-to-machine message can easily be performed using CreateFile, WriteFile and CloseHandle.  But note: ... no file is actually created; a mailslot is a pseudofile; it resides in memory, and you use standard file functions to access it. Unlike disk files, however, mailslots are temporary -- when all handles to a mailslot are closed, the mailslot and all the data it contains are deleted.

The Message From field can contain any string that indicates the sender.  The Send To variable contains either a specific machine name, or * to send to all active machines on the domain. The Message sent is restricted to 128 characters.

This demo was created on Windows XP and tested by broadcasting messages to XP and Windows 2000 machines. Through reader reports I can now confirm that while this code can be executed successfully on both 9x-based and NT-based systems, 9x systems still require WinPopup running in order to receive the messages.

 BAS Module Code

 Form Code
Start a new project with three text boxes (Text1-Text3 (Text3 is multiline in this demo)), a command button (Command1) and a label (Label1) to display the returned message. Other ID labels for the form are optional. Add the following to the form:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
Private Const OPEN_EXISTING = 3
Private Const GENERIC_WRITE = &H40000000
Private Const FILE_SHARE_READ = &H1

Private Const vbDotEveryone As String = "*"

'User-defined type for passing
'the data to BroadcastMessage
Private Type MailslotMessageData
   sMsgFrom As String
   sSendTo As String
   sMessage As String
End Type

Private Declare Function CreateFile Lib "kernel32" _
   Alias "CreateFileA" _
  (ByVal lpFileName As String, _
   ByVal dwDesiredAccess As Long, _
   ByVal dwShareMode As Long, _
   ByVal lpSecurityAttributes As Long, _
   ByVal dwCreationDisposition As Long, _
   ByVal dwFlagsAndAttributes As Long, _
   ByVal hTemplateFile As Long) As Long

Private Declare Function WriteFile Lib "kernel32" _
  (ByVal hFile As Long, _
   ByVal lpBuffer As Any, _
   ByVal nNumberOfBytesToWrite As Long, _
   lpNumberOfBytesWritten As Long, _
   ByVal lpOverlapped As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
  (ByVal hHandle As Long) As Long

Private Sub Form_Load()

   Text1.Text = "Systems Database Administrator"
   Text2.Text = "*"
   With Text3
      .MaxLength = 128
      .Text = "An unscheduled maintenance requirement " & _
              "will take the database offline beginning " & _
              vbNewLine & _
              "6:00 pm Friday, resuming at 8:00 am Sunday."
   End With
   Command1.Caption = "Send Message"
End Sub

Private Sub Command1_Click()
   Dim msg As MailslotMessageData
  'fill the structure with the
  'message data
   With msg
      .sMsgFrom = Text1.Text
      .sSendTo = Text2.Text
      .sMessage = Text3.Text
   End With
  'return the success to a label
   Label1.Caption = BroadcastMessage(msg)
End Sub

Private Function BroadcastMessage(msg As MailslotMessageData) As String

   Dim hFile As Long
   Dim byteswritten As Long
   Dim buff As String
   Dim sSlotName As String
  'ensure message type has data
  'and either abort transmission
  'or set default values
   If Len(msg.sMessage) = 0 Then
      BroadcastMessage = "No message specified; nothing to do."
      Exit Function
   End If
   If Len(msg.sSendTo) = 0 Then
      msg.sSendTo = vbDotEveryone
   End If
   If Len(msg.sMsgFrom) = 0 Then
      msg.sMsgFrom = "Mailslot System Message"
   End If

  'must be something to do, so...
  'the mailslot name is a combination of
  'the receiving machine name prefixed
  'with double slashes, followed by
   sSlotName = "\\" & msg.sSendTo & "\mailslot\messngr"
  'the message transmitted is a
  'combination of the from, to and
  'message strings separated by null
   buff = msg.sMsgFrom & vbNullChar & _
          msg.sSendTo & vbNullChar & _
          msg.sMessage & vbNullChar & vbNullChar
  'obtain a handle to the mailslot
   hFile = CreateFile(sSlotName, _
                      GENERIC_WRITE, _
                      FILE_SHARE_READ, _
                      0&, _
                      OPEN_EXISTING, _
                      FILE_ATTRIBUTE_NORMAL, _
  'if it's a go ...
   If hFile <> 0 Then
     'write the message to the slot and close the file
      If WriteFile(hFile, _
                   buff, _
                   Len(buff), _
                   byteswritten, _
                   0) <> 0 Then
         If (Len(buff) = byteswritten) Then
            BroadcastMessage = "The message was successfully sent."
            BroadcastMessage = "Message sent but bytes written <> message size."
         End If  'If (Len(buff)
         BroadcastMessage = "Error writing the message."
      End If  'If WriteFile
      Call CloseHandle(hFile)
    End If  'If hFile

End Function
The code will populate Text1, 2 and 3 with test information. 

Note --- if you are on a domain, do not test this routine with the * in the To box ... everyone will get the alert!!  No pre-send warning or confirmation is displayed ... as soon as WriteFile is called the alerts appear.  Note as well that when an alert is sent to all machines (*), the alert also appears on the sending machine as well.


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter