-
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
-
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
-
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
-
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
-
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
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks