@@ -836,6 +836,58 @@ static TOKEN_ELEVATION_TYPE GetCurrentTokenElevationType()
836836 return retval;
837837}
838838
839+ static BOOL WINAPI WinStationGetLoggedOnCount (ULONG* pUserSessions, ULONG* pDeviceSessions)
840+ {
841+ static auto p = static_cast <decltype (&WinStationGetLoggedOnCount)>((void *)GetProcAddress (GetModuleHandle (L" winsta.dll" ), " WinStationGetLoggedOnCount" ));
842+ if (p)
843+ return p (pUserSessions, pDeviceSessions);
844+
845+ // fall-back
846+ return FALSE ;
847+ }
848+
849+ static bool ProceedWithShutdown (DWORD flags)
850+ {
851+ // this logic is inspired by user32!DisplayExitWindowsWarnings function (called from ExitWindowsEx)
852+
853+ ULONG userSessions = 0 ;
854+ ULONG deviceSessions = 0 ;
855+
856+ WinStationGetLoggedOnCount (&userSessions, &deviceSessions);
857+
858+ // we can proceed if there is at most one user session and no device sessions
859+ if (userSessions <= 1 && deviceSessions == 0 )
860+ return true ;
861+
862+ // otherwise inform user that somebody else is using the machine and ask for confirmation
863+
864+ UINT msgId = 0 ;
865+
866+ if (flags & SHUTDOWN_RESTART)
867+ {
868+ if (userSessions <= 1 )
869+ msgId = 755 ; // One or more devices on your network are using the computer resources. Restarting Windows might cause them to lose data.
870+ else if (deviceSessions != 0 )
871+ msgId = 756 ; // Other people and devices are using the computer resources. Restarting Windows might cause them to lose data.
872+ else
873+ msgId = 714 ; // Other people are logged on to this computer. Restarting Windows might cause them to lose data.
874+ }
875+ else
876+ {
877+ if (userSessions <= 1 )
878+ msgId = 753 ; // One or more devices on your network are using the computer resources.Shutting down Windows might cause them to lose data.
879+ else if (deviceSessions != 0 )
880+ msgId = 754 ; // Other people and devices are are using the computer resources. Shutting down Windows might cause them to lose data.
881+ else
882+ msgId = 713 ; // Other people are logged on to this computer. Shutting down Windows might cause them to lose data.
883+ }
884+
885+ WCHAR message[MAX_PATH]{};
886+ LoadString (GetModuleHandle (L" user32.dll" ), msgId, message, _countof (message));
887+
888+ return MessageBox (NULL , message, L" Open-Shell" , MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON1 | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_SERVICE_NOTIFICATION) != IDNO;
889+ }
890+
839891static bool ExecuteShutdownCommand (TMenuID menuCommand)
840892{
841893 DWORD flags = 0 ;
@@ -880,6 +932,11 @@ static bool ExecuteShutdownCommand(TMenuID menuCommand)
880932
881933 if (flags)
882934 {
935+ if (!ProceedWithShutdown (flags))
936+ return true ;
937+
938+ flags |= SHUTDOWN_FORCE_OTHERS;
939+
883940 if (SetShutdownPrivileges ())
884941 {
885942 flags = WindowsUpdateAdjustShutdownFlags (flags);
0 commit comments