1. Trang chủ
  2. » Công Nghệ Thông Tin

Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)

20 135 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 20
Dung lượng 176,62 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Kịch bản 1-Sự Chuyển xuống với hoàn thành thủ tục Trong kịch bản này, người nào đó gửi bạn một IRP.. Bạn sẽl đẩy IRP này tới trình điều khiển thấp hơn trong ngăn xếp PnP của các bạn, và

Trang 1

Tóm lược các kịch bản xử lý

(Summary—Eight

IRP-Handling Scenarios)

Bởi:

Khoa CNTT ĐHSP KT Hưng Yên

Mặc dù chiều dài của những giải thích có trước, sự dùng IRP thật sự hoàn toàn dễ dàng Bởi sự tính của tôi, chỉ có tám kịch bản một cách đáng kể khác nhau thông dụng, và mã được yêu cầu xử lý những kịch bản đó tương đối đơn giản Trong mục cuối cùng này của chương này, Tôi tập hợp một số bức tranh và mã lấy mẫu để giúp đỡ bạn sắp xếp lại tất cả kiến thức lý thuyết

Bởi vì mục này được dự định khi một cookbook mà bạn có thể sử dụng không có việc hoàn toàn hiểu mọi sắc thái cuối cùng, Tôi có bao gồm những sự gọi tới những chức năng khóa loại bỏ mà tôi sẽ tranh luận chi tiết trong Chương 6 Tôi cũng có sử dụng phương pháp tốc ký IoSetCompletionRoutine[Ex ] để chỉ báo những chỗ bạn nên gọi IoSetCompletionRoutineEx, trong một hệ thống ở đâu nó sẵn sàng, thiết đặt một sự hoàn thành thường lệ Tôi cũng sử dụng một phiên bản quá tải của người giúp đỡ thủ tục CompleteRequest của tôi mà không thay đổi IoStatus Thông tin trong những ví dụ này

vì điều đó đúng cho IRP_MJ_PNP và không phải không đúng cho những kiểu IRP khác Kịch bản 1-Sự Chuyển xuống với hoàn thành thủ tục

Trong kịch bản này, người nào đó gửi bạn một IRP Bạn sẽl đẩy IRP này tới trình điều khiển thấp hơn trong ngăn xếp PnP của các bạn, và bạn sẽ làm sự xử lý sau nào đó trong một sự hoàn thành thường lệ Xem hình 5-11 Chấp nhận chiến lược này khi tất cả điều sau là đúng:

• Người nào đó đang gửi bạn một IRP (ngược với bạn tạo ra chính IRP)

• IRP có lẽ đã đến ở DISPATCH_LEVEL hay trong một luồng chuyên quyền (

Vì thế là bạn không có thể làm trở ngại trong khi những trình điều khiển thấp hơn xử lý IRP)

• Sự xử lý sau của các bạn có thể được làm ở DISPATCH_LEVEL nếu cần ( Bởi

vì những thủ tục hoàn thành có lẽ đã được gọi ở DISPATCH _LEVEL)

Trang 2

Hình 5-11 Sự Chuyển xuống với sự hoàn thành thủ tục

Sự gởi đi của các bạn và những thủ tục hoàn thành sẽ có mẫu thuộc về bộ khung này: NTSTATUS DispatchSomething(PDEVICE_OBJECT fdo, PIRP Irp)

{

PDEVICE_EXTENSION pdx =

(PDEVICE_EXTENSION) fdo->DeviceExtension;

NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

if (!NT_SUCCESS(status))

return CompleteRequest(Irp, status);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(Irp,

(PIO_COMPLETION_ROUTINE) CompletionRoutine,

pdx, TRUE, TRUE, TRUE);

return IoCallDriver(pdx->LowerDeviceObject, Irp);

Trang 3

NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp,

PDEVICE_EXTENSION pdx)

{

if (Irp->PendingReturned)

IoMarkIrpPending(Irp);

<whatever post processing you wanted to do>

IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

return STATUS_SUCCESS;

}

Kịch bản 2-Sự Chuyển xuống không có sự hoàn thành thủ tục

Trong kịch bản này, người nào đó gửi bạn một IRP Bạn sẽ chuyển tiếp IRP tới trình điều khiển thấp hơn trong chồng PnP của các bạn, nhưng bạn không cần làm bất cứ cái

gì với IRP Xem hình 5-12 Chấp nhận chiến lược này, mà có thể cũng được gọi " Let Mikey try it" cách tiếp cận, khi cả hai của sự theo sau true:

• Một ai đó đang gửi bạn một IRP (ngược với bạn tạo ra chính IRP)

• Bạn không xử lý IRP này, trừ phi một trình điều khiển ở dưới bạn có lẽ đã muốn tới

Trang 4

Hình 5-12 Sự Chuyển xuống không có sự hoàn thành thủ tục

Kịch bản này thường được sử dụng trong một trình điều khiển lọc, mà cần phải đóng vai một ống dẫn đơn giản cho mọi IRP mà nó không đặc biệt cần lọc

Tôi khuyến cáo viết thủ tục trợ giúp sau đây, mà bạn có thể sử dụng mỗi khi bạn cần thuê chiến lược này

NTSTATUS ForwardAndForget(PDEVICE_EXTENSION pdx, PIRP Irp)

{

PDEVICE_EXTENSION pdx =

(PDEVICE_EXTENSION) fdo->DeviceExtension;

NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);

if (!NT_SUCCESS(status))

return CompleteRequest(Irp, status);

IoSkipCurrentIrpStackLocation (Irp);

status = IoCallDriver(pdx->LowerDeviceObject, Irp);

IoReleaseRemoveLock(&pdx->RemoveLock, Irp);

Trang 5

return status;

}

Kịch bản 3- Hoàn thành trong thủ tục gởi đi

Trong kịch bản này, bạn ngay lập tức hoàn thành một IRP mà người nào đó gửi bạn Xem hình 5-13 Chấp nhận chiến lược này khi:

• Một ai đó đang gửi bạn một IRP (ngược với bạn tạo ra chính IRP), và

• Bạn có thể xử lý IRP ngay lập tức Điều này là trường hợp cho nhiều cách thức của những yêu cầu điều khiển (IOCTL) vào/ra Hoặc

• Cái gì đó rõ ràng sai với IRP, mà trong đó trường hợp gây ra nó quên ngay lập tức có lẽ đã là thứ tử tế nhất để làm

Hình 5-13 Hoàn thành trong sự liên lạc thủ tục

Sự liên lạc thur tục của các bạn có mẫu thuộc về bộ khung này:

NTSTATUS DispatchSomething(PDEVICE_OBJECT fdo, PIRP Irp)

{

PDEVICE_EXTENSION pdx =

(PDEVICE_EXTENSION) fdo->DeviceExtension;

<process the IRP>

Irp->IoStatus.Status = STATUS_XXX;

Irp->IoStatus.Information = YYY;

Trang 6

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return STATUS_XXX;

}

Kịch bản 4-Hàng đợi cho sau này xử lý

Trong kịch bản này, người nào đó gửi bạn một IRP điều đó bạn không có thể xử lý ngay tức thì Bạn mang IRP vào một hàng đợi cho sau này xử lý ở một thủ tục StartIo Xem Hình 5-14 Chấp nhận chiến lược này khi cả hai sự theo sau đúng:

• Người nào đó đang gửi bạn một IRP (ngược với bạn tạo ra chính IRP)

• Bạn không biết rằng bạn có thể xử lý IRP ngay tức thì Điều này thường xuyên

là trường hợp cho IRPs mà đòi hỏi được xếp theo thứ tự truy nhập phần cứng, như những sự đọc và viết

Hình 5-14 Hàng đợi cho xử lý sau này

Mặc dầu bạn có nhiều sự lựa chọn, một cách tiêu biểu của sự thi hành kịch bản này suy

ra việc sử dụng một DEVQUEUE để quản lý hàng đợi IRP Những đoạn sau đây cho thấy những phần khác nhau của một trình điều khiển cho một ngắt vào/ra được chương trình hóa-được điều khiển thiết bị ngắt tương tác như thế nào Chỉ những phần được cho thấy trong chữ nét đậm liên quan đặc biệt tới sự dùng IRP

typedef struct _DEVICE_EXTENSION {

Trang 7

DEVQUEUE dqReadWrite;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

NTSTATUS AddDevice(PDRIVER_OBJECT DriverObject,

PDEVICE_OBJECT pdo)

{

InitializeQueue(&pdx->dqReadWrite, StartIo);

IoInitializeDpcRequest(fdo, (PIO_DPC_ROUTINE) DpcForIsr);

}

NTSTATUS DispatchReadWrite(PDEVICE_OBJECT fdo, PIRP Irp)

{

PDEVICE_EXTENSION pdx =

(PDEVICE_EXTENSION) fdo->DeviceExtension;

IoMarkIrpPending(Irp);

StartPacket(&pdx->dqReadWrite, fdo, Irp, CancelRoutine);

return STATUS_PENDING;

}

VOID CancelRoutine(PDEVICE_OBJECT fdo, PIRP Irp)

{

PDEVICE_EXTENSION pdx =

(PDEVICE_EXTENSION) fdo->DeviceExtension;

Trang 8

CancelRequest(&pdx->dqReadWrite, Irp);

}

VOID StartIo(PDEVICE_OBJECT fdo, PIRP Irp)

{

}

BOOLEAN OnInterrupt(PKINTERRUPT junk, PDEVICE_EXTENSION pdx)

{

PIRP Irp = GetCurrentIrp(&pdx->dqReadWrite);

Irp->IoStatus.Status = STATUS_XXX;

Irp->IoStatus.Information = YYY;

IoRequestDpc(pdx->DeviceObject, NULL, pdx);

}

VOID DpcForIsr(PKDPC junk1, PDEVICE_OBJECT fdo, PIRP junk2,

PDEVICE_EXTENSION pdx)

{

PIRP Irp = GetCurrentIrp(&pdx->dqReadWrite);

StartNextPacket(&pdx->dqReadWrite, fdo);

Trang 9

IoCompleteRequest(Irp, IO_NO_INCREMENT);

}

Kịch bản 5-IRP Không đồng bộ của riêng mình

Trong kịch bản này bạn tạo nên một IRP không đồng bộ, bạn tiếp tới trình điều khiển khác Xem Hình 5-15 Chấp nhận chiến lược này khi những điều kiện sau đây đúng:

• Bạn cần trình điều khiển khác để thực hiện một thao tác trên lợi ích của các bạn

• Hay là bạn trong một luồng chuyên quyền ( bạn không quyết tâm Block) hay bạn chạy ở DISPATCH_LEVEL (trong trường hợp nào bạn không có thể

block)

Hình 5-15 IRP không đồng bộ của riêng mình

Bạn sẽ có mã như sau trong trình điều khiển của các bạn Điều này không chiến thắng tất yếu trong một sự liên lạc thủ tục IRP, và đối tượng thiết bị đích không được chiến thắng tất yếu là tiếp theo thấp hơn một trong ngăn xếp PnP của các bạn Nhìn vào tài liệu DDK cho những chi tiết đầy đủ về gọi IoBuildAsynchronousFsdRequest và IoAllocateIrp như thế nào

SOMETYPE SomeFunction(PDEVICE_EXTENSION pdx,

PDEVICE_OBJECT DeviceObject)

{

NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock,

Trang 10

(PVOID) 42);

if (!NT_SUCCESS(status))

return <status>;

PIRP Irp;

Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_XXX, DeviceObject,

);

-or-Irp = IoAllocate-or-Irp(DeviceObject->StackSize, FALSE);

PIO_STACK_LOCATION stack = IoGetNextIrpStackLocation(Irp);

stack->MajorFunction = IRP_MJ_XXX;

<additional initialization)

IoSetCompletionRoutine[Ex]([pdx->DeviceObject,] Irp,

(PIO_COMPLETION_ROUTINE) CompletionRoutine, pdx,

TRUE, TRUE, TRUE);

ObReferenceObject(DeviceObject);

IoCallDriver(DeviceObject, Irp);

ObDereferenceObject(DeviceObject);

}

Trang 11

NTSTATUS CompletionRoutine(PDEVICE_OBJECT junk, PIRP Irp,

PDEVICE_EXTENSION pdx)

{

<IRP cleanup see below>

IoFreeIrp(Irp);

IoReleaseRemoveLock(&pdx->RemoveLock, (PVOID) 42);

return STATUS_MORE_PROCESSING_REQUIRED;

}

Những sự gọi tới IoAcquireRemoveLock và IoReleaseRemoveLock (những điểm được gắn nhãn A) chỉ cần thiết nếu thiết bị tới nào bạn gửi IRP này là LowerDeviceObject trong ngăn xếp PnP của các bạn 42 là một nhãn chuyên quyền-nó là hoàn toàn phức tạp

để cố gắng gỡ bỏ sự khóa sau những tồn tại IRP, đúng như vậy chúng tôi có thể sử dụng con trỏ IRP như một nhãn gỡ lỗi xây dựng

Những sự gọi ObReferenceObject và ObDereferenceObject mà đi trước và đi theo sau

sự gọi IoCallDriver (những điểm được gắn nhãn B) chỉ cần thiết khi nào bạn đã sử dụng IoGetDeviceObjectPointer để thu được con trỏ DeviceObject và khi sự hoàn thành tảu tục ( hay cái gì đó nó gọi) sẽ giải phóng sự tham khảo kết quả tới một đối tượng thiết bị hay tệp tin

Bạn không có cả hai mã A và mã B-bạn có một tập hợp hay không cái nào

Nếu bạn sử dụng IoBuildAsynchronousFsdRequest để xây dựng một IRP_MJ_READ HayIRP _MJ_WRITE, bạn có một vài cleanup tương đối phức tạp nào đó để thực hiện trong sự hoàn thành thủ tục

Cleanup cho DO_DIRECT_IO đích (C leanup for DO_DIRECT_IO Target ):

Nếu đối tượng thiết bị đích chỉ báo phương pháp đệm DO_DIRECT_IO bạn sẽ phải giải phóng những danh sách bộ mô tả kí ức mà quản lý vào/ra cấp phát cho bộ đệm dữ liệu của các bạn:

NTSTATUS CompletionRoutine( )

Trang 12

PMDL mdl;

while ((mdl = Irp->MdlAddress))

{

Irp->MdlAddress = mdl->Next;

MmUnlockPages(mdl); // <== only if you earlier

// called MmProbeAndLockPages IoFreeMdl(mdl);

}

IoFreeIrp(Irp);

<optional release of remove lock>

return STATUS_MORE_PROCESSING_REQUIRED;

}

Cleanup cho DO_BUFFERED_IO đích ( Cleanup for DO_BUFFERED_IO Target ):

Nếu đối tượng thiết bị đích chỉ báo DO_BUFFERED_IO , quản lý vào/ra sẽ tạo ra một

bộ đệm hệ thống Sự hoàn thành thủ tục của các bạn về mặt lý thuyết cần phải sao chép

dữ liệu từ bộ đệm hệ thống đến bộ đệm của riêng mình và sau đó giải phóng bộ đệm hệ thống Không may, những bit cờ hiệu và những lĩnh vực được cần để làm điều này thì không phải được lấy tài liệu trong DDK Lời khuyên của tôi trực tiếp sẽ đơn giản không gửi những sự đọc và viết tới một trình điều khiển mà sử dụng bộ đệm vào/ra Thay vào

đó, gọi ZwReadFile hay ZwWriteFile

Cleanup cho những đích khác (C leanup for Other Targets ):

Nếu thiết bị đích chỉ báo không DO_DIRECT_IO hay DO_BUFFERED_IO, không có cleanup bổ sung Phew!

Kịch bản 6-IRP đồng bộ của riêng mình

Trang 13

Trong kịch bản này bạn tạo nên một đồng bộ IRP, bạn chuyển tiếp tới trình điều khiển khác Xem hình 5-16 Chấp nhận chiến lược này khi tất cả sự theo sau đúng:

• Bạn cần trình điều khiển khác để thực hiện một thao tác trên sự đại diện của các bạn

• Bạn phải đợi thao tác để hoàn thành trước đây theo đuổi

• Bạn chạy ở PASSIVE_LEVEL trong một luồng không chuyên quyền

Hình 5-16 IRP đồng bộ của riêng mình

Bạn sẽ có mã như sự theo sau trong trình điều khiển của) các bạn Điều này không chiến thắng tất yếu trong một sự liên lạc thủ tục IRP, và đối tượng thiết bị đích không được chiến thắng tất yếu là tiếp theo thấp hơn một trong ngăn xếp PnP của các bạn Nhìn vào tài liệu DDK cho những chi tiết đầy đủ về gọi IoBuildSynchronousFsdRequest và IoBuildDeviceIoControlRequest như thế nào

SOMETYPE SomeFunction(PDEVICE_EXTENSION pdx,

PDEVICE_OBJECT DeviceObject)

{

NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock,

Trang 14

(PVOID) 42);

if (!NT_SUCCESS(status))

return <status>;

PIRP Irp;

KEVENT event;

IO_STATUS_BLOCK iosb;

KeInitializeEvent(&event, NotificationEvent, FALSE);

Irp = IoBuildAsynchronousFsdRequest(IRP_MJ_XXX,

DeviceObject, , &event, &iosb);

-or-Irp = IoBuildDeviceIoControlRequest(IOCTL_XXX, DeviceObject,

, &event, &iosb);

status = IoCallDriver(DeviceObject, Irp);

if (status == STATUS_PENDING)

{

KeWaitForSingleObject(&event, Executive, KernelMode,

FALSE, NULL);

status = iosb.Status;

}

Trang 15

IoReleaseRemoveLock(&pdx->RemoveLock, (PVOID) 42);

}

Như trong kịch bản 5, những sự gọi tới IoAcquireRemoveLock và IoReleaseRemoveLock (những điểm được gắn nhãn A) chỉ cần thiết nếu thiết bị tới nào bạn gửi IRP này là LowerDeviceObject trong ngăn xếp PnP của các bạn 42 là một nhãn chuyên quyền-nó đơn giản quá phức tạp để thử để thu nhận sự khóa loại bỏ sau tồn tại IRP, đúng như vậy chúng tôi có thể sử dụng con trỏ IRP như một nhãn gỡ lỗi xây dựng

Chúng tôi sẽ sử dụng kịch bản này thường xuyên trong Chương 12 để gửi những khối yêu cầu USB (URBs) đồng bộ xuống ngawn xếp Trong những ví dụ chúng tôi sẽ nghiên cứu ở đó, chúng tôi sẽ thường đang làm điều này trong văn cảnh của một sự liên lạc thủ tục IRP mà độc lập thu nhận sự khóa loại bỏ Bởi vậy, bạn không chiến thắng nhìn thấy

mã khóa loại bỏ thêm trong những ví dụ đó

Bạn không phải làm quét dọn sau khi IRP này! Quản lý vào/ra làm nó tự động

Kịch bản 7-Sự Chuyển qua Đồng bộ Xuống

In kịch bản này, người nào đó gửi bạn một IRP Bạn đi qua IRP xuống đồng bộ trong ngăn xếp PnP của các bạn và sau đó tiếp tục xử lý Xem hình 5-17 Chấp nhận chiến lược này khi tất cả sự theo sau đúng:

• Người nào đó đang gửi bạn một IRP (ngược với bạn tạo ra chính IRP)

• Bạn chạy ở PASSIVE_LEVEL trong một luồng không chuyên quyền

• Sự xử lý sau của các bạn cho IRP phải được làm ở PASSIVE_LEVEL

Trang 16

Hình 5-17 Sự chuyển qua Đồng bộ xuống

Một ví dụ tốt của khi nào bạn cần sử dụng chiến lược này trong khi đang xử lý một hương vị(flavor)IRP_MN_START_DEVICE của yêu cầu PnP

Tôi khuyến cáo viết hai thủ tục giúp đỡ để làm cho nó trở nên dễ dàng thực hiện sự chuyển qua đồng bộ này- thao tác xuống:

NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)

{

KEVENT event;

KeInitialize(&event, NotificationRoutine, FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)

ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);

NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);

if (status == STATUS_PENDING)

{

KeWaitForSingleObject(&event, Executive, KernelMode,

Trang 17

FALSE, NULL);

status = Irp->IoStatus.Status;

}

return status;

}

NTSTATUS ForwardAndWaitCompletionRoutine(PDEVICE_OBJECT fdo,

PIRP Irp, PKEVENT pev)

{

if (Irp->PendingReturned)

KeSetEvent(pev, IO_NO_INCREMENT, FALSE);

return STATUS_MORE_PROCESSING_REQUIRED;

}

Người gọi thủ tục này cần gọi cho IoCompleteRequest cho IRP này và để thu nhận và giải phóng sự khóa loại bỏ Nó không thích hợp cho ForwardAndWait để chứa đựng khóa lôgic loại bỏ bởi vì người gọi có lẽ đã không muốn giải phóng sự khóa sớm như vậy

Chú ý rằng chức năng IoForwardIrpSynchronously Windows XP DDK đóng gói đây giống như những bước

Kịch bản 8-IRP Không đồng bộ được xử lý đồng bộ

In kịch bản này, bạn tạo nên một IRP không đồng bộ, bạn chuyển tiếp tới trình điều khiển khác Rồi bạn đợi IRP để hoàn thành Xem hình 5-18 Chấp nhận chiến lược này khi tất cả sự theo sau đúng:

• Bạn cần trình điều khiển khác để thực hiện một thao tác trên sự đại diện của các bạn

• Bạn cần đợi thao tác để kết thúc trước khi bạn có thể tiếp tục

• Bạn chạy ở APC_LEVEL trong một luồng không chuyên quyền

Ngày đăng: 31/12/2015, 22:11

HÌNH ẢNH LIÊN QUAN

Hình 5-11. Sự Chuyển xuống với sự hoàn thành thủ tục . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 11. Sự Chuyển xuống với sự hoàn thành thủ tục (Trang 2)
Hình 5-12. Sự Chuyển xuống không có sự hoàn thành thủ tục . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 12. Sự Chuyển xuống không có sự hoàn thành thủ tục (Trang 4)
Hình 5-13. Hoàn thành trong sự liên lạc thủ tục . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 13. Hoàn thành trong sự liên lạc thủ tục (Trang 5)
Hình 5-14. Hàng đợi cho xử lý sau này . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 14. Hàng đợi cho xử lý sau này (Trang 6)
Hình 5-15. IRP không đồng bộ của riêng mình . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 15. IRP không đồng bộ của riêng mình (Trang 9)
Hình 5-16. IRP đồng bộ của riêng mình . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 16. IRP đồng bộ của riêng mình (Trang 13)
Hình 5-17. Sự chuyển qua Đồng bộ xuống . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 17. Sự chuyển qua Đồng bộ xuống (Trang 16)
Hình 5-18. IRP không đồng bộ được xử lý đồng bộ . - Tóm lược các kịch bản xử lý (summary—eight IRP handling scenarios)
Hình 5 18. IRP không đồng bộ được xử lý đồng bộ (Trang 18)

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w