Reboot computer using API in Windows NT

I want to reboot the computer in Windows NT when a certain condition is met. I use the API function (ExitWindows) which works in Windows 95, but fails to work in Windows NT. This fuction is supposed to work in any Win-32 environment.

Fuction declaration:
Private Declare Function ExitWindows Lib "User32" Alias "ExitWindowsEx" (ByVal dwOptions As Long, ByVal dwReserved As Long) As Long

Function call:
If ... Then ExitWindows EWX_REBOOT, &HFFFFFFFF

LVL 7
Dr. Kamal MehdiAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AmberiteCommented:
Make SURE that to declare EWX_REBOOT, you are not using: Const EWX_REBOOT As Long = 2
Instead you must use:
Public Const EWX_REBOOT = 2This is a common mistake and can lead to the problem. ALSO, instead of using that declare, try this:
Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long - This is the standard Windows declaration.


0
y96andhaCommented:
If you'd like to pass the question on to someone else, I could give you a code working under Windows NT.
0
AmberiteCommented:
wait your turn y96...
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

y96andhaCommented:
Sure, I just wanted you to know that your answer won't work, Amberite.
0
AmberiteCommented:
hmm.. maybe.. by the way, what does y96andha mean?
0
y96andhaCommented:
It's my University of Linköping login ID.

My name is Andreas Hansson, I started University level studies 1996, and the letter Y is used for the study programme I am in.

If you're interested, you can find some info about the University on http://www.liu.se/ and about this particular study programme on http://www.edu.isy.liu.se/y/Main-e.html. The full English name for it is "Applied Physics and Electrical Engineering".

My University e-mail is y96andha@cyd.liu.se.

About the question: The problem is that the WinNT security requires you to enable the SeShutdownPrivilege before you can shutdown the system. And I just happened to have the code for it in a program I wrote some time ago.


0
Dr. Kamal MehdiAuthor Commented:
Dear Amberit
Thank you for trying to answer my question. I really appreciate it.
In fact, your suggested solution can not work because:

1. I allready have the Const EXW_REBOOT declared in my form, and when you use the constant only in the specific form, there is no need to declare it as Public Const in a module. This also applies to the Subs and Functions. I learned this from my experience in VB in the past.

2. Since my code works perfectly in Win95 which is a full 32-bit platform, it should work exactly the same in Win NT (I suppose).

Windows NT have many restricted security considerations, and I expected that my problem is in a way or another related to these considerations.

Thank you again Amberit.

y96andha, thank you for your interest. Please suggest your solution.
0
y96andhaCommented:
This comes from another program I have written, so not all of the declarations may be necessary. EWX_FORCE for example is provided in case you would like to force a shutdown, where you would use (EWX_FORCE+EWX_REBOOT,0) as the parameters to ExitWindowsEx. This is tested with Windows NT and VB 4 professional, but that should be enough, as you said that you had a working solution for Windows 95.

I will be leaving on vacation tomorrow, returning Thursday next week, so it will take a while for me to respond to any questions you might have.




Declarations:


Private Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
Private Const SE_PRIVILEGE_ENABLED = &H2
Private Const EWX_REBOOT = 2
Private Const EWX_FORCE = 4
Private Const TOKEN_ADJUST_PRIVILEGES = &H20
Private Const TOKEN_QUERY = &H8



Private Type LUID
    LowPart As Long
    HighPart As Long
End Type

Private Type LUID_AND_ATTRIBUTES
        LowPart As Long
        HighPart As Long
        Attributes As Long
End Type

Private Type TOKEN_PRIVILEGES
    PrivilegeCount As Long
    LowPart As Long
    HighPart As Long
    Attributes As Long
End Type

Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, ByVal PreviousState As Long, ByVal ReturnLength As Long) As Long
Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long




Code to actually do the shutdown:


    Dim tok As Long
    Dim sht As LUID
    Dim st As TOKEN_PRIVILEGES
    Dim success As Long
    success = OpenProcessToken(GetCurrentProcess, TOKEN_QUERY + TOKEN_ADJUST_PRIVILEGES, tok)
    Debug.Print "OpenProcessToken"; success
    success = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, sht)
    Debug.Print "LookupPrivilegeValue"; success
    st.PrivilegeCount = 1
    st.LowPart = sht.LowPart
    st.HighPart = sht.HighPart
    st.Attributes = SE_PRIVILEGE_ENABLED
    success = AdjustTokenPrivileges(tok, 0, st, 0, 0, 0)
    Debug.Print "AdjustTokenPrivileges"; success
    success = ExitWindowsEx(EWX_REBOOT, 0)
    Debug.Print "ExitWindowsEx"; success

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MirkwoodCommented:
Bought This Question.
0
Dr. Kamal MehdiAuthor Commented:
Too much money and too much copy-paste Mirkwood :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.