Nh?ng cách khác nhau c?a x? l? IRPs - cheat sheet (ph?n 1/2)

D?ch tiêu đ? D?ch tiêu đ?
ID c?a bài: 320275 - Xem s?n ph?m mà bài này áp d?ng vào.
Bung t?t c? | Thu g?n t?t c?

? Trang này

TÓM T?T

Giới thiệu

M?t trong nh?ng nhi?m v? thư?ng xuyên nh?t đư?c th?c hi?n trong mô h?nh tr?nh đi?u khi?n Windows Tr?nh đi?u khi?n (WDM) đang g?i thư yêu c?u đ?u vào/đ?u ra các gói d? li?u (IRPs) t? m?t trong nh?ng tr?nh đi?u khi?n đ? tr?nh đi?u khi?n khác. M?t ngư?i lái xe ho?c là t?o ra IRP riêng c?a nó và g?i nó đ?n th?p hơn tr?nh đi?u khi?n, ho?c tr?nh đi?u khi?n chuy?n ti?p IRPs nó nh?n đư?c tr?nh đi?u khi?n khác mà đư?c g?n vào phía trên.

Bài vi?t này th?o lu?n v? t?t c? nh?ng cách có th? r?ng m?t ngư?i lái xe có th? g?i IRPs đ?n m?t ngư?i lái xe th?p hơn v?i chú thích m?u m?. Tùy thu?c vào s? c?n thi?t, nhà văn ngư?i lái xe có th? làm theo m?t trong các b?n m?u đư?c đưa ra trong bài vi?t này và không b? ?nh hư?ng b?i c? IRP x? l? quy t?c.

Ph?n 1 c?a ch? đ? này cho th?y k?ch b?n 5 v? làm th? nào đ? chuy?n ti?p m?t IRP cho tr?nh đi?u khi?n khác t? m?t thói quen công văn, và 7 k?ch b?n c?n l?i (đư?c li?t kê trong ph?n 2 c?a ch? đ? này) th?o lu?n v? nh?ng cách khác nhau c?a vi?c t?o ra m?t IRP và g?i nó đ? tr?nh đi?u khi?n khác. Ph?n 2 c?a ch? đ? này đư?c ch?a trong các ki?n th?c sau đây Căn c? đi?u:
326315 Nh?ng cách khác nhau c?a x? l? IRPs - cheat sheet (ph?n 2/2)
Trư?c khi b?n xem xét các k?ch b?n khác nhau, lưu ? các sau đây v? t?nh tr?ng đư?c tr? v? b?i thói quen hoàn thành:
M?t thói quen hoàn thành IRP có th? tr? l?i ho?c STATUS_MORE_PROCESSING_REQUIRED ho?c STATUS_SUCCESS.
Ngư?i qu?n l? I/O s? d?ng các quy t?c sau khi nó ki?m tra các tr?ng thái:
  • N?u t?nh tr?ng STATUS_MORE_PROCESSING_REQUIRED, d?ng hoàn thành IRP, đ? l?i ngăn x?p v? trí không thay đ?i và tr? l?i.
  • N?u t?nh tr?ng là b?t c? đi?u g? khác hơn STATUS_MORE_PROCESSING_REQUIRED, ti?p t?c hoàn t?t IRP tr? lên.
B?i v? ngư?i qu?n l? I/O không ph?i bi?t đư?c giá tr? không STATUS_MORE_PROCESSING_REQUIRED đư?c s? d?ng, s? d?ng STATUS_SUCCESS (v? giá tr? 0 là m?t cách hi?u qu? loadable trên ki?n trúc b? x? l? h?u h?t).

Đ? c?i thi?n d? đ?c m?, Windows XP SP1 và Windows XP.NET Driver phát tri?n Kit Ntddk.h và Wdm.h tiêu đ? s? có m?t m?i # define có ngh?a là đ?t tên là STATUS_CONTINUE_COMPLETION, mà là bi?t đ? STATUS_SUCCESS như th? hi?n trong đo?n m? sau:
// 
// This value should be returned from completion routines to continue
// completing the IRP upwards. Otherwise, STATUS_MORE_PROCESSING_REQUIRED
// should be returned.
// 
#define STATUS_CONTINUE_COMPLETION      STATUS_SUCCESS
// 
// Completion routines can also use this enumeration instead of status codes.
// 
typedef enum _IO_COMPLETION_ROUTINE_RESULT {
    
    ContinueCompletion = STATUS_CONTINUE_COMPLETION,
    StopCompletion = STATUS_MORE_PROCESSING_REQUIRED

} IO_COMPLETION_ROUTINE_RESULT, *PIO_COMPLETION_ROUTINE_RESULT;
				

THÔNG TIN THÊM

K?ch b?n 1: Chuy?n ti?p và quên

S? d?ng m? sau đây n?u có m?t ngư?i lái xe ch? mu?n chuy?n ti?p IRP xu?ng và có không có hành đ?ng b? sung. Tr?nh đi?u khi?n không có thi?t l?p m?t hoàn thành thói quen trong trư?ng h?p này. N?u tr?nh đi?u khi?n m?t ngư?i lái xe c?p cao, IRP có th? đư?c hoàn t?t đ?ng b? ho?c không đ?ng b?, tùy thu?c vào t?nh tr?ng mà đư?c tr? l?i b?i ngư?i lái xe th?p hơn.
NTSTATUS
DispatchRoutine_1(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    // 
    // You are not setting a completion routine, so just skip the stack
    // location because it provides better performance.
    // 
    IoSkipCurrentIrpStackLocation (Irp);
    return IoCallDriver(TopOfDeviceStack, Irp);
} 

K?ch b?n 2: Chuy?n ti?p và ch? đ?i

S? d?ng m? sau đây n?u có m?t ngư?i lái xe mu?n chuy?n ti?p IRP đ? m?t h? th?p lái xe và ch? cho nó đ? tr? v? đ? cho nó có th? x? l? IRP. Đi?u này là thư?ng xuyên th?c hi?n khi x? l? các PNP IRPs. Ví d?, khi b?n nh?n đư?c m?t IRP_MN_START_DEVICE IRP, b?n ph?i chuy?n ti?p IRP xu?ng đ? lái xe bus và ch? đ?i cho nó đ? hoàn t?t trư?c khi b?n có th? b?t đ?u thi?t b? c?a b?n. H? th?ng Windows XP có m?t ch?c năng m?i tên là IoForwardIrpSynchronously r?ng b?n có th? s? d?ng đ? làm ho?t đ?ng này d? dàng.
NTSTATUS
DispatchRoutine_2(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    KEVENT   event;
    NTSTATUS status;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    // 
    // You are setting completion routine, so you must copy
    // current stack location to the next. You cannot skip a location
    // here.
    // 
    IoCopyCurrentIrpStackLocationToNext(Irp);

    IoSetCompletionRoutine(Irp,
                           CompletionRoutine_2,
                           &event,
                           TRUE,
                           TRUE,
                           TRUE
                           );

    status = IoCallDriver(TopOfDeviceStack, Irp);

    if (status == STATUS_PENDING) {
        
       KeWaitForSingleObject(&event,
                             Executive, // WaitReason
                             KernelMode, // must be Kernelmode to prevent the stack getting paged out
                             FALSE,
                             NULL // indefinite wait
                             );
       status = Irp->IoStatus.Status;
    }
    
    // <---- Do your own work here.


    // 
    // Because you stopped the completion of the IRP in the CompletionRoutine
    // by returning STATUS_MORE_PROCESSING_REQUIRED, you must call
    // IoCompleteRequest here.
    // 
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    return status;

}
NTSTATUS
CompletionRoutine_2(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{ 
  if (Irp->PendingReturned == TRUE) {
    // 
    // You will set the event only if the lower driver has returned
    // STATUS_PENDING earlier. This optimization removes the need to
    // call KeSetEvent unnecessarily and improves performance because the
    // system does not have to acquire an internal lock.  
    // 
    KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
  }
  // This is the only status you can return. 
  return STATUS_MORE_PROCESSING_REQUIRED;  
} 
				

K?ch b?n 3: V? phía trư?c v?i m?t thói quen hoàn thành

Trong trư?ng h?p này, tr?nh đi?u khi?n b? hoàn thành m?t thói quen, chuy?n ti?p các IRP xu?ng, và sau đó tr? v? tr?ng thái c?a tr?nh đi?u khi?n th?p như là. M?c đích c?a thi?t l?p nh?ng thói quen hoàn thành là s?a đ?i n?i dung c?a IRP trên đư?ng Quay l?i.
NTSTATUS
DispathRoutine_3(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS status;

    // 
    // Because you are setting completion routine, you must copy the
    // current stack location to the next. You cannot skip a location
    // here.
    // 
    IoCopyCurrentIrpStackLocationToNext(Irp); 

    IoSetCompletionRoutine(Irp,
                           CompletionRoutine_31,// or CompletionRoutine_32
                           NULL,
                           TRUE,
                           TRUE,
                           TRUE
                           );
    
    return IoCallDriver(TopOfDeviceStack, Irp);

} 
N?u b?n tr? v? tr?ng thái c?a tr?nh đi?u khi?n th?p hơn t? công văn c?a b?n thói quen:
  • B?n không ph?i thay đ?i t?nh tr?ng c?a IRP trong vi?c hoàn thành thói quen. Đi?u này là đ? đ?m b?o r?ng giá tr? t?nh tr?ng đ?t trong IRP c?a IoStatus kh?i (Irp-> IoStatus.Status) là gi?ng như tr? l?i t?nh tr?ng c?a the mid tr?nh đi?u khi?n.
  • B?n ph?i truy?n bá t?nh tr?ng ch? gi?i quy?t c?a IRP như đư?c ch? đ?nh b?i Irp-> PendingReturned.
  • B?n không ph?i thay đ?i đ?ng b? c?a các IRP.
Do đó, không ch? có 2 Phiên b?n h?p l? c?a hoàn thành thói quen trong trư?ng h?p này (31 và 32):
 
NTSTATUS
CompletionRoutine_31 (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{   

    // 
    // Because the dispatch routine is returning the status of lower driver
    // as is, you must do the following:
    // 
    if (Irp->PendingReturned) {
        
        IoMarkIrpPending( Irp );
    }
    
    return STATUS_CONTINUE_COMPLETION ; // Make sure of same synchronicity 
}

NTSTATUS
CompletionRoutine_32 (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{   
    // 
    // Because the dispatch routine is returning the status of lower driver
    // as is, you must do the following:
    // 
    if (Irp->PendingReturned) {
        
        IoMarkIrpPending( Irp );
    }
    
    //    
    // To make sure of the same synchronicity, complete the IRP here.
    // You cannot complete the IRP later in another thread because the 
    // the dispatch routine is returning the status returned by the lower
    // driver as is.
    // 
    IoCompleteRequest( Irp,  IO_NO_INCREMENT);  

    // 
    // Although this is an unusual completion routine that you rarely see,
    // it is discussed here to address all possible ways to handle IRPs.  
    // 
    return STATUS_MORE_PROCESSING_REQUIRED; 
} 

				

K?ch b?n 4: Hàng đ?i cho sau này, ho?c v? phía trư?c và tái s? d?ng

S? d?ng đo?n m? sau đây trong m?t t?nh hu?ng mà các tr?nh đi?u khi?n mu?n ho?c là x?p hàng m?t IRP và x? l? nó sau đó ho?c chuy?n ti?p IRP đ? các th?p hơn chương tr?nh đi?u khi?n và tái s? d?ng nó cho m?t s? c? th? c?a th?i đ?i trư?c khi hoàn t?t các IRP. Nh?ng thói quen công văn đánh d?u IRP đang ch? gi?i quy?t và tr? v? STATUS_PENDING b?i v? IRP s? đư?c hoàn thành sau này trong m?t ch? đ? khác nhau. ? đây, các hoàn thành thói quen có th? thay đ?i t?nh tr?ng c?a IRP n?u c?n thi?t (ngư?c l?i v?i các k?ch b?n trư?c đó).
NTSTATUS
DispathRoutine_4(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    NTSTATUS status;

    // 
    // You mark the IRP pending if you are intending to queue the IRP
    // and process it later. If you are intending to forward the IRP 
    // directly, use one of the methods discussed earlier in this article.
    // 
    IoMarkIrpPending( Irp );    

    // 
    // For demonstration purposes: this IRP is forwarded to the lower driver.
    // 
    IoCopyCurrentIrpStackLocationToNext(Irp); 

    IoSetCompletionRoutine(Irp,
                           CompletionRoutine_41, // or CompletionRoutine_42
                           NULL,
                           TRUE,
                           TRUE,
                           TRUE
                           ); 
    IoCallDriver(TopOfDeviceStack, Irp);

    // 
    // Because you marked the IRP pending, you must return pending,
    // regardless of the status of returned by IoCallDriver.
    // 
    return STATUS_PENDING ;

}
Nh?ng thói quen hoàn thành ho?c là có th? tr? l?i STATUS_CONTINUE_COMPLETION ho?c STATUS_MORE_PROCESSING_REQUIRED. B?n tr? l?i STATUS_MORE_PROCESSING_REQUIRED N?u b?n đ?nh s? d?ng l?i IRP t? ch? đ? khác, hoàn thành nó sau này.
NTSTATUS
CompletionRoutine_41(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{ 
    // 
    // By returning STATUS_CONTINUE_COMPLETION , you are relinquishing the 
    // ownership of the IRP. You cannot touch the IRP after this.
    // 
    return STATUS_CONTINUE_COMPLETION ; 
} 


NTSTATUS
CompletionRoutine_42 (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp,
    IN PVOID            Context
    )
{  
    // 
    // Because you are stopping the completion of the IRP by returning the
    // following status, you must complete the IRP later.
    // 
    return STATUS_MORE_PROCESSING_REQUIRED ; 
} 
				

K?ch b?n 5: Hoàn thành IRP trong thói quen công văn

K?ch b?n này cho th?y làm th? nào đ? hoàn thành m?t IRP t?i dispatch thói quen.

Quan tr?ng Khi b?n hoàn thành m?t IRP trong thói quen công văn, s? quay tr? l?i t?nh tr?ng c?a thói quen công văn nên phù h?p v?i t?nh tr?ng c?a các giá tr? đư?c thi?t l?p trong kh?i IoStatus c?a IRP (Irp-> IoStatus.Status).
NTSTATUS
DispatchRoutine_5(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    // 
    // <-- Process the IRP here.
    // 
    Irp->IoStatus.Status = STATUS_XXX;
    Irp->IoStatus.Information = YYY;
    IoCompletRequest(Irp, IO_NO_INCREMENT);
    return STATUS_XXX;
} 

THAM KH?O

Ph?n 2 c?a ch? đ? này đư?c ch?a trong sau đây Bài vi?t cơ s? ki?n th?c:
326315 Nh?ng cách khác nhau c?a x? l? IRPs - cheat sheet (ph?n 2/2)
  • Walter Oney. L?p tr?nh mô h?nh tr?nh đi?u khi?n WindowsSecond Edition, chương 5.

Thu?c tính

ID c?a bài: 320275 - L?n xem xét sau cùng: 27 Tháng Tám 2011 - Xem xét l?i: 2.0
Áp d?ng
  • Microsoft Windows XP Driver Development Kit
T? khóa: 
kbinfo kbkmode kbwdm kbmt KB320275 KbMtvi
Máy d?ch
QUAN TRỌNG: Bài vi?t này đư?c d?ch b?ng ph?n m?m d?ch máy c?a Microsoft ch? không ph?i do con ngư?i d?ch. Microsoft cung c?p các bài vi?t do con ngư?i d?ch và c? các bài vi?t do máy d?ch đ? b?n có th? truy c?p vào t?t c? các bài vi?t trong Cơ s? Ki?n th?c c?a chúng tôi b?ng ngôn ng? c?a b?n. Tuy nhiên, bài vi?t do máy d?ch không ph?i lúc nào c?ng hoàn h?o. Lo?i bài vi?t này có th? ch?a các sai sót v? t? v?ng, cú pháp ho?c ng? pháp, gi?ng như m?t ngư?i nư?c ngoài có th? m?c sai sót khi nói ngôn ng? c?a b?n. Microsoft không ch?u trách nhi?m v? b?t k? s? thi?u chính xác, sai sót ho?c thi?t h?i nào do vi?c d?ch sai n?i dung ho?c do ho?t đ?ng s? d?ng c?a khách hàng gây ra. Microsoft c?ng thư?ng xuyên c?p nh?t ph?n m?m d?ch máy này.
Nh?p chu?t vào đây đ? xem b?n ti?ng Anh c?a bài vi?t này:320275

Cung cấp Phản hồi

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com