• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 586
  • Last Modified:

Shutdown without poweroff - VB5 on Win98 original edition (ATX PC)

I would like to be able to programmatically (not shelling out to another program) shutdown an ATX-enabled PC in Win98 original edition via VB5. The following line using an API call to ExitWindowsEx *should* work as far as I can tell, based on documentation :

ret_val& = ExitWindowsEx(EWX_SHUTDOWN, 0&)

where EWX_SHUTDOWN is a const with value 1.

But this is shutting down PC and powering it off instead. Documentation says that you need to include the EWX_POWEROFF (value = 8) flag to poweroff the system [EWX_SHUTDOWN Or EWX_POWEROFF], but my system is shutting down without it, and that's not what I want.

How can I get the intended result?
0
asmcmrr
Asked:
asmcmrr
  • 9
  • 8
  • 2
  • +1
5 Solutions
 
CareyJCommented:
Try InitiateSystemShutdown API Call

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

0
 
asmcmrrAuthor Commented:
This is Windows 98 - not NT, not XP, not ME. Only Win32 API calls valid for Win98 are going to help...
0
 
GERTJANCommented:
You can try the following line instead:

ExitWindowsEx (EWX_POWEROFF), &HFFFF
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
asmcmrrAuthor Commented:
For GERTJAN:

It doesn't work. Using it the way written actually seems to allow you to log off (you get the logon prompt) and log on again without stopping runnings programs, although that may only be the case because I logged back in as the same user.

I tried relevant variations keeping the &HFFFF, but they didn't work either. (EWX_SHUTDOWN; EWX_SHUTDOWN Or EWX_POWEROFF)
0
 
GERTJANCommented:
asmcmrr,

I,am using in a program a module to shut down a pc and that,s working fine on all the opperating systems.

The code you using seems to be fine. Maybe you can try the module and see iff there is some thifferent.

Here,s the code:

 Private Type LUID
         UsedPart As Long
         IgnoredForNowHigh32BitPart As Long
      End Type
     
      Private Type LUID_AND_ATTRIBUTES
         TheLuid As LUID
         Attributes As Long
      End Type

      Private Type TOKEN_PRIVILEGES
        PrivilegeCount As Long
        TheLuid As LUID
        Attributes As Long
      End Type
     
      Private Const EWX_LogOff As Long = 0
      Private Const EWX_SHUTDOWN As Long = 1
      Private Const EWX_REBOOT As Long = 2
      Private Const EWX_FORCE As Long = 4
      Private Const EWX_POWEROFF As Long = 8

      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 TOKEN_PRIVILEGES, ReturnLength As Long) As Long
      Private Declare Sub ExitWindowsDialog Lib "shell32.dll" Alias "#60" (ByVal hwndOwner As Long)
      Public Declare Function GetLastError Lib "kernel32" () As Long
      Public Const mlngWindows95 = 0
      Public Const mlngWindowsNT = 1
      Public glngWhichWindows32 As Long
      Public Declare Function GetVersion Lib "kernel32" () As Long
      Public Declare Sub SetLastError Lib "kernel32" _
         (ByVal dwErrCode As Long)

      Private Sub AdjustToken()
          Const TOKEN_ADJUST_PRIVILEGES = &H20
          Const TOKEN_QUERY = &H8
          Const SE_PRIVILEGE_ENABLED = &H2
         Dim hdlProcessHandle As Long
         Dim hdlTokenHandle As Long
         Dim tmpLuid As LUID
         Dim tkp As TOKEN_PRIVILEGES
         Dim tkpNewButIgnored As TOKEN_PRIVILEGES
         Dim lBufferNeeded As Long

          hdlProcessHandle = GetCurrentProcess()
          OpenProcessToken hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or _
            TOKEN_QUERY), hdlTokenHandle

      ' Get the LUID for shutdown privilege.
          LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid

          tkp.PrivilegeCount = 1    ' One privilege to set
          tkp.TheLuid = tmpLuid
          tkp.Attributes = SE_PRIVILEGE_ENABLED

     ' Enable the shutdown privilege in the access token of this process.
          AdjustTokenPrivileges hdlTokenHandle, False, _
         tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded

     End Sub
 
Public Sub ShutDown()
    Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     Dim Retval As Long, MsgResult As Long
     DoEvents
     Retval = ExitWindowsEx(EWX_SHUTDOWN, 0&)

End Sub

Public Sub ReStart()
     Dim lngVersion As Long
     lngVersion = GetVersion()
     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
    ExitWindowsEx (EWX_FORCE), &HFFFF

End Sub
Public Sub ReBooT()
      Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
     ExitWindowsEx (EWX_REBOOT), &HFFFF
End Sub

Public Sub LogOf()
      Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
     ExitWindowsEx (EWX_LogOff), &HFFFF
End Sub

Public Sub PowerOf()
      Dim lngVersion As Long
     lngVersion = GetVersion()

     If ((lngVersion And &H80000000) = 0) Then
         glngWhichWindows32 = mlngWindowsNT
     Else
         glngWhichWindows32 = mlngWindows95
     End If
     If glngWhichWindows32 = mlngWindowsNT Then
     AdjustToken
     End If
     DoEvents
     ExitWindowsEx (EWX_POWEROFF), &HFFFF
End Sub

Public Sub CloseWindow(hWnd As Long)
     ExitWindowsDialog hWnd
End Sub



0
 
asmcmrrAuthor Commented:
For GERTJAN (#2):

Going back to your original comment (using the EWX_POWEROFF flag), I just want to make sure you know what I'm trying to do. I don't want to poweroff, just shutdown (and leave the "It is now okay to shut off your computer" screen up).

I tried using your module by pasting it into its very own projects and making a simple Sub Main() :

Sub Main()

ShutDown

End Sub

And it shutdown and poweroffed off the PC. :(

Just for reference, this is a Penitum4-2.0a (2Ghz) on an Asus P4S-533 motherboard.

---
ASM
0
 
CareyJCommented:
ExitWindowsEx is working that way because you have the Win98
"FastReboot" Option enabled on that computer.  You configured
your computer to bypass the "Its now safe to turn off" Win98
message.

Your VB program's API call can't override this user setting.  

If you've forgotten how you enabled the Fast Shutdown option
on that computer, do these steps to disable it and then your
API call to ExitWindowsEx will work like you want:
   1. Click Start, Programs, Accessories, System Tools
   2. Run System Information.
   3. On the Tools menu, click System Configuration Utility.
   4. On the General tab, click the Advanced Button.
   5. Click to check the "Disable Fast Shutdown" check box
   6. Click OK, and then click OK.
   7. Click "Yes" to restart your computer.

To make your function reliable on other Win98 computers, you may
want to programmatically check the registry value for "FastReboot"  
prior to making your API call.  If the value is "1", your function
will cause the computer to shutdown completely.  I don't recommend
programmatically changing the value for the user just so your
program works correctly.

The "FastReboot" value is in the following registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Shutdown
0
 
asmcmrrAuthor Commented:
CareyJ:

Actually, I already had fast shutdown disabled. I re-enabled it to be thorough when testing GERTJAN's code, and it didn't work either way.
0
 
CareyJCommented:
ExitWindowsEx is working that way because you have the Win98
"FastReboot" Option enabled on that computer.  You configured
your computer to bypass the "Its now safe to turn off" Win98
message.

Your VB program's API call can't override this user setting.  

If you've forgotten how you enabled the Fast Shutdown option
on that computer, do these steps to disable it and then your
API call to ExitWindowsEx will work like you want:
   1. Click Start, Programs, Accessories, System Tools
   2. Run System Information.
   3. On the Tools menu, click System Configuration Utility.
   4. On the General tab, click the Advanced Button.
   5. Click to check the "Disable Fast Shutdown" check box
   6. Click OK, and then click OK.
   7. Click "Yes" to restart your computer.

To make your function reliable on other Win98 computers, you may
want to programmatically check the registry value for "FastReboot"  
prior to making your API call.  If the value is "1", your function
will cause the computer to shutdown completely.  I don't recommend
programmatically changing the value for the user just so your
program works correctly.

The "FastReboot" value is in the following registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Shutdown
0
 
CareyJCommented:
I just tried it on my test stand.  With FastReboot "ON", ExitWindowsEx makes the PC shutdown completely, bypassing the "It's safe to ..." screen.  When I set FastReboot "OFF", ExitWindowsEx drops the PC to the "It's safe to..." screen.

Obviously, this problem is with the PC or it's Win98 installation/options.  Have you tried your program on another Win98 box to see how it works for the rest of us in Win98?

Also, go to Microsoft.com and search for "Win98 Shutdown Supplement".  Download the Supplement and run it on that computer.  The supplement fixes many Shutdown issues in Win98.
0
 
asmcmrrAuthor Commented:
The shutdown supplement is for Win98 SE only. I have Win98 original edition. My only other ATX-Win98 PC is running a near identical setup. Pentium4 Celeron on Asus P4S533-E motherboard. I will try it out.
0
 
asmcmrrAuthor Commented:
I tried it on the other computer and it doesn't work either I'm afraid, same result. (I tried it with fast shutdown enabled and disabled)
0
 
CareyJCommented:
Do those PC's stop at the "It's safe to..." screen when you click Start/Shutdown?
0
 
asmcmrrAuthor Commented:
For a second, then they turn off.
0
 
CareyJCommented:
Then it's not a API call problem.  It's a Windows Shutdown configuration.  This could also be a delay = 0 for "Wait time" at the "safe to turn off" screen.

I've seen a shareware utility named TweakUI that, among many performance enhancing registry changes, one option could configure Win98 to skip through the "Safe to turn off" screen.  Has someone ran TweakUI on those machines?

Also, check your bios settings for a motherboard shutdown method. Options here, if your bios has it, are something like:
1) Manual    <---This pauses for user intervention
2) Restart   <---This simulates a "Reset" Button press
2) Poweroff  <---This simulates a "Power" Button press

If you remain stumped, you might have better luck asking this question in the OS/Win98 Topic Area.  It's a classic configuration problem.
0
 
asmcmrrAuthor Commented:
I have TweakUI and have used it for a long time. The Win9x versions don't have any wait time settings for shutdown. There is a bootdelay option, but that's for startup, not shutdown. My bios (Award) doesn't have any shutdown configuration beyond picking what holding in the start button for > 4 seconds will do. (Soft Poweroff or Suspend)
0
 
CareyJCommented:
Well, the problem isn't in the API call.  You're asking why the PC doesn't stop at Logo.sys when you call ExitWindowsEx when it doesn't even do that in a normal shutdown.  ExitWindowsEx doesn't change your shutdown options, it executes them.

Did you check your Bios' APM options to see if there is a "poweroff" shutdown option that is enabled?

Maybe you could try ExitWindowsEx with both Bios and Win98 APM options disabled.

0
 
asmcmrrAuthor Commented:
Unfortunately, the BIOS doesn't have much of anything for APM beyond the "soft off" or "suspend" options. I know for sure that the API call is good, I used rundll to execute it by copying and pasting code right from Microsoft's K.B. on the subject. I've tried all Windows options I can think of, unless someone can point out a different one nothing's going to change. I think posting this to the "Win98" area is a good idea though? Can I "move" this question there since it isn't answered yet or do I have to post a new one?
0
 
CareyJCommented:
You'll have to post another one.

If you get an answer, come back to this one and post the answer here too.
0
 
CleanupPingCommented:
asmcmrr:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
Experts: Post your closing recommendations!  Who deserves points here?
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 9
  • 8
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now