Cihaz Kuyruklarını Ayarlama ve Kullanma

Sürücü, sürücü veya cihaz başlatma sırasında KeInitializeDeviceQueue'yi çağırarak bir cihaz kuyruğu nesnesi ayarlar. Aygıtlarını başlattıktan sonra, sürücü KeInsertDeviceQueue veya KeInsertByKeyDeviceQueue'yi çağırarak IRP'leri bu kuyruğa ekler. Aşağıdaki şekilde bu çağrılar gösterilmektedir.

cihaz kuyruklarını ayarlama ve kullanma.

Bu şekilde gösterildiği gibi, sürücünün yerleşik olması gereken bir cihaz kuyruğu nesnesi için depolama sağlaması gerekir. Cihaz kuyruğu nesnesi ayarlayan sürücüler genellikle sürücü tarafından oluşturulan bir cihaz nesnesinin cihaz uzantısında gerekli depolama alanını sağlar, ancak sürücü bir denetleyici nesnesi kullanıyorsa veya sürücü tarafından ayrılmış sayfasız havuzda depolama alanı bir denetleyici uzantısında olabilir.

Sürücü bir cihaz uzantısında cihaz kuyruğu nesnesi için depolama alanı sağlıyorsa, cihaz nesnesini oluşturduktan sonra ve cihazı başlatmadan önce KeInitializeDeviceQueue'yi çağırır. Başka bir deyişle, sürücü kuyruğu AddDevice yordamından veya PnP IRP_MN_START_DEVICE isteğini işlediğinde başlatabilir. KeInitializeDeviceQueue çağrısında, sürücü cihaz kuyruğu nesnesi için sağladığı depolamaya bir işaretçi geçirir.

Sürücü, cihazlarını başlattıktan sonra, IRP'yi kuyruğun kuyruğuna yerleştiren KeInsertDeviceQueue veya önceki şekilde gösterildiği gibi IRP'yi sürücü tarafından belirlenen SortKey değerine göre kuyruğa yerleştiren KeInsertDeviceQueue'yi çağırarak cihaz kuyruğuna bir IRP ekleyebilir.

Bu destek yordamlarının her biri, IRP'nin kuyruğa eklenip eklenmediğini belirten bir Boole değeri döndürür. Bu çağrıların her biri, kuyruk şu anda boşsa (Not-Busy) cihaz kuyruğu nesnesinin durumunu Meşgul olarak da ayarlar. Ancak, kuyruk boşsa (Not-Busy), hiçbir KeInsertXxxDeviceQueue yordamı IRP'yi kuyruğa eklemez. Bunun yerine, cihaz kuyruğu nesnesinin durumunu Meşgul olarak ayarlar ve YANLIŞ döndürür. IRP kuyruğa alınmadığı için, sürücü onu daha fazla işlem için başka bir sürücü rutinine aktararak devam etmek zorundadır.

Ek cihaz kuyruklarını ayarlarken şu uygulama yönergelerini izleyin:

KeInsertXxxDeviceQueue çağrısı FALSE döndürdüğünde, çağıranın daha fazla işlem yapmak için kuyruğa almaya çalıştığı IRP'yi başka bir sürücü rutinine geçirmesi gerekiyor. Ancak KeInsertXxxDeviceQueue çağrısı cihaz kuyruğu nesnesinin durumunu Meşgul olarak değiştirir. Bu nedenle, sürücü önce KeRemoveXxxDeviceQueue'yi çağırmadıkça, bir sonraki IRP kuyruğa eklenir.

Cihaz kuyruğu nesnesinin durumu Meşgul olarak ayarlandığında, sürücü daha fazla işlem için bir IRP'yi kuyruktan çıkarabilir veya aşağıdaki destek yordamlarından birini çağırarak durumu Not-Busy olarak sıfırlayabilir.

  • Kuyruğun başındaki IRP'yi kaldırmak için KeRemoveDeviceQueue

  • Sürücü tarafından belirlenen SortKey değerine göre seçilen bir IRP'yi kaldırmak için KeRemoveByKeyDeviceQueue

  • Kuyruktaki belirli bir IRP'yi kaldırmak veya belirli bir IRP'nin kuyrukta olup olmadığını belirlemek için KeRemoveEntryDeviceQueue

    KeRemoveEntryDeviceQueue , IRP'nin cihaz kuyruğunda olup olmadığını belirten bir Boole döndürür.

Boş ancak Meşgul olan bir cihaz kuyruğundan bir girdiyi kaldırmak için bu yordamlardan herhangi birinin çağrılması, kuyruk durumunu Meşgul Değil olarak değiştirir.

Her bir cihaz kuyruğu nesnesi, yerleşik bir yönetici döndürme kilidiyle korunur (Cihaz Kuyruğu Nesnesi Kullanma şeklinde gösterilmez). Sonuç olarak, bir sürücü, IRP'leri kuyruğa ekleyebilir ve bunları çok işlemcili bir sistemde güvenli bir şekilde, IRQL = DISPATCH_LEVEL veya daha düşük bir seviyede çalışan herhangi bir sürücü rutininden kaldırabilir. Bu IRQL kısıtlaması nedeniyle bir sürücü, DIRQL'de çalışan ISR veya SynchCritSection yordamlarından herhangi bir KeXxxDeviceQueue yordamını çağıramaz.

Daha fazla bilgi için Donanım Önceliklerini Yönetme ve Döndürme Kilitleri bölümüne bakın. Belirli bir destek yordamına yönelik IRQL gereksinimleri için yordamın başvuru sayfasına bakın.