Microsoft KB Archive/244820

= How to obtain Messange Queuing owner name by using Visual Basic =

Article ID: 244820

Article Last Modified on 2/22/2007

-

APPLIES TO


 * Microsoft Message Queue Server 1.0
 * Microsoft Message Queuing 2.0
 * Microsoft Message Queuing 3.0
 * Microsoft Visual Basic 6.0 Enterprise Edition
 * Microsoft Visual Basic 6.0 Learning Edition
 * Microsoft Visual Basic 6.0 Professional Edition

-



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.



Steps to obtain Message Queuing queue owner name by using Visual Basic
 Create a new Visual Basic Standard EXE project. Follow these steps to add a reference the Message Queuing ActiveX components in the project:  On the Project menu, click References. Click to select the Microsoft Message Queue Object Library check box, and then click OK.  Add a TextBox control ("Text1") and a CommandButton control ("Command1") to the default form.  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 </li>  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 </li> Press F5 (or click Start) to run the program.</li> Type the path name of an existing queue in the text box.</li> Click Command1. Notice that a message box with the name of the owner of the queue appears.</li></ol>

<div class="references_section">