Rebooting NT from VB

Rebooting NT from VB

How do I reboot (with an option to force) inside of Win NT? I know about the ExitWindowsEx API call, which works fine in Windows 95, but unfortunately this does not work correctly in NT.

From my testing, the ExitWindowsEx API call will only do a log off (or forced log off) but not a full system shutdown and reboot.

Actually, under NT, this is not such an easy question. You must first give yourself shutdown privileges, even though you have those same privileges as an interactive user?and that is what makes it more interesting.

The code below works just fine:

 Option ExplicitDeclare Function ExitWindowsEx _   Lib "user32" _   (ByVal uFlags As Long, _    ByVal dwReserved As Long) As LongPrivate Const EWX_FORCE As Long = 4&Private Const EWX_LOGOFF As Long = 0&Private Const EWX_REBOOT As Long = 2&Private Const EWX_SHUTDOWN As Long = 1&Private Const ERROR_SUCCESS As Long = 0&Private Const ERROR_NOT_ALL_ASSIGNED As Long = 1300&Private Declare Function AdjustTokenPrivileges _   Lib "advapi32.dll" _   (ByVal TokenHandle As Long, _    ByVal DisableAllPrivileges As Long, _    NewState As TOKEN_PRIVILEGES, _    ByVal BufferLength As Long, _    PreviousState As TOKEN_PRIVILEGES, _    ReturnLength As Long) As LongPrivate Declare Function LookupPrivilegeValue _   Lib "advapi32.dll" Alias "LookupPrivilegeValueA" _   (ByVal lpSystemName As Any, _    ByVal lpName As String, _    lpLuid As LUID) As LongPrivate Declare Function OpenProcessToken _   Lib "advapi32.dll" _   (ByVal ProcessHandle As Long, _    ByVal DesiredAccess As Long, _    TokenHandle As Long) As LongPrivate Declare Function GetCurrentProcess _   Lib "kernel32" () As LongPrivate Const TOKEN_QUERY As Long = &H8&Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20&Private Const SE_PRIVILEGE_ENABLED  As Long = &H2Private Type LUID   lowpart As Long   highpart As LongEnd TypePrivate Type LUID_AND_ATTRIBUTES   pLuid As LUID   Attributes As LongEnd TypePrivate Type TOKEN_PRIVILEGES   PrivilegeCount As Long   Privileges As LUID_AND_ATTRIBUTESEnd TypePublic Sub ShutDown(ByVal xi_blnForce As Boolean)   Dim p_lngRtn            As Long   Dim p_lngFlags          As Long   Dim p_lngToken          As Long   Dim p_lngBufLen         As Long   Dim p_lngLastErr        As Long   Dim p_typLUID           As LUID   Dim p_typTokenPriv      As TOKEN_PRIVILEGES   Dim p_typPrevTokenPriv  As TOKEN_PRIVILEGES      p_lngRtn = OpenProcessToken(GetCurrentProcess(), _                  TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, _                  p_lngToken)   If p_lngRtn = 0 Then      ' Failed      Debug.Print ReturnApiErrString(Err.LastDllError)      Exit Sub   End If      p_lngRtn = LookupPrivilegeValue(0&, "SeShutdownPrivilege", p_typLUID)   If p_lngRtn = 0 Then      ' Failed      Debug.Print ReturnApiErrString(Err.LastDllError)      Exit Sub   End If      p_typTokenPriv.PrivilegeCount = 1   p_typTokenPriv.Privileges.Attributes = SE_PRIVILEGE_ENABLED   p_typTokenPriv.Privileges.pLuid = p_typLUID      p_lngRtn = AdjustTokenPrivileges(p_lngToken, False, _                     p_typTokenPriv, Len(p_typPrevTokenPriv), _                     p_typPrevTokenPriv, p_lngBufLen)   If p_lngRtn = 0 Then      ' Failed      Debug.Print Err.LastDllError, ReturnApiErrString(Err.LastDllError)      Exit Sub   Else      p_lngLastErr = Err.LastDllError      If p_lngLastErr = ERROR_SUCCESS Then         ' Everything is OK      ElseIf p_lngLastErr = ERROR_NOT_ALL_ASSIGNED Then         Debug.Print "Not all privileges assigned."      Else         Debug.Print p_lngLastErr, ReturnApiErrString(p_lngLastErr)      End If   End If                        If xi_blnForce = False Then      p_lngFlags = EWX_REBOOT   Else      p_lngFlags = EWX_REBOOT And EWX_FORCE   End If      p_lngRtn = ExitWindowsEx(p_lngFlags, 0&)   End Sub


Share the Post: