IRP_MN_EXECUTE_METHOD
데이터 블록 내에서 메서드를 지원하는 모든 드라이버는 이 IRP를 처리해야 합니다. 드라이버는 WMI 요청 처리에 설명된 대로 WmiSystemControl 을 호출하거나 IRP 자체를 처리 하여 WMI IRP를 처리할 수 있습니다.
드라이버가 WmiSystemControl 을 호출하여 IRP_MN_EXECUTE_METHOD 요청을 처리하는 경우 WMI는 해당 드라이버의 DpWmiExecuteMethod 루틴을 차례로 호출합니다.
주 코드
보낸 경우
WMI는 데이터 블록과 연결된 메서드를 실행하기 위해 이 IRP를 보냅니다.
WMI는 임의 스레드 컨텍스트에서 IRQL = PASSIVE_LEVEL 이 IRP를 보냅니다.
WMI는 IRP_MN_EXECUTE_METHOD 보내기 전에 IRP_MN_QUERY_SINGLE_INSTANCE 보냅니다. 드라이버가 IRP_MN_EXECUTE_METHOD 지원하는 경우 메서드가 실행되는 동일한 데이터 블록에 대한 IRP_MN_QUERY_SINGLE_INSTANCE 처리기가 있어야 합니다.
입력 매개 변수
Parameters.WMI.ProviderId 는 요청에 응답해야 하는 드라이버의 디바이스 개체를 가리킵니다. 이 포인터는 IRP에서 드라이버의 I/O 스택 위치에 있습니다.
Parameters.WMI.DataPath 는 실행할 메서드와 연결된 데이터 블록을 식별하는 GUID를 가리킵니다.
Parameters.WMI.BufferSize는 = sizeof(WNODE_METHOD_ITEM)여야 하는 >Parameters.WMI.Buffer에서 페이지가 지정되지 않은 버퍼의 크기와 메서드에 대한 출력 데이터의 크기를 나타냅니다.
Parameters.WMI.Buffer는 MethodID가 실행할 메서드의 식별자를 나타내고 DataBlockOffset은 구조체의 시작부터 입력 데이터의 첫 번째 바이트(있는 경우)까지의 오프셋(바이트)을 나타내는 WNODE_METHOD_ITEM 구조를 가리킵니다. Parameters.WMI.Buffer-> SizeDataBlock 은 입력 데이터를 포함하여 입력 WNODE_METHOD_ITEM 크기( 바이트)를 나타내고 입력이 없는 경우 0을 나타냅니다.
출력 매개 변수
드라이버가 WmiSystemControl을 호출하여 WMI IRP를 처리하는 경우 WMI는 드라이버의 DpWmiExecuteMethod 루틴에서 반환된 데이터로 WNODE_METHOD_ITEM 채웁니다.
그렇지 않으면 드라이버는 Parameters.WMI.Buffer가 가리키는 WNODE_METHOD_ITEM 구조를 다음과 같이 채웁니다.
출력 데이터를 포함하여 출력 WNODE_METHOD_ITEM 크기로 WnodeHeader.BufferSize를 업데이트.
출력 데이터의 크기로 SizeDataBlock을 업데이트 출력 데이터가 없으면 0입니다.
Parameters.WMI.Buffersize를 검사하여 버퍼가 출력 데이터를 포함하여 출력 WNODE_METHOD_ITEM 받을 수 있을 만큼 큰지 확인합니다. 버퍼가 충분히 크지 않으면 드라이버는 Parameters.WMI.Buffer가 가리키는 WNODE_TOO_SMALL 구조에서 필요한 크기를 채웁니다. 버퍼가 sizeof(WNODE_TOO_SMALL)보다 작으면 드라이버가 IRP에 실패하고 STATUS_BUFFER_TOO_SMALL 반환합니다.
DataBlockOffset에서 시작하는 입력 데이터를 통해 출력 데이터(있는 경우)를 씁니다. 드라이버는 DataBlockOffset의 입력 값을 변경해서는 안 됩니다.
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
STATUS_WMI_INSTANCE_NOT_FOUND
STATUS_WMI_ITEMID_NOT_FOUND
성공하면 드라이버는 Irp-IoStatus.Information>를 Parameters.WMI.Buffer 의 버퍼에 기록된 바이트 수 로 설정합니다.
작업
드라이버는 WMI 요청 처리에 설명된 대로 WmiSystemControl 을 호출하거나 IRP 자체를 처리 하여 WMI IRP를 처리할 수 있습니다.
드라이버가 WmiSystemControl을 호출하여 WMI IRP를 처리하는 경우 해당 루틴은 드라이버의 DpWmiExecuteMethod 루틴을 호출하거나 드라이버가 루틴을 정의하지 않으면 STATUS_INVALID_DEVICE_REQUEST 반환합니다.
드라이버가 IRP_MN_EXECUTE_METHOD 요청 자체를 처리하는 경우 Parameters.WMI.ProviderId 가 드라이버가 IoWMIRegistrationControl에 전달한 포인터와 동일한 디바이스 개체를 가리키는 경우에만 처리해야 합니다. 그렇지 않으면 드라이버는 다음 하위 드라이버에 요청을 전달해야 합니다.
드라이버는 모든 입력 값의 유효성을 검사해야 합니다. 특히 드라이버는 IRP 요청 자체를 처리하는 경우 다음을 수행해야 합니다.
정적 이름의 경우 WNODE_METHOD_ITEM 구조체의 InstanceIndex 멤버가 데이터 블록에 대해 드라이버에서 지원하는 instance 인덱스 범위 내에 있는지 확인합니다.
동적 이름의 경우 instance 이름 문자열이 드라이버에서 지원하는 데이터 블록 instance 식별하는지 확인합니다.
WNODE_METHOD_ITEM 구조체의 MethodId 멤버가 드라이버가 데이터 블록에 대해 지원하는 메서드 식별자 범위 내에 있고 호출자가 메서드를 실행할 수 있는지 확인합니다.
WNODE_METHOD_ITEM 구조체의 DataBlockOffset 및 SizeDataBlock 멤버가 지정된 메서드의 매개 변수를 포함할 수 있을 만큼 큰 버퍼를 설명하고 매개 변수가 메서드에 유효한지 확인합니다.
Parameters.WMI.Buffersize가 출력 데이터로 업데이트된 후 WNODE_METHOD_ITEM 구조를 받을 수 있을 만큼 큰 버퍼를 지정했는지 확인합니다.
스레드 컨텍스트가 시작 사용자 모드 애플리케이션의 컨텍스트라고 가정하지 마세요. 상위 수준 드라이버가 이를 변경했을 수 있습니다.
요청을 처리하기 전에 드라이버는 Parameters.WMI.DataPath 가 드라이버에서 지원하는 GUID를 가리키는지 여부를 결정해야 합니다. 그렇지 않은 경우 드라이버는 IRP에 실패하고 STATUS_WMI_GUID_NOT_FOUND 반환해야 합니다.
드라이버가 데이터 블록을 지원하는 경우 다음과 같이 parameters.WMI.Buffer의 입력 WNODE_METHOD_ITEM instance 이름을 확인합니다.
WNODE_FLAG_STATIC_INSTANCE_NAMES WnodeHeader.Flags에서 설정된 경우 드라이버는 InstanceIndex를 해당 블록에 대한 드라이버의 정적 instance 이름 목록에 대한 인덱스로 사용합니다. WMI는 블록을 등록할 때 드라이버에서 제공한 등록 데이터에서 인덱스를 가져옵니다.
WnodeHeader.Flags에서 WNODE_FLAG_STATIC_INSTANCE_NAMES 명확한 경우 드라이버는 OffsetInstanceName의 오프셋을 사용하여 입력 WNODE_METHOD_ITEM instance 이름 문자열을 찾습니다. OffsetInstanceName은 구조체의 시작 부분에서 USHORT까지의 오프셋(바이트)이며, 이는 종료 null(있는 경우 포함) 및 유니코드의 instance 이름 문자열을 포함하여 instance 이름 문자열의 길이(문자가 아님)입니다.
드라이버가 지정된 instance 찾을 수 없는 경우 IRP에 실패하고 STATUS_WMI_INSTANCE_NOT_FOUND 반환해야 합니다. 동적 instance 이름이 있는 instance 경우 이 상태 드라이버가 instance 지원하지 않음을 나타냅니다. 따라서 WMI는 다른 데이터 공급자를 계속 쿼리하고 다른 공급자가 instance 찾지만 다른 이유로 요청을 처리할 수 없는 경우 데이터 소비자에게 적절한 오류를 반환할 수 있습니다.
그런 다음 드라이버는 입력 WNODE_METHOD_ITEM 메서드 ID를 확인하여 해당 데이터 블록에 대한 유효한 메서드인지 여부를 확인합니다. 그렇지 않으면 드라이버가 IRP에 실패하고 STATUS_WMI_ITEMID_NOT_FOUND 반환합니다.
메서드가 출력을 생성하는 경우 드라이버는 부작용이 있거나 두 번 수행해서는 안 되는 작업을 수행하기 전에 Parameters.WMI.BufferSize에서 출력 버퍼의 크기를 검사 합니다. 예를 들어 메서드가 카운터 그룹의 값을 반환한 다음 카운터를 다시 설정하는 경우 드라이버는 카운터를 다시 설정하기 전에 버퍼 크기를 검사(버퍼가 너무 작으면 IRP에 실패)해야 합니다. 이렇게 하면 WMI가 더 큰 버퍼를 사용하여 요청을 안전하게 다시 보냅니다.
instance 및 메서드 ID가 유효하고 버퍼 크기가 적절한 경우 드라이버는 메서드를 실행합니다. 입력 WNODE_METHOD_ITEMSizeDataBlock이 0이 아닌 경우 드라이버는 DataBlockOffset에서 시작하는 데이터를 메서드의 입력으로 사용합니다.
메서드가 출력을 생성하는 경우 드라이버는 DataBlockOffset부터 버퍼에 출력 데이터를 쓰고 출력 WNODE_METHOD_ITEMSizeDataBlock을 출력 데이터의 바이트 수로 설정합니다. 메서드에 출력 데이터가 없는 경우 드라이버는 SizeDataBlock 을 0으로 설정합니다. 드라이버는 DataBlockOffset의 입력 값을 변경해서는 안 됩니다.
instance 유효하지만 드라이버가 요청을 처리할 수 없는 경우 적절한 오류 상태 반환할 수 있습니다.
요구 사항
헤더 |
Wdm.h(Wdm.h, Ntddk.h 또는 Ntifs.h 포함) |