Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek popisuje, jak vytvořit jedinečný kód IOCTL. IOCTLs mohou být:
- Veřejné IOCTLs, které jsou obvykle systémově definované a zdokumentované společností Microsoft.
- Privátní IOCTLs, které jsou obvykle určeny výhradně pro vzájemnou komunikaci softwarových komponent dodavatele. Obvykle jsou definovány v souboru hlaviček dodavatele a nejsou zdokumentované Společností Microsoft.
Rozložení IOCTL
Hodnota IOCTL je 32bitová hodnota, která se skládá z několika polí. Následující obrázek znázorňuje bitové uspořádání IOCTL.
Každé pole v IOCTL má specifický účel, jak je popsáno v následující tabulce:
| Obor | Bity v IOCTL | Popis |
|---|---|---|
| Společné | 31 | Dodavatelé musí tento bit nastavit, pokud pro DeviceType používají hodnotu přiřazenou dodavatelem. |
| TypZařízení | 16-30 | Určuje typ zařízení. Tato hodnota se musí shodovat s hodnotou nastavenou v členu DeviceType struktury DEVICE_OBJECT ovladače. Dodavatelé by měli použít hodnotu od 32768 do 65535 (0x8000 až 0xffff) a měli by nastavit běžný bit. Hodnoty 0 až 32767 (0x0000 až 0x7fff) jsou vyhrazené pro Microsoft. Další informace naleznete v tématu Určení typů zařízení. |
| Přístup | 14-15 | Určuje typ přístupu, který volající musí požadovat při otevření objektu souboru, který představuje zařízení (viz IRP_MJ_CREATE). Správce vstupně-výstupních operací vytvoří IRP a zavolá ovladač s konkrétní hodnotou IOCTL pouze v případě, že volající požadoval zadaná přístupová práva. Toto pole je určeno pomocí následujících systémově definovaných konstant: FILE_ANY_ACCESS, FILE_READ_DATA a FILE_WRITE_DATA. |
| na míru | 13 | Při nastavení to označuje, že IOCTL je definováno dodavatelem. |
| Funkce | 2-12 | Jedinečný kód pro ovladač, který identifikuje funkci, kterou má provést. Pro hodnotu IOCTL vytvořenou dodavatelem použijte hodnotu v rozsahu od 2048 do 4095 (0x800 až 0xfff) a nastavte bit Vlastní. Hodnoty menší než 2048 (0x000 až 0x7ff) jsou vyhrazené pro Microsoft. |
| Metoda | 0-1 | Určuje, jak má systém předávat data mezi volajícím DeviceIoControl (nebo IoBuildDeviceIoControlRequest) a ovladačem, který zpracovává IRP. Další informace naleznete v části Pokyny k nastavení bitů metody. |
Makro pro definování kódů ovládacích prvků vstupně-výstupních operací
Pomocí systémového CTL_CODE makra definujte nové kódy ovládacích prvků vstupně-výstupních operací. Toto makro je definováno v souboru devioctl.h následujícím způsobem:
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
Popis deviceType, Function, Method a Access najdete v předchozí části.
Při definování nových kódů ovládacích prvků vstupně-výstupních operací mějte na paměti následující pravidla:
Pokud bude nové IOCTL dostupné softwarovým komponentám v uživatelském módu, musí být používáno s požadavky IRP_MJ_DEVICE_CONTROL. Komponenty uživatelského režimu volají DeviceIoControl k odesílání IRP_MJ_DEVICE_CONTROL požadavků.
Pokud je nová hodnota IOCTL dostupná pouze pro komponenty ovladače v režimu jádra, musí být použita s požadavky IRP_MJ_INTERNAL_DEVICE_CONTROL. Komponenty režimu jádra mohou vytvářet požadavky IRP_MJ_INTERNAL_DEVICE_CONTROL voláním IoBuildDeviceIoControlRequest. Další informace naleznete v tématu Vytváření žádostí IOCTL v ovladačích.
Definice nového kódu IOCTL, ať už je určená pro IRP_MJ_DEVICE_CONTROL nebo IRP_MJ_INTERNAL_DEVICE_CONTROL požadavky, používá následující formát:
#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)
Zvolte popisný název konstanty pro hodnotu IOCTL formuláře IOCTL_Device_Function, kde Zařízení označuje typ zařízení a funkce indikuje operaci. Například systém dodávaná IOCTL_VIDEO_ENABLE_CURSOR konstanta používá "VIDEO" pro zařízení a "ENABLE_CURSOR" pro funkci.
Pokyny k nastavení bitů Accessu
Při definování nové hodnoty IOCTL musíte zvolit hodnotu pro bitové pole Accessu , která označuje typ přístupu, který volající musí požádat při otevření objektu souboru, který představuje zařízení. Správce vstupně-výstupních operací vytvoří IRP a zavolá ovladač s konkrétním IOCTL pouze v případě, že volající požaduje specifická přístupová práva.
Access je určen pomocí následujících systémově definovaných konstant:
FILE_ANY_ACCESS
Správce vstupně-výstupních operací odešle IRP pro všechny volající, kteří mají popisovač objektu souboru, který představuje objekt cílového zařízení. Než zadáte FILE_ANY_ACCESS pro nový kód IOCTL, musíte mít naprosto jistotu, že povolení neomezeného přístupu k vašemu zařízení nevytváří možnou cestu pro uživatele se zlými úmysly k ohrožení systému.
ČTENÍ_DAT_Z_SOUBORU
Správce vstupně-výstupních operací odešle protokol IRP jenom pro volajícího s přístupovými právy ke čtení a umožní ovladači základního zařízení přenášet data ze zařízení do systémové paměti.
FILE_WRITE_DATA (zápis dat do souboru)
Správce vstupně-výstupních operací odešle protokol IRP jenom pro volajícího s přístupovými právy k zápisu a umožní ovladači základního zařízení přenášet data ze systémové paměti do jeho zařízení.
FILE_READ_DATA a FILE_WRITE_DATA mohou být zkombinovány pomocí operace OR dohromady, pokud volající musí mít přístupová práva ke čtení i zápisu.
Některé kódy řízení vstupně-výstupních operací definované systémem mají hodnotu Access FILE_ANY_ACCESS, která volajícímu umožňuje odeslat konkrétní hodnotu IOCTL bez ohledu na přístup udělený zařízení. Mezi příklady patří řídicí kódy vstupně-výstupních operací, které se odesílají ovladačům exkluzivních zařízení.
Jiné kódy řízení vstupně-výstupních operací definovaných systémem vyžadují, aby volající měl přístupová práva ke čtení, přístupová práva k zápisu nebo obojí. Například následující definice veřejné IOCTL_DISK_SET_PARTITION_INFO IOCTL ukazuje, že tento vstupně-výstupní požadavek lze odeslat ovladači pouze v případě, že volající má přístupová práva ke čtení i zápisu:
#define IOCTL_DISK_SET_PARTITION_INFO\
CTL_CODE(IOCTL_DISK_BASE, 0x008, METHOD_BUFFERED,\
FILE_READ_DATA | FILE_WRITE_DATA)
Ovladače mohou použít IoValidateDeviceIoControlAccess k provádění přísnější kontroly přístupu, než jakou nabízejí přístupové bity IOCTL.
Pokyny k nastavení bitů metody
Při definování nové hodnoty IOCTL musíte zvolit hodnotu pro pole Bit Method , která označuje, jak má systém předávat data mezi volajícím DeviceIoControl (nebo IoBuildDeviceIoControlRequest) a ovladačem, který zpracovává IRP.
K nastavení pole Metoda použijte jednu z následujících systémově definovaných konstant.
METHOD_UKLÁDANÝ
Určuje metodu vyrovnaného I/O, která se obvykle používá pro přenos malých objemů dat na každou žádost. Většina kódů ovládacích prvků vstupně-výstupních operací pro zařízení a zprostředkující ovladače tuto hodnotu používá.
Informace o tom, jak systém určuje vyrovnávací paměti dat pro METHOD_BUFFERED vstupně-výstupní řídicí kódy, naleznete v tématu Popisy vyrovnávací paměti pro vstupně-výstupní řídicí kódy.
Další informace o vstupně-výstupních operacích s vyrovnávací pamětí najdete v tématu Použití vstupně-výstupních operací ve vyrovnávací paměti.
METHOD_IN_DIRECT nebo METHOD_OUT_DIRECT
Určuje přímou vstupně-výstupní metodu, která se obvykle používá ke čtení nebo zápisu velkých objemů dat pomocí DMA nebo PIO, které se musí rychle přenést.
Zadejte METHOD_IN_DIRECT, pokud volající DeviceIoControl nebo IoBuildDeviceIoControlRequest předá data ovladači.
Zadejte METHOD_OUT_DIRECT, pokud volající DeviceIoControl nebo IoBuildDeviceIoControlRequest obdrží data z ovladače.
Informace o tom, jak systém určuje vyrovnávací paměti dat pro METHOD_IN_DIRECT a METHOD_OUT_DIRECT V/V řídicí kódy, naleznete v tématu Popisy vyrovnávací paměti pro vstupně-výstupní řídicí kódy.
Další informace o přímých vstupně-výstupních operacích naleznete v tématu Použití přímých vstupně-výstupních operací.
METODA_ANI_JEDNA
Určuje , že vstupně-výstupní metoda není ukládána do vyrovnávací paměti ani není přímá. Správce vstupně-výstupních operací neposkytuje žádné systémové vyrovnávací paměti ani knihovny MDLS. IRP poskytuje virtuální adresy uživatelského režimu vstupních a výstupních vyrovnávacích pamětí zadaných pro DeviceIoControl nebo IoBuildDeviceIoControlRequest bez ověření nebo mapování.
Informace o tom, jak systém určuje vyrovnávací paměti dat pro METHOD_NEITHER vstupně-výstupní řídicí kódy, naleznete v tématu Popisy vyrovnávací paměti pro vstupně-výstupní řídicí kódy.
Tuto metodu lze použít pouze v případě, že je zaručeno, že ovladač běží v kontextu vlákna, které pochází z žádosti o řízení vstupně-výstupních operací. Tento stav zaručuje pouze ovladač režimu jádra nejvyšší úrovně, takže metoda METHOD_NEITHER se zřídka používá pro IOCTLs, které se předávají ovladačům zařízení nízké úrovně.
Tímto způsobem ovladač nejvyšší úrovně:
- Musí určit, jestli se má nastavit vyrovnávací paměť nebo přímý přístup k uživatelským datům při přijetí žádosti.
- Možná musí uzamknout uživatelský pufr.
- Musí zabalit přístup k vyrovnávací paměti uživatele do strukturované obslužné rutiny výjimek (viz Zpracování výjimek).
V opačném případě může volající v uživatelském režimu změnit data uložená ve vyrovnávací paměti dříve, než je ovladač může použít, nebo může být volající vykázán z paměti právě ve chvíli, kdy ovladač přistupuje k uživatelské vyrovnávací paměti.
Další informace naleznete v tématu Použití žádné vyrovnávací paměti ani přímé vstupně-výstupní operace.
Další užitečná makra
Následující makra jsou užitečná pro extrahování 16bitového pole DeviceType a 2bitového pole Metoda z hodnoty IOCTL.
#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0xffff0000)) >> 16)
#define METHOD_FROM_CTL_CODE(ctrlCode) ((ULONG)(ctrlCode & 3))
Tato makra jsou definována v wdm.h a Ntddk.h.