Запитання 2 Інтерфейсна бібліотека
Ntdll.dll – спеціальна бібліотека системної підтримки, потрібна під час використання DLL підсистем. Вона містить функції двох типів:
■ інтерфейси диспетчера системних сервісів (system service dispatch stubs) до сервісів виконавчої системи Windows;
■ внутрішні функції підтримки, що використовуються підсистемами, DLL підсистем та іншими компонентами операційної системи.
Перша група функцій надає інтерфейс до сервісів виконавчої системи Windows, які можна викликати з режиму користувача. Таких функцій більше 200, наприклад NtCreateFile і т. д. Більшість з них доступна через Windows API (проте деякі з них призначені тільки для застосування всередині самої операційної системи).
Для кожної з цих функцій у Ntdll існує точка входу з тим самим ім'ям. Код усередині функції містить специфічну для конкретної апаратної архітектури команду переходу в режим ядра для виклику диспетчера системних сервісів, який після перевірки деяких параметрів викликає справжній сервіс режиму ядра з Ntoskrnl.exe.
Ntdll включає безліч функцій підтримки, наприклад функції взаємодії з процесом підсистеми Windows (функції, імена яких починаються з Csr). Там же знаходиться диспетчер АРС (asynchronous procedure call) користувальницького режиму та диспетчер виключень
Підсистеми оточення
Підсистема Windows
Ця підсистема складається з таких основних елементів.
■ Процес підсистеми оточення (Csrss.exe), що надає:
■ підтримку консольних (текстових) вікон;
■ підтримку створення та видалення процесів та потоків;
■ часткову підтримку процесів 16-розрядної віртуальної DOS-машини (VDM);
■безліч інших функцій, наприкладGetTempFile,DefineDosDevice,і кілька функцій підтримки природних мов.
■ Драйвер режиму ядра (Win32k.sys), що включає:
■ диспетчер вікон, який керує відображенням та виведенням вікон на екран, приймає введення з клавіатури, миші та інших пристроїв, передає користувацькі повідомлення додаткам;
■ Graphics Device Interface (GDI) - це бібліотека функцій для пристроїв графічного виводу. У GDI входять функції для маніпуляцій з графікою та відтворення ліній, тексту та фігур.
■ DLL-модулів підсистем (Kernel32.dll, Advapi32.dll, User32.dll і Gdi32.dll), що транслюють виклики документованих функцій Windows API у виклики відповідних (і здебільшого недокументованих) сервісів режиму ядра з Ntoskrnl.exe та Win32k.sys .
До Windows NT 4 диспетчер вікон і графічні послуги були частиною процесу підсистеми Windows користувальницького режиму. У Windows NT 4 основна частина коду, відповідального за обробку вікон і графіки, перенесена з контексту процесу підсистеми Windows в набір сервісів, що викликаються в режимі ядра (у файл Win32k.sys). Цей перенесення було здійснено переважно підвищення загальної продуктивності системи. Окремий серверний процес, що містить графічну підсистему, вимагав численних перемикань контексту потоків і процесів, що забирало багато тактів процесора і значні ресурси пам'яті, навіть незважаючи на високу оптимізацію вихідної архітектури цієї підсистеми.
Наприклад, кожен потік клієнта обслуговується парним серверним потоком у процесі підсистеми Windows, що очікує запитів від клієнтського потоку. Для передачі повідомлень між потоками використовується спеціальний механізм взаємодіїміж процесами так званий швидкий LPC (fast LPC). На відміну від звичайного перемикання контексту потоків передача даних між парними потоками через швидкий LPC не викликає в ядрі події перепланування, що дозволяє серверному потоку виконуватися протягом кванта часу клієнтського потоку (поза чергою, визначеної планувальником). Більш того, для швидкої передачі великих структур даних, наприклад бітових карт, використовуються буфери пам'яті, що розділяються, і клієнти отримують прямий доступ (тільки для читання) до ключових структур даних сервера, а це зводить до мінімуму необхідність у частому перемиканні контексту між клієнтами і сервером Windows .
GDI-операції виконуються у пакетному режимі. При цьому серія графічних об'єктів, запитаних Windows-програмами, не обробляється сервером і не промальовується на пристрої виводу доти, доки не буде заповнена вся черга GDI. Розмір черги можна встановити через Windows-функціюGdiSetBatchLimit.У будь-який момент усі об'єкти з черги можна скинути викликом функціїGdiFlush.З іншого боку, незмінні властивості та структури даних GDI після отримання від процесів підсистеми Windows кешуються клієнтськими процесами для прискорення доступу до них.
Так що ж залишається в тій частині процесу підсистеми Windows, яка працює в режимі користувача? Оскільки консольні програми не перемальовують вікна, всі операції з відтворення та оновлення консольних та текстових вікон проводяться саме цією частиною Windows. Побачити її діяльність нескладно: просто відкрийте вікно командного рядка та перетягніть поверх нього інше вікно. Ви побачите, що процес підсистеми Windows починає витрачати процесорний час, перемальовуючи консольне вікно. Крім підтримкиконсольних вікон, лише невелика частина Windows-функцій посилає повідомлення процесу підсистеми Windows. До них відносяться функції, що відповідають за створення та завершення процесів та потоків, призначення букв мережевим дискам, створення тимчасових файлів. Як правило, Windows-програма нечасто перемикає (якщо взагалі перемикає) контекст у процес підсистеми Windows.
Чи не постраждала стабільністьWindowsвід перекладуUSERіGDIу режим ядра?
Деякі цікавляться, чи не вплине на стабільність системи переведення такої значної частини коду в режим ядра. Але ризик зниження стабільності системи мінімальний. Справа в тому, що до Windows NT 4 (як і в даний час) помилка на кшталт порушення доступу (access violation) в процесі підсистеми Windows користувача режиму (Csrss.exe) призводила до краху системи, тому що процес підсистеми Windows був і залишається життєво важливим для функціонування всієї системи. Оскільки структури даних, що визначають вікна на екрані, містяться саме в цьому процесі, його загибель призводить до знищення інтерфейсу користувача. Однак навіть при функціонуванні Windows як сервер без інтерактивних процесів система не могла б працювати без Csrss, оскільки серверні процеси іноді використовують віконні повідомлення для контролю внутрішнього стану програм. Так що в Windows помилки на кшталт порушення доступу в тому ж коді, який тільки виконується в режимі ядра, просто швидше призводять до краху - винятки в режимі ядра вимагають припинення роботи системи.
Теоретично виникає інша небезпека. Оскільки цей код виконується в режимі ядра, помилка (наприклад, використання неправильного покажчика) може пошкодити захищені структури даних режиму ядра. До WindowsNT 4 це могло призвести до порушення доступу, оскільки запис у сторінки режиму ядра з режиму користувача не дозволяється. Але результатом став би крах системи. Тепер при виконанні коду в режимі ядра запис на будь-яку сторінку пам'яті за неправильним покажчиком не обов'язково викличе негайний крах системи. Але якщо при цьому будуть пошкоджені якісь структури даних, крах швидше за все відбудеться. Проте виникає ризик, що через такий вказівник буде пошкоджена не структура даних, а буфер пам'яті, і це призведе до повернення програми користувача або запису на диск невірних даних.
Ще один негативний наслідок переведення графічних драйверів у режим ядра. Раніше деякі частини графічного драйвера виконували в Csrss, інші частини — в режимі ядра. Тепер весь драйвер працює лише у режимі ядра. Так як не всі драйвери графічних пристроїв, що підтримуються Windows, розробляються Microsoft, вона тісно співпрацює з виробниками обладнання, щоб гарантувати розробку ними надійних і ефективних драйверів. Всі драйвери, що поставляються з системою, тестуються так само ретельно, як і інші компоненти виконавчої системи.
Схема, коли підсистема підтримки вікон і графіки виконується як ядра, перестав бути принципово ризикованою.
На закінчення відзначимо, що підвищення продуктивності в результаті перекладу диспетчера вікон і GDI з режиму користувача в режим ядра досягнуто без скільки-небудь значного зниження стабільності і надійності системи — навіть у разі декількох сеансів, створених у конфігурації з підтримкою Terminal Services.