C++Builder: Вешаем систему


Сегодня мы сделаем небольшую программку, с помощью которой можно будет повесить Windows в трёх различных степенях тяжести. Первые две степени весьма условны, поскольку "величина зависания" будет зависеть от мощности вашей системы и от степени её загруженности. Третья степень - полное зависание - должна повесить компьютер намертво: "тремя пальцами не поможешь".

Создаём в Builder'е новое приложение (File -> New Application). Начинаем с проектирования формы. Вот что у меня получилось:

zav_form.jpg; 17,9 kb
Рис 1. Форма будущей программы

Как видно из рисунка, степень зависания выбирается с помощью компонента класса TRadioGroup. На всякий случай, я добавил четвёртый вариант, если кто-то не захочет вешать свою систему. Для заполнения элементов списка обратитесь к его свойству Items. Чтобы выделить четвёртый пункт в списке, свойство ItemIndex устанавливаем в 3 (т. к. индексация начинается с нуля).

Осталось самое главное - написать обработчик нажатия на кнопку. Кликаем на ней два раза и пишем:
HANDLE hProcess;

switch(RadioGroup1->ItemIndex)
  {
  case 0://Лёгкое зависание
        hProcess=OpenProcess(PROCESS_SET_INFORMATION,FALSE,GetCurrentProcessId());
        if(hProcess==NULL)
          {
          L1->Caption="Error.";
          return;
          }
        if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
          while(true)UpdateWindow(GetDesktopWindow());
        else L1->Caption="Error.";
  break;

  case 1://Среднее зависание
        hProcess=OpenProcess(PROCESS_SET_INFORMATION,FALSE,GetCurrentProcessId());
        if(hProcess==NULL)
          {
          L1->Caption="Error.";
          return;
          }
        if(SetPriorityClass(hProcess,REALTIME_PRIORITY_CLASS))
          while(true)--Tag;
        else L1->Caption="Error.";
  break;

  case 2://Крутое, так крутое!
        SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,TRUE,NULL,0);
        asm
          {
          LABEL: cli
          jmp LABEL
          }

  //Никаких зависаний
  default:Close();
  }

Код начинается с определения выбранного пункта компонента RadioGroup1. При "лёгком" и "среднем" зависании мы открываем собственный процесс, получая его дескриптор и устанавливаем ему нужный приоритет. После этого включаем определённую нагрузку в бесконечном цикле, которая при увеличенном приоритете процесса заставит систему больше квантов времени уделять ему (в ущерб остальным процессам), что и создаст эффект подвисания.

В случае "крутого зависания" мы создаём для операционной системы иллюзию выполнения заставки, чтобы отключить Ctrl+Alt+Del (вообще, это можно без проблем опустить). После этого помещаем в код ассемблерную вставку, в которой постоянно выполняется инструкция отключения всех аппаратных прерываний, хотя её достаточно выполнить однократно. После этого компьютер перестаёт реагировать на прерывания от всех устройств, и остаётся только сделать холодный рестарт.
Если вы собираетесь тестировать работу программы - будьте осторожны: я не отвечаю за потерю данных при неудачном завершении работы.


Hosted by uCoz