Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, benzersiz bir G/Ç denetim kodunun (IOCTL) nasıl oluşturulacağı açıklanır. IOCTL'ler şu olabilir:
- Genellikle sistem tarafından tanımlanan ve Microsoft tarafından belgelenen genel IOCTL'ler.
- Genellikle bir satıcının yazılım bileşenleri tarafından birbirleriyle iletişim kurmak için kullanılması amaçlanan özel IOCTL'ler. Bunlar genellikle bir satıcının üst bilgi dosyasında tanımlanır ve Microsoft tarafından belgelenmez.
IOCTL düzeni
IOCTL, birkaç alandan oluşan 32 bitlik bir değerdir. Aşağıdaki şekilde bir IOCTL'nin bit tabanlı düzeni gösterilmektedir:
IOCTL'deki her alanın, aşağıdaki tabloda açıklandığı gibi belirli bir amacı vardır:
| Alan | IOCTL'de bitler | Açıklama |
|---|---|---|
| Ortak | 31 | Satıcılar DeviceType için satıcı tarafından atanan bir değer kullandıklarında bu biti ayarlamalıdır. |
| DeviceType | 16-30 | Cihaz türünü tanımlar. Bu değer, sürücünün DEVICE_OBJECT yapısının DeviceType üyesinde ayarlanan değerle eşleşmelidir. Satıcılar 32768 ile 65535 (0xffff arasında 0x8000) değerini kullanmalı ve Ortak biti ayarlamalıdır. 0 ile 32767 (0x7fff arasında 0x0000) değerleri Microsoft için ayrılmıştır. Daha fazla bilgi için bkz. Cihaz Türlerini Belirtme. |
| Erişim | 14-15 | Bir çağıranın cihazı temsil eden dosya nesnesini açarken istemesi gereken erişim türünü gösterir (bkz. IRP_MJ_CREATE). G/Ç yöneticisi, IRP'leri oluşturur ve yalnızca çağıranın belirtilen erişim haklarını talep ettiği durumlarda sürücüyü belirli bir IOCTL ile çağırır. Bu alan şu sistem tanımlı sabitler kullanılarak belirtilir: FILE_ANY_ACCESS, FILE_READ_DATA ve FILE_WRITE_DATA. |
| Özel | 13 (on üç) | Ayarlandığında, IOCTL'nin satıcı tanımlı bir IOCTL olduğunu gösterir. |
| İşlev | 2-12 | Gerçekleştirilecek işlevi tanımlayan sürücü için benzersiz kod. Satıcı tarafından oluşturulan bir IOCTL için 2048 ile 4095 (0xfff arasında 0x800) değerini kullanın ve Özel biti ayarlayın. 2048'den küçük değerler (0x000 ile 0x7ff arasında) Microsoft için ayrılmıştır. |
| Yöntemi | 0-1 | Sistemin DeviceIoControl (veya IoBuildDeviceIoControlRequest) çağıranı ile IRP'yi işleyen sürücü arasında nasıl veri geçirildiğini gösterir. Daha fazla bilgi için bkz . Yöntem bitlerini ayarlama yönergeleri. |
G/Ç denetim kodlarını tanımlamak için makro
Yeni G/Ç denetim kodlarını tanımlamak için sistem tarafından sağlanan CTL_CODE makroyu kullanın. Bu makro devioctl.h dosyasında aşağıdaki gibi tanımlanır:
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
)
DeviceType, Function, Method ve Access'in açıklaması için önceki bölüme bakın.
Yeni G/Ç denetim kodlarını tanımlarken aşağıdaki kuralları göz önünde bulundurun:
Kullanıcı modu yazılım bileşenleri için yeni bir IOCTL kullanılabilir olacaksa, IRP_MJ_DEVICE_CONTROL istekleriyle kullanılmalıdır. Kullanıcı modu bileşenleri, IRP_MJ_DEVICE_CONTROL istekleri göndermek için DeviceIoControl'u çağırır.
Yeni bir IOCTL yalnızca çekirdek modu sürücü bileşenleri için kullanılabilir olacaksa, IRP_MJ_INTERNAL_DEVICE_CONTROL istekleriyle kullanılmalıdır. Çekirdek modu bileşenleri, IoBuildDeviceIoControlRequest çağrısı yaparak IRP_MJ_INTERNAL_DEVICE_CONTROL istekleri oluşturabilir. Daha fazla bilgi için bkz. Sürücülerde IOCTL İstekleri Oluşturma.
İster IRP_MJ_DEVICE_CONTROL ister IRP_MJ_INTERNAL_DEVICE_CONTROL istekleriyle kullanılmak üzere tasarlanan yeni bir IOCTL kodunun tanımı aşağıdaki biçimi kullanır:
#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)
IOCTL_Cihaz_İşlevi biçimindeki IOCTL için açıklayıcı bir sabit ad seçin; burada Cihaz, cihaz türünü ve İşlev işlemi gösterir. Örneğin, sistem tarafından sağlanan IOCTL_VIDEO_ENABLE_CURSOR sabiti Cihaz için "VİDEO" ve İşlev için "ENABLE_CURSOR" kullanır.
Access bitlerini ayarlama kılavuzu
Yeni bir IOCTL tanımlarken, Access bit alanı için bir çağıranın cihazı temsil eden dosya nesnesini açarken istemesi gereken erişim türünü gösteren bir değer seçmeniz gerekir. G/Ç yöneticisi, yalnızca çağıran kişi belirtilen erişim haklarını talep ettiğinde IRP'ler oluşturur ve sürücüyü belirli bir IOCTL ile çağırır.
Erişim , aşağıdaki sistem tanımlı sabitler kullanılarak belirtilir:
HİÇBİR_ERMİSİMLE_BİLGİYE_ULAŞIM
G/Ç yöneticisi, hedef cihaz nesnesini temsil eden dosya nesnesine erişim hakkı olan herhangi bir çağıranın IRP'sini gönderir. Yeni bir IOCTL kodu için FILE_ANY_ACCESS belirtmeden önce cihazınıza sınırsız erişim izni vermenin kötü amaçlı kullanıcıların sistemi tehlikeye atması için olası bir yol oluşturmadığından kesinlikle emin olmalısınız.
DOSYA_OKUMA_VERİSİ
G/Ç yöneticisi, IRP'yi yalnızca okuma erişim haklarına sahip bir arayan için gönderir ve temel cihaz sürücüsünün cihazdan sistem belleğine veri aktarmasına izin verir.
DOSYA_VERİ_YAZ
G/Ç yöneticisi, IRP'yi yalnızca yazma erişim haklarına sahip bir arayan için gönderir ve temel cihaz sürücüsünün sistem belleğinden cihazına veri aktarmasına izin verir.
Çağıranın hem okuma hem de yazma erişim hakları olması gerekiyorsa FILE_READ_DATA ve FILE_WRITE_DATA birlikte ORed yapılabilir.
Bazı sistem tanımlı G/Ç denetim kodları, çağıranın cihaza verilen erişimden bağımsız olarak belirli bir IOCTL göndermesine olanak tanıyan FILE_ANY_ACCESS Erişim değerine sahiptir. Örnek olarak özel cihazların sürücülerine gönderilen G/Ç denetim kodları verilebilir.
Diğer sistem tanımlı G/Ç denetim kodları, çağıranın okuma erişim haklarına, yazma erişim haklarına veya her ikisine de sahip olmasını gerektirir. Örneğin, genel IOCTL_DISK_SET_PARTITION_INFO IOCTL'nin aşağıdaki tanımı, bu G/Ç isteğinin yalnızca çağıranın hem okuma hem de yazma erişim hakları varsa bir sürücüye gönderilebileceğini gösterir:
#define IOCTL_DISK_SET_PARTITION_INFO\
CTL_CODE(IOCTL_DISK_BASE, 0x008, METHOD_BUFFERED,\
FILE_READ_DATA | FILE_WRITE_DATA)
Sürücüler, IOCTL'nin Access bitleri tarafından sağlanandan daha katı erişim denetimi gerçekleştirmek için IoValidateDeviceIoControlAccess kullanabilir.
Yöntem bitlerini ayarlama kılavuzu
Yeni bir IOCTL tanımlarken , Method bit alanı için, sistemin DeviceIoControl (veya IoBuildDeviceIoControlRequest) çağıranı ile IRP'yi işleyen sürücü arasında nasıl veri geçireceğini gösteren bir değer seçmeniz gerekir.
Yöntem alanını ayarlamak için aşağıdaki sistem tanımlı sabitlerden birini kullanın.
BUFFERED_YÖNTEM
Genellikle istek başına küçük miktarda veri aktarmak için kullanılan arabelleğe alınan G/Ç yöntemini belirtir. Cihaz ve ara sürücüler için G/Ç denetim kodlarının çoğu bu değeri kullanır.
Sistemin METHOD_BUFFERED G/Ç denetim kodları için veri arabelleklerini nasıl belirttiği hakkında bilgi için bkz. G/Ç Denetim Kodları için Arabellek Açıklamaları.
Arabelleğe alınan G/Ç hakkında daha fazla bilgi için Arabelleğe Alınan G/Ç Kullanımı bölümüne bakın.
METHOD_IN_DIRECT veya METHOD_OUT_DIRECT
Genellikle hızlı bir şekilde aktarılması gereken DMA veya PIO kullanarak büyük miktarda veriyi okumak veya yazmak için kullanılan doğrudan G/Ç yöntemini belirtir.
DeviceIoControl veya IoBuildDeviceIoControlRequest çağıranın sürücüye veri geçirip geçirmediğini METHOD_IN_DIRECT belirtin.
DeviceIoControl veya IoBuildDeviceIoControlRequest çağrısının sürücüden veri alacağı durumunda METHOD_OUT_DIRECT belirtin.
Sistemin METHOD_IN_DIRECT ve METHOD_OUT_DIRECT G/Ç denetim kodları için veri arabelleklerini nasıl belirttiği hakkında bilgi için bkz. G/Ç Denetim Kodları için Arabellek Açıklamaları.
Doğrudan G/Ç hakkında daha fazla bilgi için bkz. Doğrudan G/Ç kullanma.
YÖNTEM_HİÇBİRİ
G/Ç yönteminin arabelleksiz veya doğrudan olmadığını belirtir. G/Ç yöneticisi herhangi bir sistem arabelleği veya MDL sağlamaz. IRP, DeviceIoControl veya IoBuildDeviceIoControlRequest için belirtilen giriş ve çıkış arabelleklerinin kullanıcı modu sanal adreslerini doğrulamadan veya eşlemeden sağlar.
Sistemin METHOD_NEITHER G/Ç denetim kodları için veri arabelleklerini nasıl belirttiği hakkında bilgi için bkz. G/Ç Denetim Kodları için Arabellek Açıklamaları.
Bu yöntem yalnızca sürücünün G/Ç denetim isteğinin kaynağı olan iş parçacığı bağlamında çalışması garanti edilirse kullanılabilir. Yalnızca en üst düzey çekirdek modu sürücüsünün bu koşulu karşılaması garanti edilir, bu nedenle METHOD_NEITHER düşük düzeyli cihaz sürücülerine geçirilen IOCTL'ler için nadiren kullanılır.
Bu yöntemle, en üst düzey sürücü:
- İstek alındığında kullanıcı verilerine arabelleğe alınmış mı yoksa doğrudan erişim mi ayarlanacağı belirlenmelidir.
- Muhtemelen kullanıcı arabelleğinin kilitlenmesi gerekebilir.
- Yapılandırılmış bir özel durum işleyicisi içinde, kullanıcı arabelleğine erişimini sarmalamalıdır (bkz Özel Durumları İşleme).
Aksi takdirde, kaynak kullanıcı modu çağıranı, sürücü verileri kullanamadan arabellekteki verileri değiştirebilir ya da sürücü kullanıcı arabelleğine erişirken çağıran süreç aniden değiştirilebilir.
Daha fazla bilgi için bkz. Ne Arabelleğe Alınan Ne de Doğrudan G/Ç Kullanma.
Diğer yararlı makrolar
Aşağıdaki makrolar, IOCTL'den 16 bit DeviceType ve 2 bit Yöntem alanlarını ayıklamak için kullanışlıdır.
#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0xffff0000)) >> 16)
#define METHOD_FROM_CTL_CODE(ctrlCode) ((ULONG)(ctrlCode & 3))
Bu makrolar Wdm.h ve Ntddk.h'de tanımlanır.