News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Win7; detecting shutdown in an MASM program

Started by MtheK, November 02, 2013, 02:57:50 AM

Previous topic - Next topic

MtheK

  Is there a WINAPI command that I can INVOKE to determine if Windows
is in shutdown mode? IBM M/F has a simple way to determine this.

  It appears that Windows Task Scheduler will start a task even during
shutdown, which seems weird. I found many Google hits about people
wanting to use WTS to DO a shutdown, but I want to NOT start a task
during shutdown. I didn't see any options in Triggers or Conditions.
In my case, it apparently was killed shortly after, and did not drive
my SetConsoleCtrlHandler code immediately after its' startup, and thus,
not do my cleanup for the next startup. Yet my separate cleanup task
itself, which sleeps forever until the handler is driven, was driven
properly, but BEFORE the new task was started (in fact, the new task
was started 6 seconds after the cleanup task finished, per History
and since I timestamp all my msgs), so it found nothing to clean up.

  In a .BAT, I found these:

tasklist.exe /V /FI "IMAGENAME eq SHUTDOWN.exe" | %SystemRoot%\System32\find /i "SHUTDOWN.exe"
wmic.exe os get status /value | %SystemRoot%\System32\find /i "Status=OK"

  The first one doesn't find anything at shutdown; perhaps this .exe I'm
looking for isn't there, or perhaps only for a short time, if at all.
It works fine manually, looking for an .exe that I know is running
(ie: my cleanup task).

  The second one does work, but I consider it hokey to rely on parsed
data. Is this the same on Win6, 7 and 8? What if it's changed on a whim?
OS and COMPUTERSYSTEM, looking at what seems to be the same thing, produces
different output. WMIC also doesn't seem to set an ERRORLEVEL, at least
from what I can tell.

  Also, BOTH seem to require ADMIN authority. They both fail under the
GUEST logonid. Just like FSUTIL, yet my MASM can find volumes w/o being ADMIN.

  I'd like to do the latter via a WINAPI, w/o being ADMIN, but I can't seem to
find anything. Any suggestions?


dedndave

the operating system sends notification messages to all top-level windows

http://masm32.com/board/index.php?topic=1491.msg15340#msg15340

you are primarily interested in the second half of that post

for console apps, you want a control handler

dedndave

this may be more what you want...
    INVOKE  GetSystemMetrics,SM_SHUTTINGDOWN
;returns EAX <> 0 if shutting down

Magnum

I posted this on a windows batch file newsgroup.

Hope it helps.

Andy


On Fri, 1 Nov 2013 09:14:18 -0700 (PDT), Andy wrote:
>  Is there a WINAPI command that I can INVOKE to determine if Windows
> is in shutdown mode? IBM M/F has a simple way to determine this.

The system doesn't provide shutdown status or log-off status that can be
checked on demand.

> tasklist.exe /V /FI "IMAGENAME eq SHUTDOWN.exe" | %SystemRoot%\System32\find /i "SHUTDOWN.exe"

This only work if the shutdown/logoff was initiated by the SHUTDOWN.EXE.

> wmic.exe os get status /value | %SystemRoot%\System32\find /i "Status=OK"

This will never work. The "Status" property doesn't even provide the
required information. Check MSDN. Don't assume.

>   Also, BOTH seem to require ADMIN authority. They both fail under the
> GUEST logonid. Just like FSUTIL, yet my MASM can find volumes w/o being ADMIN.

Accessing WMI and finding volumes are two different things.

>   I'd like to do the latter via a WINAPI, w/o being ADMIN, but I can't seem to
> find anything. Any suggestions?

Write an EXE program that has a hidden window.
Handle the shutdown/logoff window message and create a file named
"ShuttingDown.txt" somewhere, then allow shutdown/logoff to proceed.

Make the program run on system startup and does nothing but wait or the
shutdown/logoff window message.
When run, delete the "ShuttingDown.txt" file, if present.

That file will serve as a marker that your batch file can check.
Or you can use the registry instead of a file.

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

MtheK

  Thank you all for your comments/suggestions, and especially for GetSystemMetrics.  This works great, but not EVERY time. Specifically, tasks that are started by WTS after shutdown has started do NOT change this, nor get its' Handler driven, at least in the beginning (in a test of 3 progs in a .BAT, only the 3rd detected shutdown).

  My point about VOLUMES was that I can get VOLUMENAMEs w/MASM without being ADMIN. Other than FSUTIL (ADMIN), I don't know how to get this information.

  The WMIC does seem to work; if not =OK, I assume a shutdown. I didn't have any ENQ hangs using this, tho perhaps I didn't hit the timing correctly.

  I DO have an invisible window, started by WTS as SILENT. However, it gets driven
BEFORE WTS starts the task, and so has nothing to clean up.

  Here's my logs so far...it appears that Event13 kills the running .BAT when the
current program finishes (if < SPI_GETWAITTOKILLTIMEOUT) ??? This is the real
problem. Why does WTS start my task if the OS will just flush it and not give it
any time to run?????!!!!!

-----


  LT2B, 11/4/13, 19:39:23-44, ENQDEQ.log NOT CLEARED????????????????????????
temp cmt'd 2 DELs in DSNTODAY.bat for 2 ENQDEQ (DSNTODAYAbended...) calls

NOTIFY.txt
   SLEEP Mon 11/04/2013 19:39:24.19 error 1073807364; 40010004h WaitToKill expired at shut? DWM EV9009?
     even if ran, way B 4 WTS start (right when PowerOff button pressed)

CLEANUP.txt
  SLEEP    ABENDED!6#u# 2013/11/04 19:39:41.838 0000554131 c:\DAD\SCHEDUL\execs\ c:\DAD\SCHEDUL\execs
    ABENDXIT/Handler (6): 3sec B 4 WTS start; ENQDEQ.log empty (u), other 2 erased (#)

ENQDEQWasNOTClearedMon.1104201319462645.log   WTOD=19:39:44.693 (matches z102) (prog1)
  ED 2013/11/04 19:39:44.178 (matches z969; TOD when written)   
    WTS start AFTER shutdown!   
    ENQ request by DSNTODAY
    no shutdown detected, no ABENDXIT;
      this logic worked on LT1B:

  ENQDEQ   ABENDED!s?h? 2013/11/04 19:39:13.291 0000000000 c:\DAD\SCHEDUL\execs
    GetSystemMetrics detected (s): ENQ request(E), so NOT erased since don't own (h)
  ENQDEQE  ABENDED!z*** 2013/11/04 19:39:13.291 0000000000 c:\DAD\SCHEDUL\execs
    ABENDXIT/GetSystemMetrics detection sets ERRORLEVEL=10000 (*** means # > 999)
      .BATs check this in order to exit

DSNTODAYAbendedMon.1104201319394413.log (prog1)
  ENQDEQE  ABENDED!z969 2013/11/04 19:39:44.178 0000000000 c:\DAD\SCHEDUL\execs
    written at start of program
  ENQDEQE  ABENDED!z102 2013/11/04 19:39:44.693 0000000515 c:\DAD\SCHEDUL\execs
    written at end of program; ERRORLEVEL=102 (ENQ successful)
  DEQ (prog3) not run? S/B appended?! No z969 so NOT run? No shutdown detected, no ABENDXIT.
    Killed? Was running 3.7sec, < SystemParametersInfo/SPI_GETWAITTOKILLTIMEOUT=5sec
    EV13: The operating system is shutting down at system time 2013-11-05T01:39:47.626417500Z
      this is within prog2
      was the .BAT flushed?

DSNTODAY.txt (prog2)
  DSNTODAY ABENDED!z969 2013/11/04 19:39:44.709 0000000000 c:\DAD\SCHEDUL\execs
    written at start of program
  DSNTODAY ABENDED!z000 2013/11/04 19:39:47.844 0000003136 c:\DAD\SCHEDUL\execs
    written at end of program; ERRORLEVEL=0
  no shutdown detected, no ABENDXIT.
  in other tests, prog1 runs, but this does NOT (no Z969 msg, so not run)
    EV13: The operating system is shutting down at system time 2013-11-05T02:34:44.405299400Z
      this is within prog1
      ENQDEQE  ABENDED!z969 2013/11/04 20:34:44.186 0000000000 c:\DAD\SCHEDUL\execs
      ENQDEQE  ABENDED!z102 2013/11/04 20:34:44.467 0000000281 c:\DAD\SCHEDUL\execs

ENQDEQ.txt
  ENQDEQ Mon 11/04/2013 19:46:26.41 ### W A R N I N G ###: ENQDEQ: ENQUEUE timed out; ENQUEUE R=ENQDEQ forced! DSN rename w/TOD sfx attempted!

  So it appears that when EV13 occurs, the next program in the .BAT is FLUSHED???!!!!!

dedndave

what is the task ?
if it's brief, you could possibly delay shutdown

herge


Hi *.*:

It's a mute point. If is is in shut down mode or attempting to
shut the station down. The program you are trying to run had better
be real short and fast. The RAM will die when the power goes off
unless you got a UPS. Uninteruptable Power System, and or a nice
GENERAC Diesel Generator. You need a Nice big Battery because the
diesel takes two minutes to get up to speed. Make sure Diesel has a nice
big tank. It will be real fun to debug with no power.
Regards herge
Read "Slow Death by Rubber Duck"
for chemical Laughs.

Magnum

It seems like one should finish everything and then do a shutdown.

I don't much care for diesels because they contribute to noise pollution.  :biggrin:

Andy
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

MtheK

  More testing...

1.  I changed my CLEANUP (invisible "sleep forever" window) to make 3 attempts to erase, instead of just 1 after the initial wait:
. #1 done when GetSystemMetrics detected or Handler driven
. #2 waits for the time specified in SPI_GETWAITTOKILLTIMEOUT - 3 seconds (apx)
and then attempts to erase
. #2 waits 15 more seconds (apx; poor SLEEP resolution) and then attempts to erase.

  It all works properly using Ctrl-C in a normal DOS window:
C:\DAD\MASM3211>SLEEP.exe +
ABENDXIT 2013/11/08 12:18:42.463
SLEEPk   ABENDED!0??? 2013/11/08 12:18:42.463 0000018001  = new WAITTOKILLTIMEOUT (18sec)
SLEEP    ABENDED!0uuu 2013/11/08 12:18:42.479 0000082244    #1 (& #ticks since task start)
SLEEP    ABENDED!0uuu 2013/11/08 12:18:56.534 0000096315    #2
SLEEP    ABENDED!0uuu 2013/11/08 12:19:10.590 0000110371    #3

  However, w/WTS non-SILENT, X'ing the window, it fails to do #2 in CLEANUP:
ABENDXIT 2013/11/08 11:19:00.662
SLEEPk   ABENDED!2??? 2013/11/08 11:19:00.662 0000018001  = new WAITTOKILLTIMEOUT via GET
SLEEP    ABENDED!2uuu 2013/11/08 11:19:00.662 0000010265
LAST RECORD!!!
I DUP'd this in a .log as, it seems, if killed, STDOUT re-dir data is lost?

Per PROCMON, after 4sec, it just gets killed, apparently:
SLEEP.exe 5500 3180 Thread Exit SUCCESS Thread ID: 3180, User Time: 0.0000000, Kernel Time: 0.0312002 0.0000000 11:19:05.6682503 AM
7 SLEEP.exe mainCRTStartup + 0x1eaf,  SLEEP.ASM(2215) 0x402eaf
0000002215 SLEEP1SECF SLEEPINVM   in ABENDOUT (main thread; must wait for Handler for good RC) 
SLEEP.exe 5500 5484 Thread Exit SUCCESS Thread ID: 5484, User Time: 0.0000000, Kernel Time: 0.0156001 0.0000000 11:19:05.6682677 AM
7 SLEEP.exe mainCRTStartup + 0x3a42, SLEEP.ASM(2460) 0x404a42
0000002459 ;* many times, this is as far as it gets???
0000002460          SLEEP1SECF SLEEPINVC2 (handler thread)
SLEEP.exe 5500 5484 Process Exit SUCCESS Exit Status: -1073741510, User Time: 0.0000000 seconds, Kernel Time: 0.0468003 seconds, 0.0000000 11:19:05.6707338 AM
Both of my threads are "sleeping" (waiting for the time to expire, to test this apparent kill).

2.  Not sure what u mean by shutdown delay. If you are thinking of the pop-up, in
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\ShutdownWarningDialogTimeout,
if this just controls how long the pop-up stays, and then initiates shutdown, this won't help. If I change it from all F's to 10000, all I'd have to do is hit PowerOff 10 seconds earlier, and the result s/b the same as what I've been testing. In any case, doing this produced no pop-up via the PowerOff button (I have it set to shut down) or the Start button, which doesn't even have a confirmation ("Are you sure?") ?!

3.  I tried to stop the presumed killing by reading my threads' ACL. It shows
THREAD_TERMINATE as 0. This is a copy, so OR'ing a 1 did nothing. I looked at
SetSecurityInfo, but there doesn't seem to be a way to replace the minimum ACL
(no SID, no D/SACL) itself.

4. I do GETWAITTOKILLTIMEOUT; it is currently 5000. I changed it to 18000 via
SETWAITTOKILLTIMEOUT, and although it displays the value, it isn't honored.
I then added this REG_SZ to \CP\Desktop (HKCU for a DOS normal window, HKU\.default for CLEANUP (for whatever reason)) so did NOT use SETWAITTOKILLTIMEOUT; again, it shows the new value, but it doesn't honor it. This is proven because my 2nd attempt, which now waits 15 seconds, never occurs. Further, EventID102, which says when WTS finishes the CLEANUP task, never occurs (for shutdown), presumably due to the task being killed?

  So all this generates these questions:
1. Is there anything in EventLog that I can turn on to prove that my task is being killed? All my evidence sure points to this being the case. Using PROCMON during my testing shows no events after I kill it w/PROCEXPL; just ThreadExit rc=1. Not even WTS Event201, tho the rc=1 IS logged in History? If MS touts this as "dangerous", shouldn't there be a log of the event????!!!! PROCMON shows events in yellow during non-shutdown.

2. Why can't I tell WTS to NOT start a task during shutdown? Why bother if I can't
change the 5sec limit? And if it's SO IMPORTANT to be short, why allow it???

3. What allows WAITTOKILLTIMEOUT to be honored? Why have an SPI if it doesn't work? If it was privileged, why do I see it via the GET when I change it via SET? And I see it from the Registry w/o SET.

4. How can I null the THREAD_TERMINATE access right so a kill will NOT work?

  Any 1 of the last 3 would solve my problem...

dedndave

what task are you trying to perform at shutdown ?

MtheK

  I'm trying NOT to perform tasks at shutdown.

  Basically batch jobs.

  They run from 2 (when buffered) to 100 (after startup) seconds.

  Am I understanding this right? There is NO CONFIRMATION on the shutdown button of the Start menu???!!! NO CONFIRMATION??? I can see it for the PowerOff button; after all, it's on the machine. I switch btx my ADMIN and GUEST a lot, and it's way too easy to hit it by accident! I guess I'll go back to using the old Ctl-Alt-Del, JUST TO AVOID THE SHUTDOWN, since it's not a choice, and is tucked in the
lower-right as RED.

MichaelW

This might provide a partial solution:

http://technet.microsoft.com/en-us/library/cc732119.aspx
Well Microsoft, here's another nice mess you've gotten us into.

MtheK

  Unfortunately, it's not found. I found it in winsxs and copied it to \System32,
but it says the snap plug-in failed.

  This also doesn't work:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Reliability
New ? DWORD 32
Enter as name: ShutdownReasonUI
Enter as value: 1


dedndave

there is another method that may help
but, first, i would like to know what the task is that you are trying to perform
in this case, that means i want to know what task you are trying to prevent
you have not explained your goal

GoneFishing

Quote from: MtheK on November 09, 2013, 11:10:09 PM
...
  Am I understanding this right? There is NO CONFIRMATION on the shutdown button of the Start menu???!!! NO CONFIRMATION??? I can see it for the PowerOff button; after all, it's on the machine. I switch btx my ADMIN and GUEST a lot, and it's way too easy to hit it by accident! I guess I'll go back to using the old Ctl-Alt-Del, JUST TO AVOID THE SHUTDOWN, since it's not a choice, and is tucked in the
lower-right as RED.

You may try to Remove Shutdown button from Taskbar via GPO on Windows 7 Workstations
Notice that this setting also removes Power Button from Windows Security Screen accessed by pressing CTRL-ALT-DELETE