Solved

ShutDown windows NT Machine through VB5.0

Posted on 1998-12-11
12
201 Views
Last Modified: 2010-05-03
How i can shutdown a winwdows-NT machine by a program in
visual basic 5.0 . I m using API calls but unabe to declare
certain structres...like LUID...etc to set PRIVILEGES.
pls help me out by giving the declaration and how to them in API functions.

thanks
0
Comment
Question by:jss99
  • 4
  • 3
  • 2
  • +3
12 Comments
 

Author Comment

by:jss99
Comment Utility
if possible pls send me total code about how the api will be used
0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
Have you tried this function:
Private Declare Function ExitWindows Lib "user32" Alias "ExitWindows" (ByVal dwReserved As Long, ByVal uReturnCode As Long) As Long

0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
Private Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
Private Const SE_PRIVILEGE_ENABLED = &H2
Private Const EWX_SHUTDOWN =1
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


Public Sub Shutdown()

' Code that 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)
  success = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, sht)
  st.PrivilegeCount = 1
  st.LowPart = sht.LowPart
  st.HighPart = sht.HighPart
  st.Attributes = SE_PRIVILEGE_ENABLED
  success = AdjustTokenPrivileges(tok, 0, st, 0, 0, 0)
  success = ExitWindowsEx(EWX_SHUTDOWN, 0)
End Sub
0
 

Author Comment

by:jss99
Comment Utility
Well Mike your code is working fine in case i m logged on NT as a user who is having shutdown privilege...but if the user does not have shutdown privilege than program is not capable to ask the user name and password of administrator to shutdown the system.
0
 
LVL 2

Expert Comment

by:khaled022498
Comment Utility
May be this is what you are looking for, the following code illustrates how shutdown a SERVER/WorkStation but inorder to execute this code you MUST have an administration previlige on the host machine, hope this will help you, regards.

Declare Function InitiateSystemShutdown Lib "advapi32.dll" Alias "InitiateSystemShutdownA" (ByVal lpMachineName As String, ByVal lpMessage As String, ByVal dwTimeout As Long, ByVal bForceAppsClosed As Long, ByVal bRebootAfterShutdown As Long) As Long

and here how to pass the params
Dim Ret as long
Ret = InitiateSystemShutdown("NT_SRV_NAME", "System will Shutdown now", 100, True, True)

0
 

Author Comment

by:jss99
Comment Utility
hi khaled...
i want the code to prompt for user name and password ; then it should check for privileges ... then it should shutdown the system

anyway thanks

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
You can't just logon as another user in the windows world. As soon as you are logged on as one user, you're this user for this entire session. What you want is not possible. Sorry....
Accept MikeP answer that's the best you get
0
 
LVL 14

Expert Comment

by:waty
Comment Utility
Try this code :

Option Explicit

'To try out a shutdown, add two Command buttons and a Text box to the project's form and then paste in the following code. Note you should save your work before running it, because the shutdown will kill VB without asking you to save any changes! Clicking on the first Command button will initiate a shutdown, with a timeout value set to the number of seconds entered into the text box. To stop the shutdown, click the second Command button.
'
'Private Sub Command1_Click()
'    If (MsgBox("Are you sure you want to initiate a forced, timed shutdown?", vbYesNo Or vbQuestion) = vbYes) Then
'    NTForceTimedShutdown CLng(Text1.Text), "You're gonna get shutdown in " & Text1.Text & " s..."
'End If
'End Sub
'
'Private Sub Command2_Click()
'NTAbortTimedShutdown
'End Sub
'
'Private Sub Form_Load()
'Text1.Text = 60
'End Sub

' To Determine if we are running NT or not:
Private Type OSVERSIONINFO
   dwOSVersionInfoSize As Long
   dwMajorVersion As Long
   dwMinorVersion As Long
   dwBuildNumber As Long
   dwPlatformId As Long
   szCSDVersion As String * 128 ' Maintenance string for PSS usage
End Type

Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Private Const VER_PLATFORM_WIN32_NT = 2
Private Const VER_PLATFORM_WIN32_WINDOWS = 1
Private Const VER_PLATFORM_WIN32s = 0

' To Report API errors:
Private Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100
Private Const FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000
Private Const FORMAT_MESSAGE_FROM_HMODULE = &H800
Private Const FORMAT_MESSAGE_FROM_STRING = &H400
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200
Private Const FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long

Private Const eeSSDErrorBase = 1000

' ============================================================================================
' NT Only
Private Type LARGE_INTEGER
   lowpart As Long
   highpart As Long
End Type
Private Type LUID
   lowpart As Long
   highpart As Long
End Type
Private Type LUID_AND_ATTRIBUTES
   pLuid As LUID
   Attributes As Long
End Type
Private Type TOKEN_PRIVILEGES
   PrivilegeCount As Long
   Privileges(0 To 0) As LUID_AND_ATTRIBUTES
End Type
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function GetTokenInformation Lib "advapi32.dll" (ByVal TokenHandle As Long, TokenInformationClass As Integer, TokenInformation As Any, ByVal TokenInformationLength As Long, ReturnLength As Long) 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, PreviousState As TOKEN_PRIVILEGES, ReturnLength 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 Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
Private Const SE_PRIVILEGE_ENABLED = &H2

Private Const READ_CONTROL = &H20000
Private Const STANDARD_RIGHTS_ALL = &H1F0000
Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL)
Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)

Private Const TOKEN_ASSIGN_PRIMARY = &H1
Private Const TOKEN_DUPLICATE = (&H2)
Private Const TOKEN_IMPERSONATE = (&H4)
Private Const TOKEN_QUERY = (&H8)
Private Const TOKEN_QUERY_SOURCE = (&H10)
Private Const TOKEN_ADJUST_PRIVILEGES = (&H20)
Private Const TOKEN_ADJUST_GROUPS = (&H40)
Private Const TOKEN_ADJUST_DEFAULT = (&H80)
Private Const TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
      TOKEN_ASSIGN_PRIMARY Or _
      TOKEN_DUPLICATE Or _
      TOKEN_IMPERSONATE Or _
      TOKEN_QUERY Or _
      TOKEN_QUERY_SOURCE Or _
      TOKEN_ADJUST_PRIVILEGES Or _
      TOKEN_ADJUST_GROUPS Or _
      TOKEN_ADJUST_DEFAULT)
Private Const TOKEN_READ = (STANDARD_RIGHTS_READ Or _
      TOKEN_QUERY)
Private Const TOKEN_WRITE = (STANDARD_RIGHTS_WRITE Or _
      TOKEN_ADJUST_PRIVILEGES Or _
      TOKEN_ADJUST_GROUPS Or _
      TOKEN_ADJUST_DEFAULT)
Private Const TOKEN_EXECUTE = (STANDARD_RIGHTS_EXECUTE)

Private Const TokenDefaultDacl = 6
Private Const TokenGroups = 2
Private Const TokenImpersonationLevel = 9
Private Const TokenOwner = 4
Private Const TokenPrimaryGroup = 5
Private Const TokenPrivileges = 3
Private Const TokenSource = 7
Private Const TokenStatistics = 10
Private Const TokenType = 8
Private Const TokenUser = 1

Private Declare Function InitiateSystemShutdown Lib "advapi32.dll" Alias "InitiateSystemShutdownA" (ByVal lpMachineName As String, ByVal lpMessage As String, ByVal dwTimeout As Long, ByVal bForceAppsClosed As Long, ByVal bRebootAfterShutdown As Long) As Long
Private Declare Function AbortSystemShutdown Lib "advapi32.dll" Alias "AbortSystemShutdownA" (ByVal lpMachineName As String) As Long


Public Function WinError(ByVal lLastDLLError As Long) As String

   Dim sBuff As String
   Dim lCount As Long

   ' Return the error message associated with LastDLLError:
   sBuff = String$(256, 0)
   lCount = FormatMessage( _
         FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, _
         0, lLastDLLError, 0&, sBuff, Len(sBuff), ByVal 0)
   If lCount Then
      WinError = Left$(sBuff, lCount)
   End If

End Function

Public Function IsNT() As Boolean

   Static bOnce As Boolean
   Static bValue As Boolean

   ' Return whether the system is running NT or not:
   If Not (bOnce) Then
      Dim tVI As OSVERSIONINFO
      tVI.dwOSVersionInfoSize = Len(tVI)
      If (GetVersionEx(tVI) <> 0) Then
         bValue = (tVI.dwPlatformId = VER_PLATFORM_WIN32_NT)
         bOnce = True
      End If
   End If
   IsNT = bValue

End Function

Private Function NTEnableShutDown(ByRef sMsg As String) As Boolean

   Dim tLUID         As LUID
   Dim hProcess      As Long
   Dim hToken        As Long
   Dim tTP           As TOKEN_PRIVILEGES
   Dim tTPOld        As TOKEN_PRIVILEGES
   Dim lTpOld        As Long
   Dim lR            As Long

   ' Under NT we must enable the SE_SHUTDOWN_NAME privilege in the
   ' process we're trying to shutdown from, otherwise a call to
   ' try to shutdown has no effect!

   ' Find the LUID of the Shutdown privilege token:
   lR = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, tLUID)

   ' If we get it:
   If (lR <> 0) Then

      ' Get the current process handle:
      hProcess = GetCurrentProcess()
      If (hProcess <> 0) Then
         ' Open the token for adjusting and querying (if we can - user may not have rights):
         lR = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken)
         If (lR <> 0) Then

            ' Ok we can now adjust the shutdown priviledges:
            With tTP
               .PrivilegeCount = 1
               With .Privileges(0)
                  .Attributes = SE_PRIVILEGE_ENABLED
                  .pLuid.highpart = tLUID.highpart
                  .pLuid.lowpart = tLUID.lowpart
               End With
            End With

            ' Now allow this process to shutdown the system:
            lR = AdjustTokenPrivileges(hToken, 0, tTP, Len(tTP), tTPOld, lTpOld)

            If (lR <> 0) Then
               NTEnableShutDown = True
            Else
               Err.Raise eeSSDErrorBase + 6, App.EXEName & ".mShutDown", "Can't enable shutdown: You do not have the privileges to shutdown this system. [" & WinError(Err.LastDllError) & "]"
            End If

            ' Remember to close the handle when finished with it:
            CloseHandle hToken
         Else
            Err.Raise eeSSDErrorBase + 6, App.EXEName & ".mShutDown", "Can't enable shutdown: You do not have the privileges to shutdown this system. [" & WinError(Err.LastDllError) & "]"
         End If
      Else
         Err.Raise eeSSDErrorBase + 5, App.EXEName & ".mShutDown", "Can't enable shutdown: Can't determine the current process. [" & WinError(Err.LastDllError) & "]"
      End If
   Else
      Err.Raise eeSSDErrorBase + 4, App.EXEName & ".mShutDown", "Can't enable shutdown: Can't find the SE_SHUTDOWN_NAME privilege value. [" & WinError(Err.LastDllError) & "]"
   End If

End Function

Public Function NTForceTimedShutdown(Optional ByVal lTimeOut As Long = -1, Optional ByVal sMsg As String = "", Optional ByVal sMachineNetworkName As String = vbNullString, Optional ByVal bForceAppsToClose As Boolean = False, Optional ByVal bReboot As Boolean = False) As Boolean

   Dim lR As Long

   If IsNT Then
      ' Make sure we have enabled the privilege to shutdown
      ' for this process if we're running NT:
      If Not (NTEnableShutDown(sMsg)) Then
         Exit Function
      End If

      ' This is the code to do a timed shutdown:
      lR = InitiateSystemShutdown(sMachineNetworkName, sMsg, lTimeOut, bForceAppsToClose, bReboot)
      If (lR = 0) Then
         Err.Raise eeSSDErrorBase + 2, App.EXEName & ".mShutDown", "InitiateSystemShutdown failed: " & WinError(Err.LastDllError)
      End If

   Else
      Err.Raise eeSSDErrorBase + 1, App.EXEName & ".mShutDown", "Function only available under Windows NT."
   End If

End Function

Public Function NTAbortTimedShutdown(Optional ByVal sMachineNetworkName As String = vbNullString)

   AbortSystemShutdown sMachineNetworkName

End Function

0
 

Author Comment

by:jss99
Comment Utility
dear waty ;
if i want to shutdown the NT server from its client , how i can do it? can i pass administrator's password to server? how i can pass it? Your code is fine ..it's working properly.
thanks

0
 
LVL 1

Expert Comment

by:mathies
Comment Utility
Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long

Public Const EWX_FORCE = 4
Public Const EWX_LOGOFF = 0
Public Const EWX_REBOOT = 2
Public Const EWX_SHUTDOWN = 1


Public Sub RebootComputer(ByVal blnForce As Boolean)

   Dim lngRtn As Long
   
   If blnForce Then
      lngFlags = EWX_REBOOT + EWX_FORCE
   Else
      lngFlags = EWX_REBOOT
   End If
   lngRtn = ExitWindowsEx(lngFlags, 0&)
   
   
   
End Sub





0
 
LVL 8

Expert Comment

by:MikeP090797
Comment Utility
mathies, I have already suggested that solution, and it was found inappropriate by jss99. You should read the thread before posting answers, and not post the first thing that you come up with
0
 
LVL 13

Accepted Solution

by:
Mirkwood earned 100 total points
Comment Utility
Sorry, it's not possible to shutdown a certain from a client without having some sort of component installed on the server.

So create a component using some of the code as listed above and install this as a DCOM component on the server.
Now from the client you can call your component which can shutdown the server.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now