디바이스 큐 설정 및 사용
드라이버는 드라이버 또는 디바이스 초기화 시 KeInitializeDeviceQueue 를 호출하여 디바이스 큐 개체를 설정합니다. 디바이스를 시작한 후 드라이버는 KeInsertDeviceQueue 또는KeInsertByKeyDeviceQueue를 호출하여 이 큐에 IRP를 삽입합니다. 다음 그림에서는 이러한 호출을 보여 줍니다.
이 그림에서 알 수 있듯이 드라이버는 상주해야 하는 디바이스 큐 개체에 대한 스토리지를 제공해야 합니다. 디바이스 큐 개체를 설정하는 드라이버는 일반적으로 드라이버에서 만든 디바이스 개체의 디바이스 확장 에 필요한 스토리지를 제공하지만 드라이버가 컨트롤러 개체를 사용하거나 드라이버가 할당한 비페이지 풀에서 스토리지가 컨트롤러 확장에 있을 수 있습니다.
드라이버가 디바이스 확장에서 디바이스 큐 개체에 대한 스토리지를 제공하는 경우 디바이스 개체를 만든 후 디바이스를 시작하기 전에 KeInitializeDeviceQueue 를 호출합니다. 즉, 드라이버는 AddDevice 루틴에서 또는 PnP IRP_MN_START_DEVICE 요청을 처리할 때 큐를 초기화할 수 있습니다. KeInitializeDeviceQueue 호출에서 드라이버는 디바이스 큐 개체에 제공하는 스토리지에 대한 포인터를 전달합니다.
디바이스를 시작한 후 드라이버는 큐의 꼬리에 IRP를 배치하는 KeInsertDeviceQueue 또는 이전 그림과 같이 드라이버 결정 SortKey 값에 따라 IRP를 큐에 배치하는 KeInsertByKeyDeviceQueue를 호출하여 IRP를 디바이스 큐에 삽입할 수 있습니다.
이러한 각 지원 루틴은 IRP가 큐에 삽입되었는지 여부를 나타내는 부울 값을 반환합니다. 또한 이러한 각 호출은 큐가 현재 비어 있는 경우 디바이스 큐 개체의 상태를 사용 중으로 설정합니다(없음). 그러나 큐가 비어 있는 경우(없음) KeInsertXxxDeviceQueue 루틴은 IRP를 큐에 삽입하지 않습니다. 대신 디바이스 큐 개체의 상태를 Busy로 설정하고 FALSE를 반환합니다. IRP가 큐에 대기되지 않았으므로 드라이버는 추가 처리를 위해 다른 드라이버 루틴에 전달해야 합니다.
추가 디바이스 큐를 설정할 때 다음 구현 지침을 따릅니다.
KeInsertXxxDeviceQueue 호출에서 FALSE를 반환하는 경우 호출자는 다른 드라이버 루틴에 대한 추가 처리를 위해 큐에 대기하려고 시도한 IRP를 전달해야 합니다. 그러나 KeInsertXxxDeviceQueue 호출은 디바이스 큐 개체의 상태를 Busy로 변경하므로 드라이버가 KeRemoveXxxDeviceQueue 를 먼저 호출하지 않는 한 다음 IRP가 큐에 삽입됩니다.
디바이스 큐 개체의 상태가 사용 중으로 설정된 경우 드라이버는 추가 처리를 위해 IRP를 큐에서 제거하거나 다음 지원 루틴 중 하나를 호출하여 상태를 Not-Busy 다시 설정할 수 있습니다.
큐의 머리에서 IRP를 제거하는 KeRemoveDeviceQueue
드라이버 결정 SortKey 값에 따라 선택한 IRP를 제거하는 KeRemoveByKeyDeviceQueue
큐에서 특정 IRP를 제거하거나 특정 IRP가 큐에 있는지 여부를 확인하는 KeRemoveEntryDeviceQueue
KeRemoveEntryDeviceQueue 는 IRP가 디바이스 큐에 있는지 여부를 나타내는 부울을 반환합니다.
이러한 루틴을 호출하여 비어 있지만 사용 중인 디바이스 큐에서 항목을 제거하면 큐 상태가 없음으로 변경됩니다.
각 디바이스 큐 개체는 기본 제공 이그제큐티브 스핀 잠금으로 보호됩니다( 디바이스 큐 개체 사용 그림에 표시되지 않음). 따라서 드라이버는 IRQL = DISPATCH_LEVEL 이하에서 실행되는 모든 드라이버 루틴에서 IDP를 큐에 삽입하고 다중 프로세서로부터 안전한 방식으로 제거할 수 있습니다. 이 IRQL 제한으로 인해 드라이버는 DIRQL에서 실행되는 ISR 또는 SynchCritSection 루틴에서 KeXxxDeviceQueue 루틴을 호출할 수 없습니다.
자세한 내용은 하드웨어 우선 순위 관리 및 스핀 잠금 을 참조하세요. 특정 지원 루틴에 대한 IRQL 요구 사항은 루틴의 참조 페이지를 참조하세요.