How to obtain Messange Queuing owner name by using Visual Basic (244820)



The information in this article applies to:

  • Microsoft Message Queue Server (MSMQ) 1.0
  • Microsoft Message Queuing 2.0
  • Microsoft Message Queuing 3.0
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic Learning Edition for Windows 6.0
  • Microsoft Visual Basic Professional Edition for Windows 6.0

This article was previously published under Q244820

SUMMARY

The Microsoft Message Queuing object does not provide a mechanism for determining the owner of a queue. To determine the owner name for a Message Queuing queue, you can use the MQGetQueueSecurity function to obtain the security descriptor for the queue. You can then use this security descriptor with the Microsoft Windows NT Security function to obtain the actual name of the owner.

Note: This functionality is only available on Microsoft Windows NT and Microsoft Windows 2000. The security functions are not implemented in Microsoft Windows 98 or Microsoft Windows 95.

MORE INFORMATION

Steps to obtain Message Queuing queue owner name by using Visual Basic

  1. Create a new Visual Basic Standard EXE project.
  2. Follow these steps to add a reference the Message Queuing ActiveX components in the project:
    1. On the Project menu, click References.
    2. Click to select the Microsoft Message Queue Object Library check box, and then click OK.
  3. Add a TextBox control ("Text1") and a CommandButton control ("Command1") to the default form.
  4. Add the following code to the Command1_Click event:
    Private Sub Command1_Click()
    On Error GoTo ERRORHANDLER:
        Dim str As String               ' Storage for owner name
        Dim success As Boolean          ' Status value
        Dim mqInfo As new MSMQQueueInfo ' Stores info about the queue of interest
        Dim Queue As MSMQQueue          ' The queue object
        
            mqInfo.PathName = Text1.Text ' Extract the queue name from the form.
        
        Set Queue = mqInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE) ' Open the queue.
    
        success = GetQueueOwnerName(mqInfo.FormatName, str)
            
        If success Then
            MsgBox "The queue owner is " & str
        Else
            MsgBox "Failed to retrieve owner information for " & Text1.Text
        End If
    
       ' Clean up, and then exit.    
        If Not Queue Is Nothing Then
            Queue.Close
            Set Queue = Nothing
        End If
        
        Set mqInfo = Nothing
        
        Exit Sub
    
    ERRORHANDLER:
        MsgBox "There was an error! " & vbCrLf _
               & "Number: " & Err.Number & vbCrLf _
               & " Description: " & Err.Description
    End Sub
    					
  5. Add a standard code module ("Module1") to the project, and then add the following code to the code module:
    Option Explicit
    
    ' **********************
    ' Constants
    
    ' Security information type
    Public Const OWNER_SECURITY_INFORMATION = &H1&
    
    Public Const MQ_OK = 0&
    
    ' **********************
    ' Function prototypes
    
    'MQGetQueueSecurity
    'The MQGetQueueSecurity function retrieves the access control security descriptor for the queue that you specify.
    Public Declare Function MQGetQueueSecurity Lib "mqrt.dll" ( _
                                                ByVal lpwcsFormatName As Long, _
                                                ByVal SecurityInformation As Long, _
                                                ByVal pSecurityDescriptor As Long, _
                                                ByVal nLength As Long, _
                                                lpnLengthNeeded As Long _
                                                ) As Long
                                                
    'GetSecurityDescriptorOwner
    'The GetSecurityDescriptorOwner function retrieves the owner information from a security descriptor.
    Public Declare Function GetSecurityDescriptorOwner Lib "advapi32.dll" ( _
                                                ByVal pSecurityDescriptor As Long, _
                                                pOwner As Long, _
                                                lpbOwnerDefaulted As Long) _
                                                As Long
                                                
    'LookupAccountSid
    'The LookupAccountSid function accepts a security identifier (SID) as input. The function retrieves
    'the name of the account for this SID and the name of the first domain on which this SID is found.
    Public Declare Function LookupAccountSid _
                            Lib "advapi32.dll" Alias "LookupAccountSidA" ( _
                                                ByVal lpSystemName As String, _
                                                ByVal Sid As Long, _
                                                ByVal Name As String, _
                                                cbName As Long, _
                                                ByVal DomainName As String, _
                                                cbDomainName As Long, _
                                                peUse As Long) _
                                                As Long
    
    ' GetQueueOwnerName
    ' Get the user name of the owner of the queue reference by hQueue, and then add the name in strName.
    ' PARAMETERS:
    '   QueueFormatName: Format Name of the queue
    '   strName: A string variable to add the name of the owner in
    ' RETURN: TRUE on success, FALSE on failure
    Public Function GetQueueOwnerName(QueueFormatName As String, strName As String) As Boolean
    On Error GoTo ERRORHANDLER:
        GetQueueOwnerName = False
        
        Dim SecurityDescriptor() As Byte
        Dim nLength As Long
        Dim nLengthNeeded As Long
        Dim result As Long
        
        Dim SecurityInformation As Long
        SecurityInformation = OWNER_SECURITY_INFORMATION
        
        ' Call MQGetQueueSecurity two times. The first time, set the nLength
        ' parameter to 0. The function then informs you of the size that you need for the
        ' security descriptor in lpnLengthNeeded.
        
        result = MQGetQueueSecurity(StrPtr(QueueFormatName), _
                                     SecurityInformation, _
                                     ByVal 0, _
                                     0, _
                                     nLengthNeeded)
        
        If result = MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL Then
            ' This is expected. Continue.
        Else
            ' Something else went wrong. Display error, and then exit.
            MsgBox "There was an error calling MQGetQueueSecurity." & vbCrLf _
                   & "Error Number: " & Hex(result)
            Exit Function
        End If
        
        ' Now you know how big to make the security descriptor.
        nLength = nLengthNeeded
        ReDim SecurityDescriptor(nLength)
        
        ' Call MQGetQueueSecurity.
        result = MQGetQueueSecurity(StrPtr(QueueFormatName), _
                                     SecurityInformation, _
                                     VarPtr(SecurityDescriptor(0)), _
                                     nLength, _
                                     nLengthNeeded)
                                     
        If result <> MQ_OK Then
            ' Something  went wrong. Display error, and then exit.
             MsgBox "There was an error calling MQGetQueueSecurity." & vbCrLf _
                   & "Error Number: " & Hex(result)
            Exit Function
        End If
        
        strName = GetSecurityDescriptorOwnerName(SecurityDescriptor())
               
        GetQueueOwnerName = True
        
        Exit Function
    ERRORHANDLER:
        MsgBox "There was an error in GetQueueOwnerName " & vbCrLf _
               & "Number: " & Err.Number & vbCrLf _
               & " Description: " & Err.Description
    End Function
    
    
    ' GetSecurityDescriptorOwnerName
    ' Get the name that is associated with the security descriptor.
    ' RETURN: The name of the owner.
    Public Function GetSecurityDescriptorOwnerName(pSecurityDescriptor() As Byte) As String
    On Error GoTo ERRORHANDLER
    
        GetSecurityDescriptorOwnerName = ""
        
        Dim pSid As Long
        Dim bOwnerDefaulted As Long
        Dim ret As Long
        
        ret = GetSecurityDescriptorOwner(VarPtr(pSecurityDescriptor(0)), _
                                          pSid, _
                                          bOwnerDefaulted)
                           
        If ret = 0 Then
            ' Something went wrong.
            MsgBox "ERROR calling GetSecurityDescriptorOwner!" & vbCrLf & _
                    " Error Number:" & Err.LastDllError & vbCrLf & _
                    " Error Description:" & Err.Description
            Exit Function
        End If
        
        Dim cbAccountName As Long
        cbAccountName = 0
        
        Dim cbReferencedDomainName As Long
        cbReferencedDomainName = 0
        
        Dim pszAccountName As String
        Dim pszReferencedDomainName As String
        
        Dim snu As Long
        
        ' Call LookupAccountSid two times: one time to find out how large your
        ' string buffers have to be, and another time to get the actual information.
        ret = LookupAccountSid(vbNullString, _
                                pSid, _
                                pszAccountName, _
                                cbAccountName, _
                                pszReferencedDomainName, _
                                cbReferencedDomainName, _
                                snu)
                                
        ' Make your strings the correct length, and then call LookupAccountSid again.
        pszAccountName = String(cbAccountName, 0)
        pszReferencedDomainName = String(cbReferencedDomainName, 0)
        
        ret = LookupAccountSid(vbNullString, _
                                pSid, _
                                pszAccountName, _
                                cbAccountName, _
                                pszReferencedDomainName, _
                                cbReferencedDomainName, _
                                snu)
        
        If ret = 0 Then
            ' Something went wrong.
            MsgBox "ERROR calling LookupAccountSid!" & vbCrLf & _
                    " Error Number:" & Err.LastDllError & vbCrLf & _
                    " Error Description:" & Err.Description
            Exit Function
        End If
        
        pszReferencedDomainName = Left(pszReferencedDomainName, cbReferencedDomainName)
        pszAccountName = Left(pszAccountName, cbAccountName)
        
        GetSecurityDescriptorOwnerName = pszReferencedDomainName & "\" & pszAccountName
        
        Exit Function
    ERRORHANDLER:
        MsgBox "There was an error in GetSidOwnerName " & vbCrLf _
               & "Number: " & Err.Number & vbCrLf _
               & " Description: " & Err.Description
    End Function
    					
  6. Press F5 (or click Start) to run the program.
  7. Type the path name of an existing queue in the text box.
  8. Click Command1. Notice that a message box with the name of the owner of the queue appears.

REFERENCES

For additional information, click the article number below to view the article in the Microsoft Knowledge Base:

218965 How To Obtain the Owner of a File on Windows NT

For more information, visit the following Microsoft Web site:

Modification Type:MajorLast Reviewed:4/20/2005
Keywords:kbhowto KB244820