ExitWindowsEx API doesn't work from inside a DLL

Posted on 2006-07-19
Last Modified: 2013-11-13
Hi experts,

My task was to create an ASP file that can restart Windows (on the server side ofcourse).
I wrote the code, but it doesn't restart. nothing happens.
To do that I wrote this piece of ASP code:

Set o = Server.CreateObject("ServerServices.Restart")
set o = nothing

and here is my DLL (ServerServices.Restart which is registered well and has the proper permissions on the server)

Option Explicit

Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20
Private Const TOKEN_QUERY As Long = &H8
Private Const SE_PRIVILEGE_ENABLED As Long = &H2

Private Const EWX_LOGOFF As Long = &H0
Private Const EWX_SHUTDOWN As Long = &H1
Private Const EWX_REBOOT As Long = &H2
Private Const EWX_FORCE As Long = &H4
Private Const EWX_POWEROFF As Long = &H8
Private Const EWX_FORCEIFHUNG As Long = &H10 '2000/XP only

Private Const VER_PLATFORM_WIN32_NT As Long = 2

  OSVSize         As Long
  dwVerMajor      As Long
  dwVerMinor      As Long
  dwBuildNumber   As Long
  PlatformID      As Long
  szCSDVersion    As String * 128
End Type

Private Type LUID
   dwLowPart As Long
   dwHighPart As Long
End Type

   udtLUID As LUID
   dwAttributes As Long
End Type

   PrivilegeCount As Long
End Type
Private Declare Function ExitWindowsEx Lib "user32" (ByVal dwOptions As Long, ByVal dwReserved As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As Any, ReturnLength As Long) As Long
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Public Sub RestartWindows()
   Dim success As Long
   If IsWinNTPlus() Then
      success = EnableShutdownPrivledges()
      If success Then ExitWindowsEx(EWX_REBOOT, 0&)
      RestartWindows = ExitWindowsEx(EWX_REBOOT, 0&)
   End If
End Sub

Private Function IsWinNTPlus() As Boolean
   #If Win32 Then
      OSV.OSVSize = Len(OSV)
      If GetVersionEx(OSV) = 1 Then
         IsWinNTPlus = (OSV.PlatformID = VER_PLATFORM_WIN32_NT) And (OSV.dwVerMajor >= 4)
      End If
   #End If
End Function

Private Function EnableShutdownPrivledges() As Boolean

   Dim hProcessHandle As Long
   Dim hTokenHandle As Long
   Dim lpv_la As LUID
   hProcessHandle = GetCurrentProcess()
   If hProcessHandle <> 0 Then  
      If OpenProcessToken(hProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hTokenHandle) <> 0 Then
         If LookupPrivilegeValue(vbNullString, "SeShutdownPrivilege", lpv_la) <> 0 Then
            With token
               .PrivilegeCount = 1
               .laa.udtLUID = lpv_la
               .laa.dwAttributes = SE_PRIVILEGE_ENABLED
            End With
            If AdjustTokenPrivileges(hTokenHandle, False, token, ByVal 0&, ByVal 0&, ByVal 0&) <> 0 Then
               EnableShutdownPrivledges = True
            End If
         End If
      End If
   End If

End Function


I know for sure that the DLL works fine. however, when called by ASP from within a DLL - the ExitWindowsEX API returns '1' (Can't quit)....


Question by:Ugi_Fletzet
  • 3
  • 2
LVL 41

Accepted Solution

graye earned 300 total points
ID: 17205627
I assume you've adjusted the impersonation of that section of the web page to take on the rights of the logged on user (who would have to be an administrator)?

Just a note... The security associated with the IIS accounts are specifically desgined to reduce the risk of an intrusion and therefore have the "least privileges" required to function.  That means they probably don't have the appropriate authority/permissions to perform a shutdown.


Author Comment

ID: 17257942
As an intra-net application, I've adjusted the impersonation of that section of the web page to take on the rights of the server administrator which has full rights and not IUSR_xxx (IIS default user, xxx is the computer name) which has very few rights...

Does anyone ever try to do it / heard of someone who did it / know that there is a way to do it / know of an example / what ever...

It looks like a simple & essential task - the aility to restart your server with ASP code called a DLL (ActiveX control)
LVL 41

Expert Comment

ID: 17259169

I don't have an answer, but I've got a suggestion!

You could try using Windows Management Instrumentation (WMI) instead of the APIs to reboot the server.  Here is a sample:

' Add Reference to System.Management
Imports System.Management

' Use WMI's Win32Shutdown class to remotely logoff the user, reboot the PC, or
' shutdown the PC.
Public Class Actions

    Public Enum ActionTypes As Integer
        Logoff = 0
        Reboot = 4
        Shutdown = 8
    End Enum

    Public Sub DoAction(ByVal PC_Name As String, ByVal Flag As Integer, ByVal forced As Boolean)
        Dim wmi As ManagementClass
        Dim inParams, outParams As ManagementBaseObject
        Dim obj As ManagementObject
        Dim ans As Boolean
        Dim Result As Integer

        ' force the action regardless of any activity on the remote PC
        If forced = True Then
            Flag += 4
        End If
        ans = True

        wmi = New ManagementClass("\\" & PC_Name & "\root\cimv2:Win32_OperatingSystem")
        For Each obj In wmi.GetInstances()

            ' Get an input parameters object for this method
            inParams = obj.GetMethodParameters("Win32Shutdown")

            ' fill 'em in
            inParams("Flags") = Flag
            inParams("Reserved") = 0

            ' do it!
            outParams = obj.InvokeMethod("Win32Shutdown", inParams, Nothing)
            Result = Convert.ToInt32(outParams("returnValue"))
            If Result <> 0 Then
                Throw New System.ComponentModel.Win32Exception(Result)
            End If
    End Sub
End Class

Author Comment

ID: 17259420
Thank you Graye, I'll try that and return to you later (It might taks some time...)

Author Comment

ID: 17404944
Sorry for the delay, as I said - it might taks some time.

I tried the WMI way, but it still doesn't work. My guess - it's a special Windows protection, and the answer to my question should be: You're unable to accomplish the task under ASP....
Anyway - I'm giving graye the points, as he was the only one to help...

If someone will ever heard of a way to restart Windows with ASP, or if someone will come across a sample or just even a rumor of someone that did it - I'll appriciate any help.,,

Venabili - You can remove your comment.

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

912 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

20 Experts available now in Live!

Get 1:1 Help Now