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.
Při definování nových IOCTLs je důležité pamatovat na následující pravidla:
- Pokud bude nová IOCTL k dispozici softwarovým komponentám v uživatelském režimu, musí být tato IOCTL použita s požadavky IRP_MJ_DEVICE_CONTROL. Komponenty uživatelského režimu odesílají požadavky IRP_MJ_DEVICE_CONTROL voláním DeviceIoControl, což je funkce Win32.
- Pokud bude nová hodnota IOCTL k dispozici pouze pro součásti ovladače v režimu jádra, musí být hodnota IOCTL použita s požadavky IRP_MJ_INTERNAL_DEVICE_CONTROL . Komponenty režimu jádra vytvářejí požadavky IRP_MJ_INTERNAL_DEVICE_CONTROL voláním IoBuildDeviceIoControlRequest. Další informace naleznete v tématu Vytváření žádostí IOCTL v ovladačích.
Kód ovládacího prvku vstupně-výstupních operací je 32bitová hodnota, která se skládá z několika polí. Následující obrázek znázorňuje rozložení kódů ovládacích prvků vstupně-výstupních operací.
Pomocí systémového CTL_CODE makra, které je definováno v wdm.h a Ntddk.h, definujte nové vstupně-výstupní řídicí kódy. 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 označuje operaci. Příklad názvu konstanty je IOCTL_VIDEO_ENABLE_CURSOR.
Do CTL_CODE makra zadejte následující parametry:
DeviceType
Identifikuje typ zařízení. Tato hodnota se musí shodovat s hodnotou nastavenou v členu DeviceType struktury DEVICE_OBJECT ovladače. (Viz Určení typů zařízení). Hodnoty menší než 0x8000 jsou vyhrazené pro Microsoft. Hodnoty 0x8000 a vyšší můžou používat dodavatelé. Všimněte si, že hodnoty přiřazené dodavatelem nastavily Common bit.
FunctionCode
Identifikuje funkci, kterou má ovladač provést. Hodnoty menší než 0x800 jsou vyhrazené pro Microsoft. Hodnoty 0x800 a vyšší můžou používat dodavatelé. Všimněte si, že hodnoty přiřazené dodavatelem nastavují Custom bit.
Typ přenosu
Určuje, jak bude systém předávat data mezi volajícím DeviceIoControl (nebo IoBuildDeviceIoControlRequest) a ovladačem, který zpracovává IRP.
Použijte jednu z následujících systémově definovaných konstant:
METHOD_BUFFERED
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 používá tuto hodnotu TransferType .
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 budou předávat 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í.
METHOD_NEITHER
Určuje , že nejsou v vyrovnávací paměti ani přímé vstupně-výstupní operace. Správce vstupně-výstupních operací neposkytuje žádné systémové vyrovnávací paměti ani 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 možné zaručit, že ovladač běží v kontextu vlákna, které pochází z žádosti o řízení vstupně-výstupních operací. Je zaručeno, že tuto podmínku splní pouze ovladač režimu jádra nejvyšší úrovně, takže METHOD_NEITHER se zřídka používá pro kódy řízení vstupně-výstupních operací, které se předávají ovladačům zařízení nízké úrovně.
U této metody musí ovladač nejvyšší úrovně určit, zda má být nastavena vyrovnávací paměť nebo přímý přístup k uživatelským datům při přijetí požadavku, případně musí uzamknout vyrovnávací paměť uživatele a musí zabalit svůj přístup k vyrovnávací paměti uživatele ve strukturované obslužné rutině výjimky (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.
RequiredAccess
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ím kódem IO řízení pouze v případě, že volající požádal o specifikovaná přístupová práva.
RequiredAccess je určen pomocí následujících systémově definovaných konstant:
FILE_JAKÝKOLI_PŘÍSTUP
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í.
FILE_READ_DATA
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
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 RequiredAccess 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 kódu pro řízení veřejných vstupně-výstupních operací IOCTL_DISK_SET_PARTITION_INFO 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)
Poznámka:
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.
Ovladače mohou použít IoValidateDeviceIoControlAccess k provádění přísnější kontroly přístupu, než která poskytuje bity RequiredAccess IOCTL.
Další užitečná makra
Následující makra jsou užitečná pro extrahování 16bitového pole DeviceType a 2bitového typu TransferType z kódu 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.