Service Control Manager
Диспетчер керування службами (SCM) — це спеціальний системний процес у сімействі Windows NT операційних систем, який запускає, зупиняє та взаємодіє з процесами служб Windows.[1] Він розташований у виконуваному файлі %SystemRoot%\System32\services.exe. Процеси служб взаємодіють із SCM через чітко визначений API, і цей самий API внутрішньо використовується інтерактивними засобами керування службами Windows, такими як оснастка MMC Services.msc та утиліта командного рядка Service Control — sc.exe.
Виконуваний файл SCM, Services.exe, працює як консольна програма Windows і запускається процесом Wininit на ранньому етапі запуску системи.[2] Його основна функція, SvcCtrlMain(), запускає всі служби, налаштовані на автоматичний запуск. Спочатку внутрішня база даних встановлених служб ініціалізується шляхом читання двох таких розділів реєстру:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder\List, що містить назви та порядок груп служб. Розділ реєстру кожної служби містить необов'язкове значенняGroup, яке визначає порядок ініціалізації відповідної служби або драйвера пристрою відносно інших груп служб.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services, що містить фактичну базу даних служб і драйверів пристроїв та зчитується до внутрішньої бази даних SCM.[3] SCM зчитує значенняGroupкожної служби, а також залежності порядку завантаження з їхніх розділів реєструDependOnGroupтаDependOnService.[4]
На наступному етапі головна функція SCM SvcCtrlMain() викликає функцію ScGetBootAndSystemDriverState(), яка перевіряє, чи були успішно завантажені драйвери пристроїв, які мають бути запущені під час завантаження або запуску системи, а ті, яким цього зробити не вдалося, зберігаються у списку під назвою ScFailedDrivers. Потім створюється іменований канал \Pipe\Ntsvcs як інтерфейс віддаленого виклику процедур між SCM та SCP (Service Control Processes — процесами керування службами), які взаємодіють із конкретними службами.
Далі викликається функція ScAutoStartServices(), яка проходить циклом через усі служби, позначені як такі, що запускаються автоматично, враховуючи обчислені залежності порядку завантаження. У разі циклічної залежності фіксується помилка, а служба, яка залежить від служби, що належить до групи, яка йде пізніше в порядку завантаження, пропускається. Для служб із відкладеним автоматичним запуском групування не має значення, і вони завантажуються на пізнішому етапі запуску системи.[5]
Для кожної служби, яку потрібно запустити, SCM викликає функцію ScStartService(), яка перевіряє назву файлу, що запускає процес служби, забезпечуючи відповідність облікового запису, зазначеного для служби, обліковому запису, у контексті якого працює процес служби. Кожна служба, яка працює не в обліковому записі System, входить у систему шляхом виклику функції LSASS LogonUserEx(), для якої процес LSASS шукає «секретні» паролі, що зберігаються в розділі реєстру HKLM\SECURITY\Policy\Secrets. Вони були збережені SCP за допомогою API LsaStorePrivateData() під час початкового налаштування служби.[6]
Далі для кожної служби, процес якої ще не було запущено, викликається функція ScLogonAndStartImage(). Процеси служб створюються у призупиненому стані за допомогою API CreateProcessAsUser(). Перед відновленням виконання процесу служби створюється іменований канал \Pipe\Net\NtControlPipeX (де X — число, яке збільшується для кожної ітерації служби), що слугує каналом зв'язку між SCM та процесом служби. Процес служби під'єднується до каналу шляхом виклику функції StartServiceCtrlDispatcher(), після чого SCM надсилає службі команду «start».[7]
Служби з відкладеним автоматичним запуском були додані у Windows Vista, щоб розв'язати проблему тривалого запуску системи, а також пришвидшити запуск критично важливих служб, які не можна відкладати.[8] Спочатку метод автоматичної ініціалізації служб був розроблений для основних системних служб, від яких залежать інші програми та служби. SCM ініціалізує відкладені служби лише після обробки всіх невідкладених служб з автоматичним запуском, викликаючи функцію ScInitDelayStart(). Ця функція ставить у чергу відкладений (за замовчуванням на 120 секунд) робочий елемент, пов'язаний із відповідним робочим потоком. Окрім того, що вони ініціалізуються із затримкою, між відкладеними та невідкладеними службами немає інших відмінностей.
Служби, значення реєстру Type яких дорівнює SERVICE_KERNEL_DRIVER або SERVICE_FILE_SYSTEM_DRIVER, обробляються особливим чином: вони являють собою драйвери пристроїв, для яких ScStartService() викликає функцію ScLoadDeviceDriver(), яка завантажує відповідний драйвер (зазвичай файл із розширенням .sys), що має розташовуватися в каталозі %SystemRoot%\System32\Drivers. Для цього викликається системний виклик NtLoadDriver, а до процесу SCM додається привілей SeLoadDriverPrivilege.
SCM надає додаткову функціональність, яка безпосередньо не пов'язана зі службами Windows: він повідомляє графічні інтерфейсні програми, такі як Windows Explorer, про створення або видалення підключення мережевого диска, транслюючи Windows-повідомлення WM_DEVICECHANGE.
- ↑ Russinovich, Solomon & Ionescu (2009:79)
- ↑ Russinovich, Solomon & Ionescu (2009:291)
- ↑ Database of Installed Services. Microsoft Developer Network. Процитовано 6 березня 2011.
- ↑ Russinovich, Solomon & Ionescu (2009:292)
- ↑ Russinovich, Solomon & Ionescu (2009:294)
- ↑ Russinovich, Solomon & Ionescu (2009:295)
- ↑ Russinovich, Solomon & Ionescu (2009:296)
- ↑ Russinovich, Solomon & Ionescu (2009:297)