다음을 통해 공유


IRP_MN_QUERY_ALL_DATA

WMI를 지원하는 모든 드라이버는 이 IRP를 처리해야 합니다. 드라이버는 WmiSystemControl을 호출하거나 WMI 요청 처리에 설명된 대로 IRP 자체를 처리하여 WMI IRP를 처리할 수 있습니다.

드라이버가 WmiSystemControl을 호출하여 IRP_MN_QUERY_ALL_DATA 요청을 처리하는 경우 WMI는 해당 드라이버의 DpWmiQueryDataBlock 루틴을 호출합니다.

주 코드

IRP_MJ_SYSTEM_CONTROL

보낸 경우

WMI는 지정된 데이터 블록의 모든 인스턴스를 쿼리하기 위해 이 IRP를 보냅니다.

WMI는 임의 스레드 컨텍스트에서 IRQL = PASSIVE_LEVEL 이 IRP를 보냅니다.

입력 매개 변수

IRP의 드라이버 I/O 스택 위치에 있는 Parameters.WMI.ProviderId 는 요청에 응답해야 하는 드라이버의 디바이스 개체를 가리킵니다.

Parameters.WMI.DataPath 는 데이터 블록을 식별하는 GUID를 가리킵니다.

Parameters.WMI.BufferSize 는 요청에서 출력 데이터를 수신하는 Parameters.WMI.Buffer에서 페이징하지 않은 버퍼의 최대 크기를 나타냅니다. 버퍼 크기는 sizeof(WNODE_ALL_DATA)보다 크거나 같아야 하며 반환되는 모든 인스턴스에 대한 인스턴스 이름 및 데이터의 크기를 더해야 합니다.

출력 매개 변수

드라이버가 WmiSystemControl을 호출하여 WMI IRP를 처리하는 경우 WMI는 드라이버가 등록한 각 블록에 대해 드라이버의 DpWmiQueryDataBlock 루틴을 한 번 호출하여 WNODE_ALL_DATA 채웁니다.

그렇지 않으면 드라이버는 다음과 같이 Parameters.WMI.BufferWNODE_ALL_DATA 구조를 채웁니다.

  • WnodeHeader.BufferSize를 반환할 전체 WNODE_ALL_DATA 바이트 수로 설정하고, WnodeHeader.Timestamp를 KeQuerySystemTime에서 반환된 값으로 설정하고, WnodeHeader.Flags를 반환할 데이터에 적절하게 설정합니다.

  • InstanceCount를 반환할 인스턴스 수로 설정합니다.

  • 블록이 동적 인스턴스 이름을 사용하는 경우 OffsetInstanceNameOffsets를 WNODE_ALL_DATA 시작부터 ULONG 오프셋 배열이 시작되는 위치까지 오프셋(바이트)으로 설정합니다. 이 배열의 각 요소는 WNODE_ALL_DATA 각 동적 인스턴스 이름이 저장되는 위치까지의 오프셋입니다. 각 동적 인스턴스 이름은 계산된 유니코드 문자열로 저장됩니다. 여기서 개수는 USHORT이고 유니코드 문자열이 뒤따릅니다. 개수에는 유니코드 문자열의 일부일 수 있는 종료 null 문자가 포함되지 않습니다. 유니코드 문자열에 종결 null 문자가 포함된 경우 이 null 문자는 WNodeHeader.BufferSize설정된 크기 내에 있어야 합니다.

  • 모든 인스턴스의 크기가 같은 경우:

    • WnodeHeader.Flags에서 WNODE_FLAG_FIXED_INSTANCE_SIZE 설정하고 FixedInstanceSize를 해당 크기(바이트)로 설정합니다.
    • 각 인스턴스가 8바이트 경계에 맞춰지도록 패딩을 사용하여 DataBlockOffset에서 시작하는 인스턴스 데이터를 씁니다. 예를 들어 FixedInstanceSize가 6이면 드라이버는 인스턴스 간에 2바이트의 패딩을 추가합니다.
  • 인스턴스 크기가 다른 경우:

    • WnodeHeader.Flags에서 WNODE_FLAG_FIXED_INSTANCE_SIZE 지우고 OffsetInstanceDataAndLength부터 InstanceCount OFFSETINSTANCEDATAANDLENGTH 구조체의 배열을 작성합니다. 각 OFFSETINSTANCEDATAANDLENGTH 구조체는 WNODE_ALL_DATA 구조체의 시작부터 각 인스턴스의 데이터 시작 부분 및 데이터 길이까지의 오프셋을 바이트 단위로 지정합니다. DataBlockOffset 은 사용되지 않습니다.

    • OffsetInstanceDataAndLength 배열의 마지막 요소 다음에 인스턴스 데이터를 쓰고 각 인스턴스가 8바이트 경계에 정렬되도록 안쪽 여백을 씁니다.

Parameters.WMI.Buffer의 버퍼 가 너무 작아서 모든 데이터를 수신할 수 없는 경우 드라이버는 Parameters.WMI.Buffer의 WNODE_TOO_SMALL 구조에서 필요한 크기를 채웁니다. 버퍼가 sizeof(WNODE_TOO_SMALL)보다 작은 경우 드라이버는 IRP에 실패하고 STATUS_BUFFER_TOO_SMALL 반환합니다.

I/O 상태 블록

드라이버가 WmiSystemControl을 호출하여 IRP를 처리하는 경우 WMI는 I/O 상태 블록에서 Irp-IoStatus.Status>Irp-IoStatus.Information>을 설정합니다.

그렇지 않으면 드라이버는 Irp-IoStatus.Status>를 STATUS_SUCCESS 설정하거나 다음과 같은 적절한 오류 상태로 설정합니다.

STATUS_BUFFER_TOO_SMALL

STATUS_WMI_GUID_NOT_FOUND

성공하면 드라이버는 Irp-IoStatus.Information을 Parameters.WMI.Buffer의 버퍼에 기록된 바이트 수로 설정합니다.>

연산

드라이버는 WmiSystemControl을 호출하거나 WMI 요청 처리에 설명된 대로 IRP 자체를 처리하여 WMI IRP를 처리할 수 있습니다.

드라이버가 WmiSystemControl을 호출하여 WMI IRP를 처리하는 경우 해당 루틴은 드라이버의 DpWmiQueryDataBlock 루틴을 호출합니다.

드라이버가 IRP_MN_QUERY_ALL_DATA 요청을 처리하는 경우 Parameters.WMI.ProviderId가 드라이버가 IoWMIRegistrationControl에 전달한 것과 동일한 디바이스 개체를 가리키는 경우에만 처리해야 합니다. 그렇지 않으면 드라이버는 다음 하위 드라이버에 요청을 전달해야 합니다.

요청을 처리하기 전에 드라이버는 Parameters.WMI.DataPath가 드라이버가 지원하는 GUID를 가리키는지 여부를 결정해야 합니다. 그렇지 않은 경우 드라이버는 IRP에 실패하고 STATUS_WMI_GUID_NOT_FOUND 반환해야 합니다.

드라이버가 데이터 블록을 지원하는 경우 다음을 수행해야 합니다.

  • Parameters.WMI.BufferSize드라이버가 반환할 모든 데이터를 받을 수 있을 만큼 큰 버퍼를 지정했는지 확인합니다.

  • Parameters.WMI.Buffer의 WNODE_ALL_DATA 구조체를 해당 데이터 블록의 모든 인스턴스에 대한 데이터로 채웁니다.

요구 사항

헤더

Wdm.h(Wdm.h, Ntddk.h 또는 Ntifs.h 포함)

참고 항목

DpWmiQueryDataBlock

IoWMIRegistrationControl

KeQuerySystemTime

WMILIB_CONTEXT

WmiSystemControl

WNODE_ALL_DATA