Zwischen QueryEndSession und EndSession vergehen ein paar Sekunden Bedenkzeit, bei dem auf die Rückgabewerte der QueryEndSession messages gewartet wird. Wie man das Herunterfahren abbricht, ist hier zu sehen (das sollte die Schwierigkeit nicht gewesen sein)
http://www.delphipraxis.net/972598-post8.html
vom feeling her würde ich einen Dialog mit countdown ala "Herunterfahren abbrechen (3..2..1..)" anzeigen lassen, falls noch wichtige Vorgänge laufen und ein user davorsitzt. Wenn die Zeit verstrichen ist, keine Interaktion erfolgt ist und noch etwas wichtiges am Laufen war, kann man einen Protokolleintrag erzeugen, unter welchen Umständen das Herunterfahren ausgeführt wurde.