Archive: My first function, Push, Pop? what is wrong?


My first function, Push, Pop? what is wrong?
  I wrote the function below, based upon UserInfo.nsi
The value of $R0 is correct at end of Function,
but is wrong when I Pop below, what is wrong?

I figure it must need a Push, or a Pop or something.
I have never used Push, Pop, Exch before, so I
would appreciate is someone could tell me what
I am missing.

Thanks, Lilla

Call IsUserAdmin
Pop $R0

; at this point $R0 should be "true" or "false"
; but instead it is empty, why at is wrong?

Function IsUserAdmin
Push $R0
ClearErrors
UserInfo::GetName
IfErrors Win9x
Pop $R1
UserInfo::GetAccountType
Pop $R2
StrCmp $R2 "Admin" 0 Continue2
; MessageBox MB_OK 'User "$R1" is in the Administrators group'
StrCpy $R0 "true"
Goto done
Continue2:
StrCmp $R2 "Power" 0 Continue3
; MessageBox MB_OK 'User "$R1" is in the Power Users group'
StrCpy $R0 "false"
Goto done
Continue3:
StrCmp $R2 "User" 0 Continue4
; MessageBox MB_OK 'User "$R1" is just a regular user'
StrCpy $R0 "false"
Goto done
Continue4:
StrCmp $R2 "Guest" 0 Continue5
; MessageBox MB_OK 'User "$R1" is a guest'
StrCpy $R0 "false"
Goto done
Continue5:
; I get here when running Win98SE, $R2 is empty
StrCmp $R2 "" 0 Continue6
;MessageBox MB_OK 'User "$R1" is a <empty>'
Goto Win9x
Continue6:
;MessageBox MB_OK "Unknown account type: $R2"
StrCpy $R0 "false"
Goto done
Win9x:
; This one means you don't need to care about admin or
; not admin because Windows 9x doesn't either
; MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
StrCpy $R0 "true"
done:
; contains 'true' or 'false' to answer IsUserAdmin
MessageBox MB_OK "R1=$R1 R2=$R2 R0=$R0" ; debug
; at this point all three values are correct
FunctionEnd


Well why do you need to do Pop $R0 anyway? $R0 will have that value without doing the pop. The reason it changes when you do pop is that pulls the top value off the stack thereby *overwriting* $R0 with whatever was on top of the stack!


At the end use Exch $R0

You can use Push $x at the start of your function to push variables onto the stack and then pop them off the stack again at the end of the function.
This is used to save variables from changing (e.g. if $1 = hello, call myfunction, $1 still = hello afterwards)

That function is a bit messy, so I shall have a look at it and see if I can clean it up!

-Stu :)



Function IsUserAdmin
Push $R0
Push $R1
Push $R2

ClearErrors
UserInfo::GetName
IfErrors Win9x
Pop $R1
UserInfo::GetAccountType
Pop $R2
StrCmp $R2 "Admin" 0 Continue1

; MessageBox MB_OK 'User "$R1" is in the Administrators group'
StrCpy $R0 "true"
Goto done

Continue1:
StrCmp $R2 "Power" 0 Continue2
; MessageBox MB_OK 'User "$R1" is in the Power Users group'
StrCpy $R0 "false"
Goto done

Continue2:
StrCmp $R2 "User" 0 Continue3
; MessageBox MB_OK 'User "$R1" is just a regular user'
StrCpy $R0 "false"
Goto done

Continue3:
StrCmp $R2 "Guest" 0 Continue4
; MessageBox MB_OK 'User "$R1" is a guest'
StrCpy $R0 "false"
Goto done

Continue4:
; I get here when running Win98SE, $R2 is empty
StrCmp $R2 "" 0 Continue5
;MessageBox MB_OK 'User "$R1" is a <empty>'
Goto Continue6

Continue5:
;MessageBox MB_OK "Unknown account type: $R2"
StrCpy $R0 "false"
Goto done

Continue6:
; This one means you don't need to care about admin or
; not admin because Windows 9x doesn't either
; MessageBox MB_OK "Error! This DLL can't run under Windows 9x!"
StrCpy $R0 "true"

done:
; contains 'true' or 'false' to answer IsUserAdmin
MessageBox MB_OK "R1=$R1 R2=$R2 R0=$R0" ; debug
; at this point all three values are correct

Pop $R2
Pop $R1
Exch $R0
FunctionEnd


If it's a useful script, put it on the NSIS Archive!

-Stu

Stu, thanks for the information, and the cleanup job.
It looks better now.

Glad you like it. I will put it on the Archive as you suggest.

Lilla


As you only want to know if the plug-in returned Admin you don't need to compare to the other values. If it's not Admin or nothing then it's false, no need to compare.

Push/Pop/Exch information can be found here:
http://nsis.sourceforge.net/archive/...php?pageid=216

Please attach large scripts next time.


Yes, I could shorten the function.

At the time I wrote it, I thought it would be good to include all tests to make it easier to tweak. For example, a Power User might be enough for some purposes.

Thanks for the link, and for let me know about attaching. I'm new and just feeling my way along here.

Lilla


I decided Kichik's was right, no point to include those extra tests. I uploaded the updated version of this function to the ARCHIVE - Useful Functions section.

Thanks Kichik for knudging me in the right direction.

Lilla


Oops, a little typo sneaked into my article: comment starting ';'-character was left on the previous line. Fixed.

Pop$0;

$
0 contains: "Value 2"
And another typo:
StrCpy$0 "Value X"

>Exch $1
>;Exchanges the top value with the variable.
;$
0 contains "Value 3"
Must of course be:
StrCpy$0 "Value X"

>Exch $0
>;Exchanges the top value with the variable.
;$
0 contains "Value 3"

The latest version of UserInfo.dll has been updated to report Win98SE user as 'Admin'. This is good.

I updated my IsUserAdmin function to reflect the new behavior of UserInfo.dll. The updated copy has been uploaded to the archive, Useful functions section.

Lilla


Have you tested IsUserAdmin function in WinNT? It returns true because UserInfo::GetAccountType returns "". Does any one knows why? Mayby it is because I tested it being loged in as user who is domain user not belongin to any local group?


BIG THANKS to virtlink for that great tutorial about the stack. i think, i've got it :)


Originally posted by jar23
Have you tested IsUserAdmin function in WinNT? It returns true because UserInfo::GetAccountType returns "". Does any one knows why? Mayby it is because I tested it being loged in as user who is domain user not belongin to any local group?
Are you saying it's always returning "" on your Windows NT, no matter what user?

Is there any chance you can do some debugging and find out why it fails? I don't have Windows NT, and have no where to get it from.