Archive: NetUserEnum problem


NetUserEnum problem
After a lot of trial and error I managed to isolate a rather strange error in one of my scripts. I am trying to enumerate the local users in my computer using the NetUserEnum API call from netapi32.dll. The call is successful and it allocates an array of USER_INFO_0 structures and each one contains a username from the local system. In my code I try to compare this username to an already existing value, but as I pull data out from the above structures, my script fails randomly. Here is the relevant code shaped into a script of its own:

SetCompressor /SOLID lzma
!include "LogicLib.nsh"

OutFile "EnumTest.exe"
InstallDir "$PLUGINSDIR"

Var "UserName"
Var "APIErrorFlag"
Var "Counter"
Var "UserExists"

!define NERR_Success 0
!define FILTER_NORMAL_ACCOUNT 0x0002

Section -Boo
SectionEnd

Function .onInit
StrCpy $UserName "Administrator"
StrCpy $APIErrorFlag 0
System::Call /NOUNLOAD 'netapi32::NetUserEnum(,i 0,i ${FILTER_NORMAL_ACCOUNT},*i .R0,i ${NSIS_MAX_STRLEN},*i .R1,*i .R2,*i 0 r4)i.r5'
${If} $5 = ${NERR_Success}
StrCpy $Counter 0
Feed:
StrCmp $Counter $R2 Stop
System::Call /NOUNLOAD '*$R0(w.R9)'
${If} $R9 == "$UserName"
StrCpy $UserExists 1
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "User Exists!"
${EndIf}
IntOp $R0 $R0 + 4
IntOp $Counter $Counter + 1
Goto Feed
Stop:
System::Call /NOUNLOAD 'netapi32::NetApiBufferFree(i R0)i .R1'
${Else}
StrCpy $APIErrorFlag 1
${EndIf}
FunctionEnd
The above fails at the System::Call /NOUNLOAD '*$R0(w.R9)' call. The wierd thing is that DrWatson reports an error at GetModuleHandleW (?).

The funny thing is that the program works sometimes but then if I move it to another directory it generates an error. But this behavior is not path-based, so for example sometimes it will work, say in C:\, sometimes it wont! AntiVirus software does not affect the above and even if moved to a clean, fresh virtual PC, the script fails randomly.

Note that changing the NetUserEnum call to
System::Call /NOUNLOAD 'netapi32::NetUserEnum(w "",i 0,i ${FILTER_NORMAL_ACCOUNT},*i .R0,i ${NSIS_MAX_STRLEN},*i .R1,*i .R2,*i 0 r4)i.r5'
has the same results

Any ideas? I am baffled to say the least ...

CF

Although I did not manage to figure out the error, I managed to implement a different approach by calling NetQueryDisplayInformation instead. This doesn't break anything so far ...

SetCompressor /SOLID lzma
!include "LogicLib.nsh"

OutFile "EnumTest.exe"
InstallDir "$PLUGINSDIR"

Var "UserName"
Var "APIErrorFlag"
Var "Counter"
Var "UserExists"

!define NERR_Success 0
!define FILTER_NORMAL_ACCOUNT 0x0002
!define strNET_DISPLAY_USER '(w,w,i,w,i,i)i'

Section -Boo
SectionEnd

Function .onInit
StrCpy $UserName "Administrator"
StrCpy $APIErrorFlag 0
System::Call /NOUNLOAD 'netapi32::NetQueryDisplayInformation(w "",i 1,i 0,i 100, i ${NSIS_MAX_STRLEN},*i .R2,*i .R0)i.r5'
${If} $5 = ${NERR_Success}
StrCpy $Counter 0
Feed:
StrCmp $Counter $R2 Stop
System::Call '*$R0${strNET_DISPLAY_USER}(.R9,,,,,)'
${If} $R9 == "$UserName"
StrCpy $UserExists 1
MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "User Exists!"
${EndIf}
IntOp $R0 $R0 + 24
IntOp $Counter $Counter + 1
Goto Feed
Stop:
System::Call /NOUNLOAD 'netapi32::NetApiBufferFree(i R0)i .R1'
${Else}
StrCpy $APIErrorFlag 1
${EndIf}
FunctionEnd


If anybody can help with the NetUserEnum problem I am still interested to see why it doesn't work ...

CF

Try printing the value of $R0, see if it contains a normal value. It might be getting over the 2^31 limit and turning negative. In this case, you can use IntFmt with %u to create an unsigned number.

BTW, you're using NetApiBufferFree on the wrong address. $R0 has long changed since NetUserEnum was called. You should keep a copy of the original address and free that instead.


Strange ...
If I add this right after the NetUserEnum call

MessageBox MB_OK|MB_ICONSTOP|MB_TOPMOST "$R0"
then the call doesn't fail. If I comment it out, it fails ... I always get something like 1567424 (or similar values) for $R0 and it is never negative ...

Good point on the NetApiBufferFree ... I completely missed that :(