Таблиця описателей об'єктів ядра

У той же час у функцій, що створюють об'єкти User або GDI, немає параметра типу

PSECURITY_ATTRIBUTES, і приклад тому - функція CreateIcon

HICON CreateIcon (HINSTANCE hinst. Int nWidth,

int nHeight, BYTE cPlanes, BYTE cBitsPixel,

CONST BYTE * pbANDbits, CONST BYTE * pbXORbits);

У таблиці 3-1 показано, як виглядає таблиця описателей, що належить про цесії Як бачите, це просто масив структур даних Кожна структура містить покажчик на який-небудь об'єкт ядра, маску доступу і деякі прапори

Якщо Ви передаєте невірний індекс (описувач), функція завершується з помилкою і GetLastError повертає 6 (ERROR_INVALID_HANDLE). Це пов'язано з тим, що насправді описатели представляють собою індекси в таблиці, їх значення прив'язані до конкретного процесу і недейовітельни в інших процесах.

Якщо виклик функції, що створює об'єкт ядра, виявляється невдалий, то зазвичай повертається 0 (NULL). Така ситуація можлива тільки при гострій нестачі пам'яті або при наявності проблем із захистом. На жаль, окремі функції повертають в таких випадках пе 0, а -1 (INVALID_HANDLE_VALUE) Наприклад, якщо CreateFile не зможе відкрити зазначений файл, вона поверне саме INVALID_HANDLE_VALUE. Будьте дуже

обережні при перевірці значення, що повертається функцією, яка створює об'єкт ядра. Так, для CreateMutex перевірка на INVALID_HANDlE_VALUE безглузда:

HANDLE hMutex = CreateMutex (.);

if (hMutex == lNVALID_HANDLE_VALUE)

// цей код ніколи не буде виконано, так як

// при помилку CreateMutex повертає NLlLL

Точно так само безглуздий і наступний код:

HANDIE hFile = CreateFile (.); if (hFile - NULL>

// і цей код ніколи не буде виконано, так як

// при помилку CreateFile повертає lNVALID_HANDLE_VALUE (-1)

Закриття об'єкта ядра

Незалежно від того, як саме Ви створили об'єкт ядра, після закінчення роботи з ним його потрібно закрьпь викликом CloseHandle

BOOL CloseHandle (HANDLE hobj);

Ця функція спочатку перевіряє таблицю описателей, що належить зухвалому процесу, щоб переконатися, ідентифікує чи переданий їй індекс (описа

Якщо ж описатель невіруючих, відбувається одне з двох. У нормальному режимі виконання процесу CloseHandle повертає FALSE, a GetLastError - код

ERROR_INVALID_HANDLE. Але при виконанні процесу в режимі налагодження система просто повідомляє відладчик про помилку.

Перед самим поверненням управління CloseHandle видаляє відповідний запис з таблиці описателей: даний описатель тспсрь недійсний у Вашому процесі і використовувати його не можна. При цьому запис видаляється незалежно від того, зруйнований об'єкт ядра чи ні! Після виклику CloseHandle Ви більше не отримаєте доступ до це-

му об'єкту ядра; але, якщо його лічильник не обнулений, об'єкт залишається в пам'яті Тут все нормально, це означає лише те, що об'єкт використовується іншим процесом (або процесами). Коли і інші процеси завершать свою роботу з цим об'єктом (теж викликавши CloseHandle), він буде зруйнований.

А раптом Ви забули викликати CloseHandle - чи буде витік пам'яті? І так і ні. Витік ресурсів (тих же об'єктів ядра) цілком імовірна, поки процес ще виконується. Однак по завершенні процесу операційна система гарантовано звільняє всі ресурси, які належали цьому процесу, і в разі об'єктів ядра діє так: в момент завершення процесу переглядає його таблицю описателей і закриває будь-які відкриті описатели.

Схожі статті