15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Показываем диалоговое окошко завершения работы системы.

Только Windows NT/2000/XP: Следующий завершает работу системы при помощи функции InitiateSystemShutdown на компьютере, на котором залогинен пользователь. Сначало необходимо получить привелегию SE_SHUTDOWN_NAME. Более подробно см. Привелегии.

 

BOOL MySystemShutdown( LPTSTR lpMsg )
{
   HANDLE hToken;              // дескриптор маркера процесса
   TOKEN_PRIVILEGES tkp;       // указатель на структуру маркера

   BOOL fResult;               // флаг завершения работы системы

   // Чтобы получить привелегию завершения работы системы, получаем
   // дескриптор маркера текущего процесса.

   if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
      return FALSE;

   // Получаем LUID для привелегии завершения работы.

   LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
        &tkp.Privileges[0].Luid);

   tkp.PrivilegeCount = 1;  // будет установлена одна привелегия
   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

   // Получаем привелегию завершения работы для этого процесса.

   AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
      (PTOKEN_PRIVILEGES) NULL, 0);

   // Если не удалось получить привелегию:

   if (GetLastError() != ERROR_SUCCESS)
      return FALSE;

   // Отображаем диалоговое окошко завершения работы и начинаем
   // отсчёт.

   fResult = InitiateSystemShutdown(
      NULL,    // локальный компьютер
      lpMsg,   // сообщение для пользователя
      20,      // таймаут
      FALSE,   // просить пользователя закрыть приложения ?
      TRUE);   // Перезагрузить после завершения работы ?

   if (!fResult)
      return FALSE;

   // Запрещаем привелегию завершения работы для нашего процесса.

   tkp.Privileges[0].Attributes = 0;
   AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        (PTOKEN_PRIVILEGES) NULL, 0);

   return TRUE;
}

Если выполнить функцию AbortSystemShutdown в период таймаута, указанного в InitiateSystemShutdown, то завершения работы системы не произойдёт.

BOOL PreventSystemShutdown()
{
   HANDLE hToken;              // дескриптор маркера процесса
   TOKEN_PRIVILEGES tkp;       // указатель на структуру маркера

   // Чтобы получить привелегию завершения работы системы, получаем
   // дескриптор маркера текущего процесса.

   if (!OpenProcessToken(GetCurrentProcess(),
         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
      return FALSE;

   // Получаем LUID для привелегии завершения работы.

   LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
         &tkp.Privileges[0].Luid);

   tkp.PrivilegeCount = 1;  // one privilege to set
   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

   // Получаем привелегию завершения работы для этого процесса.

   AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
        (PTOKEN_PRIVILEGES)NULL, 0);

   if (GetLastError() != ERROR_SUCCESS)
      return FALSE;

   // Предотвращаем завершение работы системы.

   if ( !AbortSystemShutdown(NULL) )
      return FALSE;

   // Запрещаем привелегию завершения работы для нашего процесса.

   tkp.Privileges[0].Attributes = 0;
   AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
       (PTOKEN_PRIVILEGES) NULL, 0);

   return TRUE;
}