Win32API Function NetQueryDisplayInformation

  • Thread starter Thread starter Chris van den Heuvel
  • Start date Start date
C

Chris van den Heuvel

I am trying to enumerate the users of a system from within my app (VB.NET) Not finding any .Net Framework classes to do this I turned to the Win32 API and NetQueryDisplayInformation. I can't get it to work from within VB.NET however. I found the following KB article from MS

http://support.microsoft.com/default.aspx?scid=kb;en-us;316318

When I try to convert to .Net I get an object reference not set error when calling the actual API function....Please help...

Here's my code:

Public Class UserList

'/* definitions and declarations

Private Const NET_USER = 1
Private Const NET_MACHINE = 2|
Private Const NET_GROUP = 3
Private Const ERROR_MORE_DATA = 234
Private Const REQUESTED_ENTRIES = 5
Private Const MAX_PREFERRED_LENGTH = -1

Private lResult As Int32

Private Structure NET_DISPLAY_USER
Dim usri1_name As Int32 'lpwstr
Dim usri1_comment As Int32 'lpwstr
Dim usri1_flags As Int32
Dim usri1_full_name As Int32 'lpwstr
Dim usri1_user_id As Int32
Dim usri1_next_index As Int32
End Structure

Private Structure NET_DISPLAY_GROUP
Dim grpi3_name As Int32 'lpwstr
Dim grpi3_comment As Int32 'lpwstr
Dim grpi3_group_id As Int32
Dim grpi3_attributes As Int32
Dim grpi3_next_index As Int32
End Structure

Private Structure NET_DISPLAY_MACHINE
Dim usri2_name As Int32 'lpwstr
Dim usri2_comment As Int32 'lpwstr
Dim usri2_flags As Int32
Dim usri2_user_id As Int32
Dim usri2_next_index As Int32
End Structure

Private Declare Function NetQueryDisplayInformation Lib "netapi32.dll" ( _
ByVal lpwServername As String, _
ByVal dwLevel As Int32, _
ByVal dwIndex As Int32, _
ByVal dwReqEntries As Int32, _
ByVal dwMaxLength As Int32, _
ByVal pdwNumEntries As Int32, _
ByVal pBuffer As Int32) As Int32

Private Declare Function NetApiBufferFree Lib "netapi32.dll" (ByVal BufPtr As Int32) As Int32

Private Declare Sub CopyMem Lib "KERNEL32" Alias "RtlMoveMemory" ( _
ByVal hpvDest As Int32, ByVal hpvSource As Int32, ByVal cbCopy As Int32)

Private Declare Function CopyString Lib "KERNEL32" Alias "lstrcpyW" ( _
ByVal NewString As String, ByVal OldString As Int32) As Int32

Public Sub GetUserNames()

Try

'/* This code enumerates domain users.
Dim pndu() As NET_DISPLAY_USER
Dim pszTemp As String, pszServer As String
Dim pBuffer As Int32
Dim lLevel As Int32
Dim lIndex As Int32
Dim lNumEntries As Int32
Dim lTotalEntries As Int32

pszServer = ""
lIndex = 0
lTotalEntries = 0
lNumEntries = 0

lResult = ERROR_MORE_DATA


'****************************************************************************************
'Here's where I get the object reference not set to an instance of an object error
lResult = NetQueryDisplayInformation(pszServer, NET_USER, lIndex, _
REQUESTED_ENTRIES, MAX_PREFERRED_LENGTH, lNumEntries, pBuffer)
'****************************************************************************************

Catch ex As Exception
Throw New ApplicationException(ex.Message, ex)

End Try

End Sub

End Class
 
I am trying to enumerate the users of a system from within my app (VB.NET) Not finding any .Net Framework classes to do this I turned to the Win32 API and NetQueryDisplayInformation. I can't get it to work from within VB.NET however. I found the following KB article from MS

http://support.microsoft.com/default.aspx?scid=kb;en-us;316318

When I try to convert to .Net I get an object reference not set error when calling the actual API function....Please help...

Here's my code:

Public Class UserList

'/* definitions and declarations

Private Const NET_USER = 1
Private Const NET_MACHINE = 2|
Private Const NET_GROUP = 3
Private Const ERROR_MORE_DATA = 234
Private Const REQUESTED_ENTRIES = 5
Private Const MAX_PREFERRED_LENGTH = -1

Private lResult As Int32

Private Structure NET_DISPLAY_USER
Dim usri1_name As Int32 'lpwstr
Dim usri1_comment As Int32 'lpwstr
Dim usri1_flags As Int32
Dim usri1_full_name As Int32 'lpwstr
Dim usri1_user_id As Int32
Dim usri1_next_index As Int32
End Structure

Private Structure NET_DISPLAY_GROUP
Dim grpi3_name As Int32 'lpwstr
Dim grpi3_comment As Int32 'lpwstr
Dim grpi3_group_id As Int32
Dim grpi3_attributes As Int32
Dim grpi3_next_index As Int32
End Structure

Private Structure NET_DISPLAY_MACHINE
Dim usri2_name As Int32 'lpwstr
Dim usri2_comment As Int32 'lpwstr
Dim usri2_flags As Int32
Dim usri2_user_id As Int32
Dim usri2_next_index As Int32
End Structure

Private Declare Function NetQueryDisplayInformation Lib "netapi32.dll" ( _
ByVal lpwServername As String, _
ByVal dwLevel As Int32, _
ByVal dwIndex As Int32, _
ByVal dwReqEntries As Int32, _
ByVal dwMaxLength As Int32, _
ByVal pdwNumEntries As Int32, _
ByVal pBuffer As Int32) As Int32

Private Declare Function NetApiBufferFree Lib "netapi32.dll" (ByVal BufPtr As Int32) As Int32

Private Declare Sub CopyMem Lib "KERNEL32" Alias "RtlMoveMemory" ( _
ByVal hpvDest As Int32, ByVal hpvSource As Int32, ByVal cbCopy As Int32)

Private Declare Function CopyString Lib "KERNEL32" Alias "lstrcpyW" ( _
ByVal NewString As String, ByVal OldString As Int32) As Int32

Public Sub GetUserNames()

Try

'/* This code enumerates domain users.
Dim pndu() As NET_DISPLAY_USER
Dim pszTemp As String, pszServer As String
Dim pBuffer As Int32
Dim lLevel As Int32
Dim lIndex As Int32
Dim lNumEntries As Int32
Dim lTotalEntries As Int32

pszServer = ""
lIndex = 0
lTotalEntries = 0
lNumEntries = 0

lResult = ERROR_MORE_DATA


'****************************************************************************************
'Here's where I get the object reference not set to an instance of an object error
lResult = NetQueryDisplayInformation(pszServer, NET_USER, lIndex, _
REQUESTED_ENTRIES, MAX_PREFERRED_LENGTH, lNumEntries, pBuffer)
'****************************************************************************************

Catch ex As Exception
Throw New ApplicationException(ex.Message, ex)

End Try

End Sub

End Class



The .NET classes to use for this are or in The System.DirectoryServices or System.Management namespace. The first are the ADSI wrapper classes while the latter use WMI.

No need to PInvoke here.

Willy.
 
Thanks exactly what I needed...

I am trying to enumerate the users of a system from within my app (VB.NET) Not finding any .Net Framework classes to do this I turned to the Win32 API and NetQueryDisplayInformation. I can't get it to work from within VB.NET however. I found the following KB article from MS

http://support.microsoft.com/default.aspx?scid=kb;en-us;316318

When I try to convert to .Net I get an object reference not set error when calling the actual API function....Please help...

Here's my code:

Public Class UserList

'/* definitions and declarations

Private Const NET_USER = 1
Private Const NET_MACHINE = 2|
Private Const NET_GROUP = 3
Private Const ERROR_MORE_DATA = 234
Private Const REQUESTED_ENTRIES = 5
Private Const MAX_PREFERRED_LENGTH = -1

Private lResult As Int32

Private Structure NET_DISPLAY_USER
Dim usri1_name As Int32 'lpwstr
Dim usri1_comment As Int32 'lpwstr
Dim usri1_flags As Int32
Dim usri1_full_name As Int32 'lpwstr
Dim usri1_user_id As Int32
Dim usri1_next_index As Int32
End Structure

Private Structure NET_DISPLAY_GROUP
Dim grpi3_name As Int32 'lpwstr
Dim grpi3_comment As Int32 'lpwstr
Dim grpi3_group_id As Int32
Dim grpi3_attributes As Int32
Dim grpi3_next_index As Int32
End Structure

Private Structure NET_DISPLAY_MACHINE
Dim usri2_name As Int32 'lpwstr
Dim usri2_comment As Int32 'lpwstr
Dim usri2_flags As Int32
Dim usri2_user_id As Int32
Dim usri2_next_index As Int32
End Structure

Private Declare Function NetQueryDisplayInformation Lib "netapi32.dll" ( _
ByVal lpwServername As String, _
ByVal dwLevel As Int32, _
ByVal dwIndex As Int32, _
ByVal dwReqEntries As Int32, _
ByVal dwMaxLength As Int32, _
ByVal pdwNumEntries As Int32, _
ByVal pBuffer As Int32) As Int32

Private Declare Function NetApiBufferFree Lib "netapi32.dll" (ByVal BufPtr As Int32) As Int32

Private Declare Sub CopyMem Lib "KERNEL32" Alias "RtlMoveMemory" ( _
ByVal hpvDest As Int32, ByVal hpvSource As Int32, ByVal cbCopy As Int32)

Private Declare Function CopyString Lib "KERNEL32" Alias "lstrcpyW" ( _
ByVal NewString As String, ByVal OldString As Int32) As Int32

Public Sub GetUserNames()

Try

'/* This code enumerates domain users.
Dim pndu() As NET_DISPLAY_USER
Dim pszTemp As String, pszServer As String
Dim pBuffer As Int32
Dim lLevel As Int32
Dim lIndex As Int32
Dim lNumEntries As Int32
Dim lTotalEntries As Int32

pszServer = ""
lIndex = 0
lTotalEntries = 0
lNumEntries = 0

lResult = ERROR_MORE_DATA


'****************************************************************************************
'Here's where I get the object reference not set to an instance of an object error
lResult = NetQueryDisplayInformation(pszServer, NET_USER, lIndex, _
REQUESTED_ENTRIES, MAX_PREFERRED_LENGTH, lNumEntries, pBuffer)
'****************************************************************************************

Catch ex As Exception
Throw New ApplicationException(ex.Message, ex)

End Try

End Sub

End Class



The .NET classes to use for this are or in The System.DirectoryServices or System.Management namespace. The first are the ADSI wrapper classes while the latter use WMI.

No need to PInvoke here.

Willy.
 
Back
Top