Aracılığıyla paylaş


Lower-Level Sürücüleri için IRP'ler Oluşturma

Daha düşük sürücüler tarafından rastgele bir iş parçacığı bağlamında işlenecek zaman uyumsuz istek için bir IRP ayırmak için DispatchReadWrite yordamı aşağıdaki destek yordamlarından birini çağırabilir:

  • IoAllocateIrp, bir IRP ve sıfırla başlatılmış birden fazla G/Ç yığın konumu ayırır

    Dağıtım yordamı, yeni ayrılan IRP için sonraki-alt sürücünün G/Ç yığını konumunu ayarlamalıdır; genellikle özgün IRP'deki kendi yığın konumundan bilgi kopyalayarak (muhtemelen değiştirilmiş olabilir). Daha üst düzey bir sürücü yeni ayrılan bir IRP için kendi G/Ç yığını konumunu ayırırsa, gönderme yordamı IoCompletion yordamının kullanması için istek başına bağlam bilgilerini burada ayarlayabilir.

  • IoBuildAsynchronousFsdRequest, arayanın belirlediği parametrelere göre bir sonraki-alt sürücünün G/Ç yığını konumunu ayarlar.

    Üst düzey sürücüler IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS ve IRP_MJ_SHUTDOWN istekleri için IRP ayırmak amacıyla bu yordamı çağırabilir.

    Böyle bir IRP için IoCompletion yordamı çağrıldığında G/Ç durum bloğunu denetleyebilir ve gerekirse (veya mümkünse) IRP'de sonraki-alt sürücünün G/Ç yığını konumunu yeniden ayarlayabilir ve isteği yeniden deneyebilir veya yeniden kullanabilir. Ancak IoCompletion yordamının IRP'de kendisi için yerel bağlam depolama alanı yoktur, bu nedenle sürücünün yerleşik belleğin başka bir yerinde özgün istekle ilgili bağlamı koruması gerekir.

  • IoMakeAssociatedIrp, bir IRP ve sıfırla başlatılmış bir dizi I/O yığını konumu tahsis eder ve IRP'yi bir ana IRP ile ilişkilendirir.

    Ara sürücüler, düşük sürücüler için IRP'ler oluşturmak için IoMakeAssociatedIrp'i çağıramaz.

    Düşük sürücüler için IRP'ler oluşturmak üzere IoMakeAssociatedIrp'i çağıran herhangi bir üst düzey sürücü, ilişkilendirilmiş IRP'lerini üzerinde gönderdikten ve özgün ana IRP için IoMarkIrpPending'i çağırdıktan sonra G/Ç yöneticisine denetim döndürebilir. En üst düzeydeki sürücü, tüm ilişkili IRP'ler alt düzey sürücüler tarafından tamamlandığında ana IRP'yi tamamlamak için G/Ç yöneticisine güvenebilir.

    Sürücüler nadiren ilişkili bir IRP için IoCompletion rutini belirler. En üst düzey sürücü oluşturduğu ilişkilendirilmiş bir IRP için IoSetCompletionRoutine'i çağırırsa, sürücü IoCompletion yordamından STATUS_MORE_PROCESSING_REQUIRED döndürürse G/Ç yöneticisi ana IRP'yi tamamlamaz. Bu durumlarda, sürücünün IoCompletion yordamının IoCompleteRequest ile ana IRP'yi açıkça tamamlaması gerekir.

Sürücü yeni bir IRP'de kendi G/Ç yığını konumunu ayırırsa, ioCompletion yordamı için kendi G/Ç yığını konumunda bağlam ayarlamak üzere IoGetCurrentIrpStackLocation çağrısından önce dağıtım yordamının IoSetNextIrpStackLocation çağrısı yapması gerekir. Daha fazla bilgi için bakınız Intermediate-Level Sürücüsünde IRP'leri İşleme.

Gönderme yordamı, IoMarkIrpPending'i özgün IRP ile çağırmalıdır, ancak IoCompletion yordamı bunları serbest bırakacağından sürücü tarafından ayrılan IRP'lerle çağırmamalıdır.

Dağıtım rutini, IRP'leri kısmi aktarımlar için ayırıyorsa ve temel alınan cihaz sürücüsü çıkarılabilir medya cihazını kontrol edebilirse, dağıtım rutininde orijinal IRP'deki Tail.Overlay.Thread değerinden yeni tahsis edilen IRP'lerde iş parçacığı bağlamını ayarlaması gerekir.

Çeşitli medya cihazları için temel bir sürücü, sürücü tarafından tahsis edilen bir IRP için işaretçiye başvuran IoSetHardErrorOrVerifyDevice'i çağırabilir; bu, Irp->Tail.Overlay.Thread'deki işaretçiyi referans alır. Sürücü bu destek yordamını çağırırsa, dosya sistemi sürücüsü uygun kullanıcı iş parçacığına, kullanıcının sürücünün karşılayamadıdığı bir işlemi iptal etme, yeniden deneme veya başarısız olmasını isteyen bir iletişim kutusu gönderebilir. Daha fazla bilgi için bkz. Çıkarılabilir Medyayı Destekleme .

Dağıtım yordamları, sürücüye ayrılan tüm IRP'leri alt sürücülere gönderdikten sonra STATUS_PENDING döndürmelidir.

Bir sürücünün IoCompletion yordamı, özgün IRP için IoCompleteRequest'i çağırmadan önce IoFreeIrp ile sürücüye ayrılan tüm IRP'leri serbest etmelidir. Özgün IRP'yi tamamladığında, IoCompletion yordamının kontrolü geri vermeden önce sürücü tarafından ayrılmış tüm IRP'leri serbest bırakması gerekir.

Her üst düzey sürücü, alt sürücüler için sürücü tarafından tahsis edilen (ve yeniden kullanılan) IRP'leri öyle bir şekilde düzenler ki, belirli bir isteğin ara sürücüden mi yoksa dosya sistemi veya kullanıcı modu uygulaması gibi başka bir kaynaktan mı geldiği temel alınan cihaz sürücüsü için önemli değildir.

En üst düzey sürücüler IRP'leri ayırmak ve bunları daha düşük sürücü zinciri için ayarlamak için IoMakeAssociatedIrp'i çağırabilir. Sürücü ioSetCompletionRoutine'i özgün IRP ile veya ayırdığı ilişkili IRP'lerden herhangi biriyle çağırmadığı sürece, I/O yöneticisi tüm ilişkili IRP'leri tamamlandığında özgün IRP'yi otomatik olarak tamamlar. Ancak üst düzey sürücüler, tampon bellekli G/Ç işlemi talep eden IRP'ler için ilişkili IRP'leri ayırmamalıdır.

Orta düzey bir sürücü, IoMakeAssociatedIrp çağrısı yaparak alt düzey sürücüler için IRP'leri ayıramaz. Ara sürücünün aldığı herhangi bir IRP zaten ilişkili bir IRP olabilir ve bir sürücü başka bir IRP'yi böyle bir IRP ile ilişkilendiremez.

Bunun yerine, bir ara sürücü daha düşük sürücüler için IRP'ler oluşturursa IoAllocateIrp, IoBuildDeviceIoControlRequest, IoBuildSynchronousFsdRequest veya IoBuildAsynchronousFsdRequest çağrılmalıdır. Ancak , IoBuildSynchronousFsdRequest yalnızca aşağıdaki durumlarda çağrılabilir:

  • Okuma veya yazma istekleri için IRP'ler oluşturmak üzere sürücü tarafından oluşturulan bir iş parçacığı tarafından, çünkü böyle bir iş parçacığı IoBuildSynchronousFsdRequest'egeçirilen sürücü tarafından başlatılan olay gibi bir dağıtıcı nesnesinde sabit olmayan bir iş parçacığı bağlamında (kendi başına) bekleyebilir

  • Başlatma sırasında veya kaldırma sırasında sistem iş parçacığı bağlamında

  • Oluşturma, temizleme, kapatma, kapatma ve cihaz denetimi istekleri gibi doğal olarak zaman uyumlu işlemler için IRP'ler oluşturmak için

Ancak, bir sürücünün cihaz denetimi IRP'lerini ioBuildSynchronousFsdRequest'e göre ayırmak için IoBuildDeviceIoControlRequest'i çağırma olasılığı daha yüksektir.