Win NT NetGroupGetUsers error


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 5 of 5

Thread: Win NT NetGroupGetUsers error

  1. #1
    Jason Kost Guest

    Win NT NetGroupGetUsers error


    I am currently using NetGroupGetUsers to enumerate through users in a set
    of Windows NT groups. The problem is that more or less every other time
    that I run the program, I get a 203 - "The System could not find the Environment
    Option that was entered" error from the GetLastError API function. There
    is nothing unusual about the way that I am enumerating the groups, in fact,
    I have three different groups that are being checked, and I only get this
    error on one of them. This only happens if I fun the program to completion,
    then I start it up again without waiting for something that it shells out
    to completely finish executing. I am wondering if maybe I am leaving some
    resource open, and having it timeout instead of explicitly closing it. Here
    is the code that is generating the error. This doesn't include all of the
    declarations because that is just too long. If needed though, I can include
    them later. Any help in this matter would be greatly appreciated as this
    has been haunting me for a few days now, and I would like to be able to move
    past it. Thank you.

    Jason Kost

    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray3(0), 0, BufPtr,
    _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal GetLastError())
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)

    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 +
    2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which
    have been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234

  2. #2
    Craig Clearman Guest

    Re: Win NT NetGroupGetUsers error

    Jason,

    >of Windows NT groups. The problem is that more or less every other time
    >that I run the program, I get a 203 - "The System could not find the Environment
    >Option that was entered" error from the GetLastError API function. There


    Don't use GetLastError(), unless you are calling your functions
    through a type library that does not use GetLastError(). Instead, you
    want to use Err.LastDllError.

    Second, there is no function called NetGroupEnumUsers()

    > result = NetGroupEnumUsers0(SNarray(0), GNarray3(0), 0, BufPtr,
    >_
    > BufLen, EntriesRead, TotalEntries, ResumeHandle)


    I assume you are calling NetGroupGetMembers(), but I can't be sure
    without your declares.

    Here's mine:

    Private Declare Function NetLocalGroupGetMembers _
    Lib "netapi32" ( _
    ByVal psServer As Long, _
    ByVal psLocalGroupName As Long, _
    ByVal hLevel As Long, _
    pBuffer As Long, _
    ByVal nMaxLength As Long, _
    nEntries As Long, _
    nTotal As Long, _
    hResume As Long) As Long

    Ciao, Craig

    --
    I've a terrible errible lot todue todie todue tootorribleday.
    -- James Joyce

  3. #3
    Craig Clearman Guest

    Re: Win NT NetGroupGetUsers error

    Jason,

    >of Windows NT groups. The problem is that more or less every other time
    >that I run the program, I get a 203 - "The System could not find the Environment
    >Option that was entered" error from the GetLastError API function. There


    Don't use GetLastError(), unless you are calling your functions
    through a type library that does not use GetLastError(). Instead, you
    want to use Err.LastDllError.

    Second, there is no function called NetGroupEnumUsers()

    > result = NetGroupEnumUsers0(SNarray(0), GNarray3(0), 0, BufPtr,
    >_
    > BufLen, EntriesRead, TotalEntries, ResumeHandle)


    I assume you are calling NetGroupGetMembers(), but I can't be sure
    without your declares.

    Here's mine:

    Private Declare Function NetLocalGroupGetMembers _
    Lib "netapi32" ( _
    ByVal psServer As Long, _
    ByVal psLocalGroupName As Long, _
    ByVal hLevel As Long, _
    pBuffer As Long, _
    ByVal nMaxLength As Long, _
    nEntries As Long, _
    nTotal As Long, _
    hResume As Long) As Long

    Ciao, Craig

    --
    I've a terrible errible lot todue todie todue tootorribleday.
    -- James Joyce

  4. #4
    Jason Kost Guest

    Re: Win NT NetGroupGetUsers error


    >I assume you are calling NetGroupGetMembers(), but I can't be sure
    >without your declares.


    Okay, to hopefully allay any further problems due to lack of code, here's
    the entire sub, along with declares.

    'Windows API function used to get a list of user name in an NT Global group
    Private Declare Function NetGroupEnumUsers0 Lib "NETAPI32.DLL" Alias _
    "NetGroupGetUsers" (ServerName As Byte, GroupName As Byte, _
    ByVal Level As Long, Buffer As Long, ByVal PrefMaxLen As Long, _
    EntriesRead As Long, TotalEntries As Long, ResumeHandle As Long) As
    Long

    'Special type used by the User function
    Private Type MungeLong
    X As Long
    Dummy As Integer
    End Type

    'Special type used by the User function
    Private Type MungeInt
    XLo As Integer
    XHi As Integer
    Dummy As Integer
    End Type

    'Windows API function to convert a pointer to an integer
    Private Declare Function PtrToInt Lib "kernel32" Alias "lstrcpynW" (RetVal
    As Any, ByVal Ptr As Long, ByVal nCharCount As Long) As Long

    'Windows API function used to convert a pointer to a string
    Private Declare Function PtrToStr Lib "kernel32" Alias "lstrcpyW" (RetVal
    As Byte, ByVal Ptr As Long) As Long

    'Windows API function used to obtain the length of a string
    Private Declare Function StrLen Lib "kernel32" Alias "lstrlenW" (ByVal Ptr
    As Long) As Long

    'Windows API function used to get the name of the current user
    Private Declare Function WNetGetUser Lib "mpr.dll" Alias "WNetGetUserA" (ByVal
    lpName As String, ByVal lpUserName As String, lpnLength As Long) As Long


    Private userName As String
    Private saUserArray() As String
    Private finUserArray() As String
    Private hrUserArray() As String
    Private devUserArray() As String
    Private devSize As Integer
    Private saSize As Integer
    Private hrSize As Integer
    Private finSize As Integer


    Option Explicit
    Option Compare Text
    Public Sub GroupArrays()
    'Function that determines whether or not a user is authorized to see specific
    buttons
    'based off of membership to certain Global NT groups. Code and definitions
    supplied by
    'Microsoft's online support site, except where otherwise noted. Actual function
    'definition supplied by Jason Kost.

    Dim result As Long
    Dim Resulting As Long
    Dim BufPtr As Long
    Dim EntriesRead As Long
    Dim TotalEntries As Long
    Dim ResumeHandle As Long
    Dim BufLen As Long
    Dim SNarray() As Byte
    Dim GNarray() As Byte
    Dim GNarray2() As Byte
    Dim GNarray3() As Byte
    Dim UNArray(99) As Byte
    Dim UName As String

    'Counter variables, supplied by Jason Kost
    Dim I As Integer
    Dim j As Integer


    'Switch used to specify that there is no data in GNarray3
    Dim GNarraySwitch As Integer

    Dim arrayNum As Long

    Dim TempPtr As MungeLong
    Dim TempStr As MungeInt

    'Array of all user names in the group, supplied by Jason Kost
    Dim userArray() As String

    devSize = 0

    SNarray = "\\edunivdc01" & vbNullChar
    Call UserID

    For arrayNum = 0 To 3
    j = 1
    'Checks to see if the button should be accessible by SA users, Fin users,
    HR users
    'or only by developers
    Select Case arrayNum
    Case 0
    GNarraySwitch = 42
    GNarray2 = "PeopleSoft Developer" & vbNullChar
    GNarray3 = "PeopleSoft Supt." & vbNullChar
    Case 1
    GNarray = "PS HR Users" & vbNullChar
    GNarraySwitch = 1
    Case 2
    GNarray = "PS FIN Users" & vbNullChar
    GNarraySwitch = 2
    Case 3
    GNarray = "PS SA Users" & vbNullChar
    GNarraySwitch = 3
    End Select

    BufLen = 255 ' Buffer size
    ResumeHandle = 0 ' Start with the first entry


    'Outer loop is used to fill up userArray with all of the names from the
    'group. Supplied by Jason Kost
    If GNarraySwitch <> 42 Then
    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray(0), 0, BufPtr, _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal Err.LastDllError)
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)
    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 + 2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which have
    been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234
    End If
    'Repeat of the above code chunk used to check the PeopleSoft Supt. group
    as well.
    If arrayNum = 0 Then
    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray2(0), 0, BufPtr,
    _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal Err.LastDllError)
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)

    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 +
    2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which
    have been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234

    'Gets the users from the group specified by GNarray3 if it exists

    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray3(0), 0, BufPtr,
    _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal Err.LastDllError)
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)

    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 +
    2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which
    have been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234
    End If

    Select Case arrayNum
    Case 0
    ReDim devUserArray(j)
    devUserArray = userArray
    devSize = j
    Case 1
    hrUserArray = userArray
    ReDim Preserve hrUserArray(j + devSize)
    For I = 0 To devSize - 1
    hrUserArray(j + I) = devUserArray(I)
    Next I
    hrSize = j + devSize
    Case 2
    finUserArray = userArray
    ReDim Preserve finUserArray(j + devSize)
    For I = 0 To devSize - 1
    finUserArray(j + I) = devUserArray(I)
    Next I
    finSize = j + devSize
    Case 3
    saUserArray = userArray
    ReDim Preserve saUserArray(j + devSize)
    For I = 0 To devSize - 1
    saUserArray(j + I) = devUserArray(I)
    Next I
    saSize = j + devSize
    End Select

    Next arrayNum
    'If the userName that was passed to the function is a member of the group
    specified
    'by the .ini file, then the function returns true, and the button will
    be visible.
    'Otherwise, the function returns false, and the button will not be visible.


    End Sub


    Hopefully this will help a bit



  5. #5
    Jason Kost Guest

    Re: Win NT NetGroupGetUsers error


    >I assume you are calling NetGroupGetMembers(), but I can't be sure
    >without your declares.


    Okay, to hopefully allay any further problems due to lack of code, here's
    the entire sub, along with declares.

    'Windows API function used to get a list of user name in an NT Global group
    Private Declare Function NetGroupEnumUsers0 Lib "NETAPI32.DLL" Alias _
    "NetGroupGetUsers" (ServerName As Byte, GroupName As Byte, _
    ByVal Level As Long, Buffer As Long, ByVal PrefMaxLen As Long, _
    EntriesRead As Long, TotalEntries As Long, ResumeHandle As Long) As
    Long

    'Special type used by the User function
    Private Type MungeLong
    X As Long
    Dummy As Integer
    End Type

    'Special type used by the User function
    Private Type MungeInt
    XLo As Integer
    XHi As Integer
    Dummy As Integer
    End Type

    'Windows API function to convert a pointer to an integer
    Private Declare Function PtrToInt Lib "kernel32" Alias "lstrcpynW" (RetVal
    As Any, ByVal Ptr As Long, ByVal nCharCount As Long) As Long

    'Windows API function used to convert a pointer to a string
    Private Declare Function PtrToStr Lib "kernel32" Alias "lstrcpyW" (RetVal
    As Byte, ByVal Ptr As Long) As Long

    'Windows API function used to obtain the length of a string
    Private Declare Function StrLen Lib "kernel32" Alias "lstrlenW" (ByVal Ptr
    As Long) As Long

    'Windows API function used to get the name of the current user
    Private Declare Function WNetGetUser Lib "mpr.dll" Alias "WNetGetUserA" (ByVal
    lpName As String, ByVal lpUserName As String, lpnLength As Long) As Long


    Private userName As String
    Private saUserArray() As String
    Private finUserArray() As String
    Private hrUserArray() As String
    Private devUserArray() As String
    Private devSize As Integer
    Private saSize As Integer
    Private hrSize As Integer
    Private finSize As Integer


    Option Explicit
    Option Compare Text
    Public Sub GroupArrays()
    'Function that determines whether or not a user is authorized to see specific
    buttons
    'based off of membership to certain Global NT groups. Code and definitions
    supplied by
    'Microsoft's online support site, except where otherwise noted. Actual function
    'definition supplied by Jason Kost.

    Dim result As Long
    Dim Resulting As Long
    Dim BufPtr As Long
    Dim EntriesRead As Long
    Dim TotalEntries As Long
    Dim ResumeHandle As Long
    Dim BufLen As Long
    Dim SNarray() As Byte
    Dim GNarray() As Byte
    Dim GNarray2() As Byte
    Dim GNarray3() As Byte
    Dim UNArray(99) As Byte
    Dim UName As String

    'Counter variables, supplied by Jason Kost
    Dim I As Integer
    Dim j As Integer


    'Switch used to specify that there is no data in GNarray3
    Dim GNarraySwitch As Integer

    Dim arrayNum As Long

    Dim TempPtr As MungeLong
    Dim TempStr As MungeInt

    'Array of all user names in the group, supplied by Jason Kost
    Dim userArray() As String

    devSize = 0

    SNarray = "\\edunivdc01" & vbNullChar
    Call UserID

    For arrayNum = 0 To 3
    j = 1
    'Checks to see if the button should be accessible by SA users, Fin users,
    HR users
    'or only by developers
    Select Case arrayNum
    Case 0
    GNarraySwitch = 42
    GNarray2 = "PeopleSoft Developer" & vbNullChar
    GNarray3 = "PeopleSoft Supt." & vbNullChar
    Case 1
    GNarray = "PS HR Users" & vbNullChar
    GNarraySwitch = 1
    Case 2
    GNarray = "PS FIN Users" & vbNullChar
    GNarraySwitch = 2
    Case 3
    GNarray = "PS SA Users" & vbNullChar
    GNarraySwitch = 3
    End Select

    BufLen = 255 ' Buffer size
    ResumeHandle = 0 ' Start with the first entry


    'Outer loop is used to fill up userArray with all of the names from the
    'group. Supplied by Jason Kost
    If GNarraySwitch <> 42 Then
    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray(0), 0, BufPtr, _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal Err.LastDllError)
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)
    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 + 2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which have
    been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234
    End If
    'Repeat of the above code chunk used to check the PeopleSoft Supt. group
    as well.
    If arrayNum = 0 Then
    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray2(0), 0, BufPtr,
    _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal Err.LastDllError)
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)

    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 +
    2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which
    have been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234

    'Gets the users from the group specified by GNarray3 if it exists

    Do
    result = NetGroupEnumUsers0(SNarray(0), GNarray3(0), 0, BufPtr,
    _
    BufLen, EntriesRead, TotalEntries, ResumeHandle)
    Call Errors(ByVal result, ByVal Err.LastDllError)
    For I = 1 To EntriesRead
    ' Get pointer to string from beginning of buffer
    ' Copy 4-byte block of memory in 2 steps
    Resulting = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)

    Resulting = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 +
    2, 2)

    LSet TempPtr = TempStr ' munge 2 integers into a Long
    ' Copy string to array
    Resulting = PtrToStr(UNArray(0), TempPtr.X)

    UName = Left$(UNArray, StrLen(TempPtr.X))

    'Re-sizes userArray to the current number of entries which
    have been read, and
    'adds the next one to the array, then increments the counter.
    Supplied by
    'Jason Kost
    If UName Like "[A-Z]*" Then
    ReDim Preserve userArray(j)
    userArray(j - 1) = UName
    j = j + 1
    End If

    Next I
    Loop While result = 234
    End If

    Select Case arrayNum
    Case 0
    ReDim devUserArray(j)
    devUserArray = userArray
    devSize = j
    Case 1
    hrUserArray = userArray
    ReDim Preserve hrUserArray(j + devSize)
    For I = 0 To devSize - 1
    hrUserArray(j + I) = devUserArray(I)
    Next I
    hrSize = j + devSize
    Case 2
    finUserArray = userArray
    ReDim Preserve finUserArray(j + devSize)
    For I = 0 To devSize - 1
    finUserArray(j + I) = devUserArray(I)
    Next I
    finSize = j + devSize
    Case 3
    saUserArray = userArray
    ReDim Preserve saUserArray(j + devSize)
    For I = 0 To devSize - 1
    saUserArray(j + I) = devUserArray(I)
    Next I
    saSize = j + devSize
    End Select

    Next arrayNum
    'If the userName that was passed to the function is a member of the group
    specified
    'by the .ini file, then the function returns true, and the button will
    be visible.
    'Otherwise, the function returns false, and the button will not be visible.


    End Sub


    Hopefully this will help a bit



Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center